Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[connect] Cleanup EmbeddedComponentManager scope and setup #9809

Merged
merged 2 commits into from
Dec 20, 2024

Conversation

lng-stripe
Copy link
Contributor

Summary

Addresses this PR comment.

Instead of having a singleton EmbeddedComponentManager app instance in the Example app:

  1. Create and cache EmbeddedComponentManager instances in EmbeddedComponentLoaderViewModel
  2. EmbeddedComponentManagerProvider has been demoted to a Factory, simplifying its role
  3. EmbeddedComponentLoaderViewModel is also responsible for binding app appearance settings to the manager in Activity#onCreate(). It does so by being being a lifecycle observer that Activities must register. This is aided by introducing a BaseActivity that our activities should extend.

Also, fixed a minor visual glitch with embedded component backgrounds.

Motivation

See comment. Overall, I think this eliminates some confusing state logic we had between EmbeddedComponentManagerProvider and EmbeddedComponentLoaderViewModel. There are clearer separations of concerns.

Testing

  • Added tests
  • Modified tests
  • Manually verified

Screenshots

Screen.Recording.2024-12-19.at.1.20.01.PM-compressed.mov

@lng-stripe lng-stripe requested a review from a team as a code owner December 19, 2024 18:24
Copy link
Contributor

github-actions bot commented Dec 19, 2024

Diffuse output:

OLD: identity-example-release-base.apk (signature: V1, V2)
NEW: identity-example-release-pr.apk (signature: V1, V2)

          │          compressed           │         uncompressed         
          ├───────────┬───────────┬───────┼───────────┬───────────┬──────
 APK      │ old       │ new       │ diff  │ old       │ new       │ diff 
──────────┼───────────┼───────────┼───────┼───────────┼───────────┼──────
      dex │     2 MiB │     2 MiB │   0 B │   4.1 MiB │   4.1 MiB │  0 B 
     arsc │     1 MiB │     1 MiB │   0 B │     1 MiB │     1 MiB │  0 B 
 manifest │   2.3 KiB │   2.3 KiB │   0 B │     8 KiB │     8 KiB │  0 B 
      res │ 301.8 KiB │ 301.8 KiB │   0 B │ 455.5 KiB │ 455.5 KiB │  0 B 
   native │   6.2 MiB │   6.2 MiB │   0 B │  15.8 MiB │  15.8 MiB │  0 B 
    asset │   7.1 KiB │   7.1 KiB │   0 B │   6.9 KiB │   6.9 KiB │  0 B 
    other │  90.2 KiB │  90.2 KiB │ -10 B │ 170.3 KiB │ 170.3 KiB │  0 B 
──────────┼───────────┼───────────┼───────┼───────────┼───────────┼──────
    total │   9.6 MiB │   9.6 MiB │ -10 B │  21.5 MiB │  21.5 MiB │  0 B 

 DEX     │ old   │ new   │ diff      
─────────┼───────┼───────┼───────────
   files │     1 │     1 │ 0         
 strings │ 19966 │ 19966 │ 0 (+0 -0) 
   types │  6188 │  6188 │ 0 (+0 -0) 
 classes │  4979 │  4979 │ 0 (+0 -0) 
 methods │ 29759 │ 29759 │ 0 (+0 -0) 
  fields │ 17526 │ 17526 │ 0 (+0 -0) 

 ARSC    │ old  │ new  │ diff 
─────────┼──────┼──────┼──────
 configs │  164 │  164 │  0   
 entries │ 3622 │ 3622 │  0
APK
    compressed    │   uncompressed   │                                           
──────────┬───────┼───────────┬──────┤                                           
 size     │ diff  │ size      │ diff │ path                                      
──────────┼───────┼───────────┼──────┼───────────────────────────────────────────
 28.4 KiB │  -9 B │  62.9 KiB │  0 B │ ∆ META-INF/CERT.SF                        
 25.3 KiB │  -2 B │  62.8 KiB │  0 B │ ∆ META-INF/MANIFEST.MF                    
    272 B │  +1 B │     120 B │  0 B │ ∆ META-INF/version-control-info.textproto 
──────────┼───────┼───────────┼──────┼───────────────────────────────────────────
   54 KiB │ -10 B │ 125.8 KiB │  0 B │ (total)


override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

EmbeddedComponentManager.onActivityCreate(this@MainActivity)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👀 Moved to BaseActivity#onCreate()


@OptIn(PrivateBetaConnectSDK::class)
@Singleton
class EmbeddedComponentManagerProvider @Inject constructor(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👀 Reduced to EmbeddedComponentManagerManager

val appearanceInfo = settingsService.getAppearanceId()
?.let { AppearanceInfo.getAppearance(it, context).appearance }
?: return@LaunchedEffect
embeddedComponentManager.update(appearanceInfo)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👀 Binding the app appearance setting to the manager is now done in EmbeddedComponentLoaderViewModel

import javax.inject.Inject

@Suppress("ConstPropertyName")
private object BasicComponentExampleDestination {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👀 nit: moved this below the Activity definition

loadManager()
return
// Bind appearance settings to the manager.
activity.lifecycleScope.launch {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👀 Important that we bind in the Activity scope and not ViewModel scope, otherwise there'd be a memory leak

@lng-stripe lng-stripe force-pushed the lng/connect-example-manager-per-activity branch from 8f8ba76 to b7a66a3 Compare December 20, 2024 14:46
Copy link
Collaborator

@simond-stripe simond-stripe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like some classes (BaseActivity, EmbeddedComponentManagerFactory) aren't defined. Approach looks great though - thanks for cleaning this up!

@@ -37,7 +37,10 @@ fun EmbeddedComponentManagerLoader(
) {
val embeddedComponentManager = embeddedComponentAsync()
when (embeddedComponentAsync) {
is Uninitialized, is Loading -> LoadingScreen()
is Uninitialized -> {
// Don't show anything to avoid flicker.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch

@@ -248,6 +248,8 @@ internal class StripeConnectWebViewContainerImpl<Listener, Props>(

private fun bindViewState(state: StripeConnectWebViewContainerState) {
val viewBinding = this.viewBinding ?: return
logger.debug("Binding view state: $state")
viewBinding.root.setBackgroundColor(state.backgroundColor)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! Looks like this fixes MXMOBILE-2996 - I've linked this PR and marked it as done.

@lng-stripe lng-stripe force-pushed the lng/connect-example-manager-per-activity branch from b7a66a3 to 47f60e0 Compare December 20, 2024 15:02
Copy link
Collaborator

@simond-stripe simond-stripe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great!

@lng-stripe lng-stripe enabled auto-merge (squash) December 20, 2024 15:08
@lng-stripe lng-stripe merged commit 75d9647 into master Dec 20, 2024
13 checks passed
@lng-stripe lng-stripe deleted the lng/connect-example-manager-per-activity branch December 20, 2024 15:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants