Skip to content

Commit

Permalink
[Integration] Remove Mavericks (#8157)
Browse files Browse the repository at this point in the history
* [FC] Moves Activities and some Panes out of Mavericks (#8125)

* Removes mackericks references on Consent screen.

* Updates files.

* Uses viewmodel factory builder.

* Updates functions.

* Updates execute.

* Updates compose util.

* Adds missing side effects.

* Simplifies code.

* Renames viewmodel.

* Updates async.

* Removes mavericks from institution picker.

* Reverts rename.

* Updates baseline.

* Adds setState and persists state.

* Renames result error to fail.

* Migrates Initial activity out of mavericks.

* Removes persist state.

* Updates tests.

* Regenerates API.

* filterNotNull.

* Nits.

* Updates async.

* use suspend block.

* Update financial-connections/src/main/java/com/stripe/android/financialconnections/core/FinancialConnectionsViewModel.kt

Co-authored-by: Till Hellmund <tillh@stripe.com>

* Tries onAsync.

* Moves activity to stripe ui core.

* PR feedback.

* Regenerates deps.

---------

Co-authored-by: Till Hellmund <tillh@stripe.com>

* [FC] Removes mavericks from repositories and more panes. (#8154)

* Migrates more screens out of mavs.

* Migrates partner auth.

* Removes active auth session field.

* Updates tests.

* Updates attach payment viewmodel.

* PR feedback.

* Api dump.

* [FC] Removes mavericks from all viewmodels and tests (#8155)

* Migrates more screens out of mavs.

* Migrates partner auth.

* Removes active auth session field.

* Updates tests.

* Updates attach payment viewmodel.

* PR feedback.

* Api dump.

* Migrates missing viewmodels.

* Updates dependencies.

* PR feedback.

* Merge master.

* [FC] Removes mavericks dependency (#8160)

* Migrates more screens out of mavs.

* Migrates partner auth.

* Removes active auth session field.

* Updates tests.

* Updates attach payment viewmodel.

* PR feedback.

* Api dump.

* Migrates missing viewmodels.

* Updates dependencies.

* Removes mavericks dependency.

* Merge with integration.

* Uses collect.

* Updates dependencies

* Updates Changelog.

* Update CHANGELOG.md

Co-authored-by: Till Hellmund <tillh@stripe.com>

---------

Co-authored-by: Till Hellmund <tillh@stripe.com>
  • Loading branch information
carlosmuvi-stripe and tillh-stripe authored Mar 27, 2024
1 parent 4e317c4 commit 060ad2e
Show file tree
Hide file tree
Showing 113 changed files with 1,924 additions and 1,936 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

## XX.XX.XX - 2023-XX-XX

### Financial Connections
* [CHANGED][8157](https://github.com/stripe/stripe-android/pull/8157) Financial Connections no longer depends on the Mavericks library.

## 20.40.2 - 2024-03-25

### PaymentSheet
Expand Down
4 changes: 0 additions & 4 deletions dependencies.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ ext.versions = [
kotlinSerializationConverter: '1.0.0',
ktlint : '0.48.2',
leakCanary : '2.13',
mavericks : '3.0.9',
material : '1.11.0',
mockito : '5.10.0',
mockitoInline : '5.2.0',
Expand Down Expand Up @@ -162,8 +161,6 @@ ext.libs = [
leakCanary : "com.squareup.leakcanary:leakcanary-android:${versions.leakCanary}",
loggingInterceptor : "com.squareup.okhttp3:logging-interceptor:${versions.okhttp}",
material : "com.google.android.material:material:${versions.material}",
mavericks : "com.airbnb.android:mavericks:${versions.mavericks}",
mavericksCompose : "com.airbnb.android:mavericks-compose:${versions.mavericks}",
microblinkCapture : "com.microblink:capture-core:${versions.microblinkCapture}",
okio : "com.squareup.okio:okio:${versions.okio}",
payButtonCompose : "com.google.pay.button:compose-pay-button:${versions.payButtonCompose}",
Expand Down Expand Up @@ -218,7 +215,6 @@ ext.testLibs = [
junit : "org.jetbrains.kotlin:kotlin-test-junit:${versions.kotlin}",
test : "org.jetbrains.kotlin:kotlin-test:${versions.kotlin}",
],
mavericks : "com.airbnb.android:mavericks-testing:${versions.mavericks}",
mockito : [
android: "org.mockito:mockito-android:${versions.mockito}",
core : "org.mockito:mockito-core:${versions.mockito}",
Expand Down
100 changes: 39 additions & 61 deletions example/dependencies/dependencies.txt

Large diffs are not rendered by default.

210 changes: 94 additions & 116 deletions financial-connections-example/dependencies/dependencies.txt

Large diffs are not rendered by default.

3 changes: 0 additions & 3 deletions financial-connections/api/financial-connections.api
Original file line number Diff line number Diff line change
Expand Up @@ -504,9 +504,6 @@ public final class com/stripe/android/financialconnections/features/success/Comp
public final fun getLambda-1$financial_connections_release ()Lkotlin/jvm/functions/Function3;
}

public final class com/stripe/android/financialconnections/launcher/FinancialConnectionsSheetActivityArgs$Companion {
}

public final class com/stripe/android/financialconnections/launcher/FinancialConnectionsSheetActivityArgs$ForData$Creator : android/os/Parcelable$Creator {
public fun <init> ()V
public final fun createFromParcel (Landroid/os/Parcel;)Lcom/stripe/android/financialconnections/launcher/FinancialConnectionsSheetActivityArgs$ForData;
Expand Down
3 changes: 0 additions & 3 deletions financial-connections/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@ dependencies {
implementation libs.kotlin.coroutines
implementation libs.kotlin.coroutinesAndroid
implementation libs.kotlin.serialization
implementation libs.mavericks
implementation libs.mavericksCompose

debugImplementation libs.compose.uiTestManifest
debugImplementation libs.compose.uiTooling
Expand All @@ -64,7 +62,6 @@ dependencies {
testImplementation testLibs.mockito.core
testImplementation testLibs.mockito.inline
testImplementation testLibs.mockito.kotlin
testImplementation testLibs.mavericks
testImplementation testLibs.robolectric
testImplementation testLibs.testParameterInjector
testImplementation testLibs.turbine
Expand Down
24 changes: 0 additions & 24 deletions financial-connections/consumer-rules.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,3 @@
*;
}

# ------------------------
# MvRx Config
# -----------------------

# MavericksViewModel loads the Companion class via reflection and thus we need to make sure we keep
# the name of the Companion object.
-keepclassmembers class ** extends com.airbnb.mvrx.MavericksViewModel {
** Companion;
}

# Members of the Kotlin data classes used as the state in Mavericks are read via Kotlin reflection which cause trouble
# with Proguard if they are not kept.
# During reflection cache warming also the types are accessed via reflection. Need to keep them too.
-keepclassmembers,includedescriptorclasses,allowobfuscation class ** implements com.airbnb.mvrx.MavericksState {
*;
}

# The MavericksState object and the names classes that implement the MavericksState interface need to be
# kept as they are accessed via reflection.
-keepnames class com.airbnb.mvrx.MavericksState
-keepnames class * implements com.airbnb.mvrx.MavericksState

# MavericksViewModelFactory is referenced via reflection using the Companion class name.
-keepnames class * implements com.airbnb.mvrx.MavericksViewModelFactory
253 changes: 115 additions & 138 deletions financial-connections/dependencies/dependencies.txt

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion financial-connections/detekt-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
<ID>MagicNumber:LinkAccountPickerScreen.kt$3</ID>
<ID>MagicNumber:ManualEntryViewModel.kt$ManualEntryViewModel$4</ID>
<ID>MagicNumber:SharedPartnerAuth.kt$.50f</ID>
<ID>MatchingDeclarationName:FinancialConnectionsViewModel.kt$Async&lt;out T></ID>
<ID>MatchingDeclarationName:ServerDrivenUi.kt$BulletUI</ID>
<ID>MatchingDeclarationName:Type.kt$FinancialConnectionsTypography</ID>
<ID>MaxLineLength:FinancialConnectionsUrls.kt$FinancialConnectionsUrls.DataPolicy$const val merchant = "https://support.stripe.com/user/questions/what-data-does-stripe-access-from-my-linked-financial-account"</ID>
Expand All @@ -36,6 +37,6 @@
<ID>SwallowedException:PostAuthorizationSession.kt$PostAuthorizationSession$e: StripeException</ID>
<ID>TooManyFunctions:FinancialConnectionsManifestRepository.kt$FinancialConnectionsManifestRepository</ID>
<ID>TooManyFunctions:FinancialConnectionsManifestRepository.kt$FinancialConnectionsManifestRepositoryImpl : FinancialConnectionsManifestRepository</ID>
<ID>TooManyFunctions:FinancialConnectionsSheetNativeViewModel.kt$FinancialConnectionsSheetNativeViewModel : MavericksViewModelTopAppBarHost</ID>
<ID>TooManyFunctions:FinancialConnectionsSheetNativeViewModel.kt$FinancialConnectionsSheetNativeViewModel : FinancialConnectionsViewModelTopAppBarHost</ID>
</CurrentIssues>
</SmellBaseline>
6 changes: 0 additions & 6 deletions financial-connections/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,6 @@
android:exported="false"
android:windowSoftInputMode="adjustResize"
android:theme="@style/StripeDefaultTheme" />

<provider
android:name=".appinitializer.FinancialConnectionsInitializer"
android:authorities="${applicationId}.financialconnections-init"
android:exported="false"
android:multiprocess="true" />
</application>

<!--
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package com.stripe.android.financialconnections

import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.widget.Toast
import androidx.activity.addCallback
import androidx.activity.compose.setContent
import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
Expand All @@ -15,9 +17,10 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.airbnb.mvrx.Mavericks
import com.airbnb.mvrx.MavericksView
import com.airbnb.mvrx.withState
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import com.stripe.android.financialconnections.FinancialConnectionsSheetViewEffect.FinishWithResult
import com.stripe.android.financialconnections.FinancialConnectionsSheetViewEffect.OpenAuthFlowWithUrl
import com.stripe.android.financialconnections.FinancialConnectionsSheetViewEffect.OpenNativeAuthFlow
Expand All @@ -28,14 +31,16 @@ import com.stripe.android.financialconnections.launcher.FinancialConnectionsShee
import com.stripe.android.financialconnections.launcher.FinancialConnectionsSheetNativeActivityArgs
import com.stripe.android.financialconnections.ui.FinancialConnectionsSheetNativeActivity
import com.stripe.android.financialconnections.ui.theme.FinancialConnectionsTheme
import com.stripe.android.financialconnections.utils.argsOrNull
import com.stripe.android.financialconnections.utils.viewModelLazy
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch

internal class FinancialConnectionsSheetActivity : AppCompatActivity(), MavericksView {
internal class FinancialConnectionsSheetActivity : AppCompatActivity() {

val viewModel: FinancialConnectionsSheetViewModel by viewModelLazy()

val args by argsOrNull<FinancialConnectionsSheetActivityArgs>()
val viewModel: FinancialConnectionsSheetViewModel by viewModels(
factoryProducer = { FinancialConnectionsSheetViewModel.Factory }
)

private val startBrowserForResult = registerForActivityResult(StartActivityForResult()) {
viewModel.onBrowserActivityResult()
Expand All @@ -49,10 +54,10 @@ internal class FinancialConnectionsSheetActivity : AppCompatActivity(), Maverick

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (args == null) {
if (getArgs(intent) == null) {
finish()
} else {
viewModel.onEach { postInvalidate() }
observeViewEffects()
browserManager = BrowserManager(application)
if (savedInstanceState != null) viewModel.onActivityRecreated()
}
Expand Down Expand Up @@ -91,46 +96,72 @@ internal class FinancialConnectionsSheetActivity : AppCompatActivity(), Maverick
/**
* handle state changes here.
*/
override fun invalidate() {
withState(viewModel) { state ->
state.viewEffect?.let { viewEffect ->
when (viewEffect) {
is OpenAuthFlowWithUrl -> startBrowserForResult.launch(
browserManager.createBrowserIntentForUrl(
uri = Uri.parse(viewEffect.url)

private fun observeViewEffects() = lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.stateFlow
.map { it.viewEffect }
.distinctUntilChanged()
.filterNotNull()
.collect { viewEffect ->
when (viewEffect) {
is OpenAuthFlowWithUrl -> startBrowserForResult.launch(
browserManager.createBrowserIntentForUrl(
uri = Uri.parse(viewEffect.url)
)
)
)

is FinishWithResult -> {
viewEffect.finishToast?.let {
Toast.makeText(this, it, Toast.LENGTH_LONG).show()
is FinishWithResult -> {
viewEffect.finishToast?.let { resId ->
Toast.makeText(
this@FinancialConnectionsSheetActivity,
resId,
Toast.LENGTH_LONG
).show()
}
finishWithResult(viewEffect.result)
}
finishWithResult(viewEffect.result)
}

is OpenNativeAuthFlow -> startNativeAuthFlowForResult.launch(
Intent(
this,
FinancialConnectionsSheetNativeActivity::class.java
).also {
it.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION)
it.putExtra(
Mavericks.KEY_ARG,
FinancialConnectionsSheetNativeActivityArgs(
initialSyncResponse = viewEffect.initialSyncResponse,
configuration = viewEffect.configuration
)
)
}
)
is OpenNativeAuthFlow -> openNativeAuthFlow(viewEffect)
}
viewModel.onViewEffectLaunched()
}
viewModel.onViewEffectLaunched()
}
}
}

private fun openNativeAuthFlow(viewEffect: OpenNativeAuthFlow) {
startNativeAuthFlowForResult.launch(
FinancialConnectionsSheetNativeActivity.intent(
context = this,
args = FinancialConnectionsSheetNativeActivityArgs(
initialSyncResponse = viewEffect.initialSyncResponse,
configuration = viewEffect.configuration
)
)
)
}

private fun finishWithResult(result: FinancialConnectionsSheetActivityResult) {
setResult(RESULT_OK, Intent().putExtras(result.toBundle()))
finish()
}

companion object {

private const val EXTRA_ARGS = "FinancialConnectionsSheetActivityArgs"
fun intent(context: Context, args: FinancialConnectionsSheetActivityArgs): Intent {
return Intent(context, FinancialConnectionsSheetActivity::class.java).apply {
addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION)
putExtra(EXTRA_ARGS, args)
}
}

fun getArgs(savedStateHandle: SavedStateHandle): FinancialConnectionsSheetActivityArgs? {
return savedStateHandle.get<FinancialConnectionsSheetActivityArgs>(EXTRA_ARGS)
}

fun getArgs(intent: Intent): FinancialConnectionsSheetActivityArgs? {
return intent.getParcelableExtra(EXTRA_ARGS)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package com.stripe.android.financialconnections

import android.os.Bundle
import androidx.annotation.StringRes
import com.airbnb.mvrx.MavericksState
import com.airbnb.mvrx.PersistState
import com.stripe.android.financialconnections.launcher.FinancialConnectionsSheetActivityArgs
import com.stripe.android.financialconnections.launcher.FinancialConnectionsSheetActivityResult
import com.stripe.android.financialconnections.model.FinancialConnectionsSessionManifest
Expand All @@ -13,15 +12,28 @@ import com.stripe.android.financialconnections.model.SynchronizeSessionResponse
*/
internal data class FinancialConnectionsSheetState(
val initialArgs: FinancialConnectionsSheetActivityArgs,
val activityRecreated: Boolean = false,
@PersistState val manifest: FinancialConnectionsSessionManifest? = null,
@PersistState val webAuthFlowStatus: AuthFlowStatus = AuthFlowStatus.NONE,
val viewEffect: FinancialConnectionsSheetViewEffect? = null
) : MavericksState {
val activityRecreated: Boolean,
val manifest: FinancialConnectionsSessionManifest?,
val webAuthFlowStatus: AuthFlowStatus,
val viewEffect: FinancialConnectionsSheetViewEffect?
) {

val sessionSecret: String
get() = initialArgs.configuration.financialConnectionsSessionClientSecret

/**
* Constructor used to build the initial state.
*/
constructor(args: FinancialConnectionsSheetActivityArgs, savedState: Bundle?) : this(
initialArgs = args,
activityRecreated = false,
manifest = savedState?.getParcelable(KEY_MANIFEST),
webAuthFlowStatus = savedState?.getSerializable(KEY_WEB_AUTH_FLOW_STATUS)
as? AuthFlowStatus
?: AuthFlowStatus.NONE,
viewEffect = null
)

enum class AuthFlowStatus {
/**
* AuthFlow is happening outside of the SDK (app2app, web browser, etc).
Expand All @@ -47,12 +59,11 @@ internal data class FinancialConnectionsSheetState(
NONE
}

/**
* Constructor used by Mavericks to build the initial state.
*/
constructor(args: FinancialConnectionsSheetActivityArgs) : this(
initialArgs = args
)
companion object {
const val KEY_SAVED_STATE = "financial_connections_sheet_state"
const val KEY_MANIFEST = "financial_connections_sheet_manifest"
const val KEY_WEB_AUTH_FLOW_STATUS = "financial_connections_sheet_web_auth_flow_status"
}
}

/**
Expand Down
Loading

0 comments on commit 060ad2e

Please sign in to comment.