Skip to content

Conversation

@carlosmuvi-stripe
Copy link
Contributor

@carlosmuvi-stripe carlosmuvi-stripe commented Sep 16, 2025

Summary

  • Even if inheriting MaterialTheme is required for Identity, we should handle non-Material theme usage gracefully to avoid crashes.
  • This PR ensures we fallback to default MaterialTheme values for AppCompat/other themes

AppCompat theme is still required

Motivation

👻

java.lang.IllegalArgumentException: createMdcTheme requires the host context's theme to extend Theme.MaterialComponents

Testing

  • Added tests
  • Modified tests
  • Manually verified

Screenshots

Before After
before screenshot after screenshot

Changelog

@github-actions
Copy link
Contributor

Risky Change

This is considered a risky change because it adjusts the sample app build.gradle, please review carefully.
We've seen issues in the past which resulted in failed builds for merchants. Please make sure the build.gradle change is intended.

By adding the label accept-risky-change to this PR, I acknowledge that I'm changing an example app and have verified that the SDK remains in a shippable state.

@carlosmuvi-stripe carlosmuvi-stripe changed the title [Identity] Don't crash on non-material theme [Identity] Gracefully handle non-material themes. Sep 16, 2025
Comment on lines +57 to +65
create("appcompat") {
manifestPlaceholders["appTheme"] = "@style/Theme.AppCompatTest"
manifestPlaceholders["appIcon"] = "@drawable/merchant_logo_purple"
manifestPlaceholders["appIconRound"] = "@drawable/merchant_logo_purple"

dimension = "theme"
applicationIdSuffix = ".appcompat"
versionNameSuffix = "-appcompat"
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

to test non-material theming, now you can use

./gradlew :identity-example:installAppcompatDebug

@github-actions
Copy link
Contributor

github-actions bot commented Sep 16, 2025

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.1 MiB │   2.1 MiB │ +1.5 KiB │   4.3 MiB │   4.3 MiB │ +1.6 KiB 
     arsc │     1 MiB │   1.1 MiB │ +4.6 KiB │     1 MiB │   1.1 MiB │ +4.6 KiB 
 manifest │   2.3 KiB │   2.3 KiB │     +1 B │     8 KiB │     8 KiB │      0 B 
      res │ 302.7 KiB │ 302.7 KiB │     -5 B │ 456.5 KiB │ 456.5 KiB │      0 B 
   native │   7.9 MiB │   7.9 MiB │      0 B │  19.3 MiB │  19.3 MiB │      0 B 
    asset │   7.7 KiB │   7.7 KiB │    -47 B │   7.5 KiB │   7.4 KiB │    -47 B 
    other │  95.7 KiB │    96 KiB │   +237 B │ 183.5 KiB │ 183.8 KiB │   +256 B 
──────────┼───────────┼───────────┼──────────┼───────────┼───────────┼──────────
    total │  11.4 MiB │  11.4 MiB │ +6.3 KiB │  25.3 MiB │  25.3 MiB │ +6.4 KiB 

 DEX     │ old   │ new   │ diff             
─────────┼───────┼───────┼──────────────────
   files │     1 │     1 │  0               
 strings │ 20687 │ 20696 │ +9 (+1052 -1043) 
   types │  6505 │  6509 │ +4 (+1046 -1042) 
 classes │  5269 │  5272 │ +3 (+922 -919)   
 methods │ 31514 │ 31523 │ +9 (+9818 -9809) 
  fields │ 18235 │ 18243 │ +8 (+6350 -6342) 

 ARSC    │ old  │ new  │ diff       
─────────┼──────┼──────┼────────────
 configs │  164 │  164 │  0         
 entries │ 3648 │ 3650 │ +2 (+2 -0)
APK
     compressed      │    uncompressed     │                                                         
──────────┬──────────┼──────────┬──────────┤                                                         
 size     │ diff     │ size     │ diff     │ path                                                    
──────────┼──────────┼──────────┼──────────┼─────────────────────────────────────────────────────────
  1.1 MiB │ +4.6 KiB │  1.1 MiB │ +4.6 KiB │ ∆ resources.arsc                                        
  2.1 MiB │ +1.5 KiB │  4.3 MiB │ +1.6 KiB │ ∆ classes.dex                                           
    190 B │   +190 B │      6 B │     +6 B │ + META-INF/androidx.compose.material3_material3.version 
    127 B │   +127 B │      5 B │     +5 B │ + META-INF/services/M4.w                                
    127 B │   +127 B │      5 B │     +5 B │ + META-INF/services/N4.a                                
          │   -127 B │          │     -5 B │ - META-INF/services/L4.w                                
          │   -127 B │          │     -5 B │ - META-INF/services/M4.a                                
  6.8 KiB │    -42 B │  6.7 KiB │    -42 B │ ∆ assets/dexopt/baseline.prof                           
 29.2 KiB │    +33 B │ 64.7 KiB │   +125 B │ ∆ META-INF/CERT.SF                                      
 25.9 KiB │    +13 B │ 64.7 KiB │   +125 B │ ∆ META-INF/MANIFEST.MF                                  
    905 B │     -5 B │    773 B │     -5 B │ ∆ assets/dexopt/baseline.profm                          
  2.3 KiB │     +1 B │    8 KiB │      0 B │ ∆ AndroidManifest.xml                                   
    636 B │     -1 B │  1.2 KiB │      0 B │ ∆ res/2n.xml                                            
    377 B │     -1 B │    724 B │      0 B │ ∆ res/7s.xml                                            
    532 B │     +1 B │    984 B │      0 B │ ∆ res/aT.xml                                            
    438 B │     -1 B │    744 B │      0 B │ ∆ res/cc.xml                                            
    377 B │     -1 B │    724 B │      0 B │ ∆ res/k9.xml                                            
    750 B │     -1 B │  1.7 KiB │      0 B │ ∆ res/p0.xml                                            
    617 B │     -1 B │  1.2 KiB │      0 B │ ∆ res/uR.xml                                            
    618 B │     -1 B │  1.1 KiB │      0 B │ ∆ res/xa.xml                                            
    378 B │     +1 B │    724 B │      0 B │ ∆ res/yT.xml                                            
  1.2 KiB │     +1 B │  1.2 KiB │      0 B │ ∆ META-INF/CERT.RSA                                     
──────────┼──────────┼──────────┼──────────┼─────────────────────────────────────────────────────────
  3.2 MiB │ +6.3 KiB │  5.5 MiB │ +6.4 KiB │ (total)
DEX
STRINGS:

   old   │ new   │ diff             
  ───────┼───────┼──────────────────
   20687 │ 20696 │ +9 (+1052 -1043) 
  
  + LA3/a;
  + LA3/b;
  + LA3/c;
  + LA3/d;
  + LA3/e;
  + LA3/f;
  + LA3/g;
  + LB4/f;
  + LB4/g;
  + LB4/h;
  + LB4/i;
  + LB4/j;
  + LB4/k;
  + LB4/l;
  + LB4/m;
  + LB4/n;
  + LB4/o;
  + LB4/p;
  + LB4/q;
  + LB4/r;
  + LB4/s;
  + LB4/t;
  + LB4/u;
  + LB4/v;
  + LB4/w;
  + LB4/x;
  + LC3/c;
  + LC3/d;
  + LC3/e;
  + LC4/b;
  + LC4/c;
  + LC4/d;
  + LC4/e;
  + LD/s0;
  + LE4/b;
  + LE4/c;
  + LE4/d;
  + LE4/e;
  + LF3/a;
  + LF3/b;
  + LF3/c;
  + LF3/d;
  + LF3/e;
  + LF3/f;
  + LF3/g;
  + LF3/h;
  + LF3/i;
  + LF3/j;
  + LF3/k;
  + LF3/l;
  + LF3/m;
  + LG4/e;
  + LG4/f;
  + LG4/g;
  + LG4/h;
  + LG4/i;
  + LI3/A;
  + LI3/B;
  + LI3/C;
  + LI3/D;
  + LI3/E;
  + LI3/F;
  + LI3/b;
  + LI3/c;
  + LI3/d;
  + LI3/e;
  + LI3/f;
  + LI3/g;
  + LI3/h;
  + LI3/i;
  + LI3/j;
  + LI3/k;
  + LI3/l;
  + LI3/m;
  + LI3/n;
  + LI3/o;
  + LI3/p;
  + LI3/q;
  + LI3/r;
  + LI3/s;
  + LI3/t;
  + LI3/u;
  + LI3/v;
  + LI3/w;
  + LI3/x;
  + LI3/y;
  + LI3/z;
  + LJ4/h;
  + LJ4/i;
  + LJ4/j;
  + LJ4/k;
  + LJ4/l;
  + LJ4/m;
  + LJ4/n;
  + LJ4/o;
  + LJ4/p;
  + LJ4/q;
  + LJ4/r;
  + LK3/c;
  + LK4/b;
  + LK4/c;
  + LK4/d;
  + LK4/e;
  + LK4/f;
  + LK4/g;
  + LM3/n;
  + LM3/o;
  + LM3/p;
  + LM3/q;
  + LM3/r;
  + LM4/A0;
  + LM4/A;
  + LM4/B;
  + LM4/C;
  + LM4/D;
  + LM4/E;
  + LM4/F;
  + LM4/G;
  + LM4/H;
  + LM4/I;
  + LM4/J;
  + LM4/K;
  + LM4/L;
  + LM4/M;
  + LM4/N;
  + LM4/O;
  + LM4/P;
  + LM4/Q;
  + LM4/S;
  + LM4/T;
  + LM4/U;
  + LM4/V;
  + LM4/W;
  + LM4/X;
  + LM4/Y;
  + LM4/Z;
  + LM4/a0;
  + LM4/b0;
  + LM4/c0;
  + LM4/d0;
  + LM4/e0;
  + LM4/f0;
  + LM4/f;
  + LM4/g0;
  + LM4/g;
  + LM4/h0;
  + LM4/h;
  + LM4/i0;
  + LM4/i;
  + LM4/j0;
  + LM4/j;
  + LM4/k0;
  + LM4/k;
  + LM4/l0;
  + LM4/l;
  + LM4/m0;
  + LM4/m;
  + LM4/n0;
  + LM4/n;
  + LM4/o0;
  + LM4/o;
  + LM4/p0;
  + LM4/p;
  + LM4/q0;
  + LM4/q;
  + LM4/r0;
  + LM4/r;
  + LM4/s0;
  + LM4/s;
  + LM4/t0;
  + LM4/t;
  + LM4/u0;
  + LM4/u;
  + LM4/v0;
  + LM4/v;
  + LM4/w0;
  + LM4/w;
  + LM4/x0;
  + LM4/x;
  + LM4/y0;
  + LM4/y;
  + LM4/z0;
  + LM4/z;
  + LP3/F;
  + LP3/G;
  + LP4/H;
  + LP4/I;
  + LP4/J;
  + LP4/K;
  + LP4/L;
  + LP4/M;
  + LP4/N;
  + LP4/O;
  + LP4/P;
  + LP4/Q;
  + LP4/S;
  + LP4/T;
  + LP4/U;
  + LP4/V;
  + LP4/W;
  + LP4/X;
  + LP4/Y;
  + LP4/Z;
  + LP4/a0;
  + LQ3/A;
  + LQ3/B;
  + LQ3/C;
  + LQ3/D;
  + LQ3/E;
  + LQ3/d;
  + LQ3/e;
  + LQ3/f;
  + LQ3/g;
  + LQ3/h;
  + LQ3/i;
  + LQ3/j;
  + LQ3/k;
  + LQ3/l;
  + LQ3/m;
  + LQ3/n;
  + LQ3/o;
  + LQ3/p;
  + LQ3/q;
  + LQ3/r;
  + LQ3/s;
  + LQ3/t;
  + LQ3/u;
  + LQ3/v;
  + LQ3/w;
  + LQ3/x;
  + LQ3/y;
  + LQ3/z;
  + LQ4/A;
  + LQ4/B;
  + LQ4/C;
  + LQ4/D;
  + LQ4/E;
  + LQ4/F;
  + LQ4/G;
  + LQ4/w;
  + LQ4/x;
  + LQ4/y;
  + LQ4/z;
  + LR4/a;
  + LR4/b;
  + LR4/c;
  + LR4/d;
  + LR4/e;
  + LR4/f;
  + LR4/g;
  + LR4/h;
  + LR4/i;
  + LR4/j;
  + LR4/k;
  + LR4/l;
  + LR4/m;
  + LR4/n;
  + LR4/o;
  + LR4/p;
  + LR4/q;
  + LR4/r;
  + LR4/s;
  + LR4/t;
  + LR4/u;
  + LR4/v;
  + LT2/c;
  + LT3/A;
  + LT3/B;
  + LT3/C;
  + LT3/D;
  + LT3/E;
  + LT3/F;
  + LT3/G;
  + LT3/H;
  + LT3/o;
  + LT3/p;
  + LT3/q;
  + LT3/r;
  + LT3/s;
  + LT3/t;
  + LT3/u;
  + LT3/v;
  + LT3/w;
  + LT3/x;
  + LT3/y;
  + LT3/z;
  + LT4/j;
  + LT4/k;
  + LT4/l;
  + LT4/m;
  + LU2/b;
  + LV3/A0;
  + LV3/A;
  + LV3/B0;
  + LV3/B;
  + LV3/C0;
  + LV3/C;
  + LV3/D0;
  + LV3/D;
  + LV3/E0;
  + LV3/E;
  + LV3/F0;
  + LV3/F;
  + LV3/G0;
  + LV3/G;
  + LV3/H0;
  + LV3/H;
  + LV3/I0;
  + LV3/I;
  + LV3/J0;
  + LV3/J;
  + LV3/K0;
  + LV3/K;
  + LV3/L0;
  + LV3/L;
  + LV3/M0;
  + LV3/M;
  + LV3/N0;
  + LV3/N;
  + LV3/O0;
  + LV3/O;
  + LV3/P0;
  + LV3/P;
  + LV3/Q0;
  + LV3/Q;
  + LV3/R0;
  + LV3/S0;
  + LV3/S;
  + LV3/T0;
  + LV3/T;
  + LV3/U0;
  + LV3/U;
  + LV3/V;
  + LV3/W;
  + LV3/X;
  + LV3/Y;
  + LV3/Z;
  + LV3/a0;
  + LV3/b0;
  + LV3/c0;
  + LV3/d0;
  + LV3/e0;
  + LV3/f0;
  + LV3/g0;
  + LV3/h0;
  + LV3/i0;
  + LV3/j0;
  + LV3/k0;
  + LV3/l0;
  + LV3/m0;
  + LV3/n0;
  + LV3/o0;
  + LV3/p0;
  + LV3/p;
  + LV3/q0;
  + LV3/q;
  + LV3/r0;
  + LV3/r;
  + LV3/s0;
  + LV3/s;
  + LV3/t0;
  + LV3/t;
  + LV3/u0;
  + LV3/u;
  + LV3/v0;
  + LV3/v;
  + LV3/w0;
  + LV3/w;
  + LV3/x0;
  + LV3/x;
  + LV3/y0;
  + LV3/y;
  + LV3/z0;
  + LV3/z;
  + LV4/f;
  + LV4/g;
  + LV4/h;
  + LV4/i;
  + LV4/j;
  + LW4/a;
  + LW4/b;
  + LW4/c;
  + LW4/d;
  + LW4/e;
  + LX3/A0;
  + LX3/A;
  + LX3/B0;
  + LX3/B;
  + LX3/C0;
  + LX3/C;
  + LX3/
...✂
ARSC
ENTRIES:

   old  │ new  │ diff       
  ──────┼──────┼────────────
   3648 │ 3650 │ +2 (+2 -0) 
  + string/dialog
  + style/Theme.AppCompatTest

Comment on lines 183 to 214
@Composable
private fun detectHostThemeType(): HostThemeType {
val context = LocalContext.current

val isMaterialTheme = remember {
runCatching {
context.obtainStyledAttributes(MaterialR.styleable.ThemeAdapterMaterialTheme).use { ta ->
ta.hasValue(MaterialR.styleable.ThemeAdapterMaterialTheme_isMaterialTheme)
}
}.getOrDefault(false)
}

val isMaterial3Theme = remember {
runCatching {
context.obtainStyledAttributes(Material3R.styleable.ThemeAdapterMaterial3Theme).use { ta ->
ta.hasValue(Material3R.styleable.ThemeAdapterMaterial3Theme_isMaterial3Theme)
}
}.getOrDefault(false)
}

return when {
isMaterialTheme -> HostThemeType.MaterialComponents
isMaterial3Theme -> HostThemeType.Material3
else -> HostThemeType.AppCompat
}
}

private enum class HostThemeType {
MaterialComponents,
Material3,
AppCompat
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Extracted this from payments. Cannot move to a shared module (stripe-ui-core) since it requires mdc / material theming related dependencies that other SDKs might not use.

Comment on lines +64 to +68
val defaultParameters = ThemeParameters(
colors = MaterialTheme.colors,
typography = MaterialTheme.typography,
shapes = MaterialTheme.shapes
)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Use default Material theme if theme params cannot be extracted from a MaterialComponents theme.

@carlosmuvi-stripe carlosmuvi-stripe removed the request for review from Twigz September 17, 2025 16:41
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