Skip to content

@W-21471024: Update Compose Material 3 to v1.4.0#2871

Draft
JohnsonEricAtSalesforce wants to merge 22 commits intoforcedotcom:devfrom
JohnsonEricAtSalesforce:feature/w-21471024_update-compose-material-3-to-v1.4.0
Draft

@W-21471024: Update Compose Material 3 to v1.4.0#2871
JohnsonEricAtSalesforce wants to merge 22 commits intoforcedotcom:devfrom
JohnsonEricAtSalesforce:feature/w-21471024_update-compose-material-3-to-v1.4.0

Conversation

@JohnsonEricAtSalesforce
Copy link
Copy Markdown
Contributor

@JohnsonEricAtSalesforce JohnsonEricAtSalesforce commented Apr 23, 2026

🎸 Ready For Review 🥁

This is a fully automated update to the request Compose version plus the Kotlin 2 and many other updates it required. Additionally, I scoped all the dependency and build system updates that are relevant to ensure major release fourteen of the SDK is new and shiny. For a big win, it looks like we can resolve every Android Studio lint warning for Gradle except those related to newDSL=false. That requires the customized directory structure of the workspace to be brought back in line with Gradle's defaults - Perhaps that's doable, but to heavy a lift for this work item.

Happy Spring Cleaning 🍃

…mpatibility

Update Kotlin to version 2.1.0 across all build files to support Jetpack Compose Material 3 1.4.0
and resolve kotlinx.serialization version requirements:

- Update root build.gradle.kts: Kotlin gradle plugin 2.1.0 and Compose Compiler plugin 2.1.0
- Update buildSrc/build.gradle.kts: Kotlin gradle plugin and stdlib to 2.1.0
- Update libs/SalesforceSDK/build.gradle.kts: Apply Kotlin Compose plugin, update serialization to 2.1.0
- Update native/NativeSampleApps/AuthFlowTester/build.gradle.kts: Apply Kotlin Compose plugin, update serialization to 2.1.0
- Remove kotlinCompilerExtensionVersion configuration (integrated in Kotlin 2.0+)

With Kotlin 2.0+, the Compose Compiler is integrated into the Kotlin compiler itself,
eliminating the need for separate kotlinCompilerExtensionVersion configuration.

Note: Build currently blocked by unrelated MobileSync configuration issue that requires
separate investigation.
…tion

Fix "SoftwareComponent with name 'release' not found" and array conversion errors caused by
Kotlin 2.1.0 type system changes:

**Root Causes:**
- Kotlin 2.0+ enforces stricter type conversion for File/Path parameters
- arrayOf() and arrayListOf() in build scripts now require explicit handling
- Publishing plugin sourcesJar configuration incompatible with new type system

**Changes:**
- Replace all arrayOf() calls in sourceSets with direct vararg parameters
- Replace all arrayListOf() with listOf() in Jacoco file filters and includes
- Wrap sourceDirectories.setFrom() string paths with files() for proper type conversion
- Update sourcesJar task in publish-module.gradle.kts to use getSourceFiles()
- Update component access from components["release"] to components.getByName("release")

**Files Modified:**
- buildSrc/src/main/kotlin/publish-module.gradle.kts
- All library build.gradle.kts files (6 modules)
- All sample app build.gradle.kts files (5 apps)

Build now successfully compiles past configuration phase. Remaining compilation errors are
expected Compose 1.4.0 API compatibility issues (Icons imports, caretSize parameter).
Add Material Icons Extended dependency and fix deprecated API usages for Compose Material 3 1.4.0:

**Icons Import Issues:**
- Add androidx.compose.material:material-icons-extended dependency to SalesforceSDK
- Add androidx.compose.material:material-icons-extended dependency to AuthFlowTester
- Use BOM-managed version to ensure compatibility with Compose BOM 2025.07.00

**API Deprecations:**
- Remove caretSize parameter from RichTooltip in LoginView.kt (deprecated and removed in Material 3 1.4.0)
- The caretSize parameter was removed from the RichTooltip API in Material3 1.4.0

**Result:**
- All Compose icon references now resolve correctly
- AuthFlowTester module builds successfully
- No compilation errors remain for Compose 1.4.0 upgrade

This completes the Compose Material 3 upgrade from 1.3.2 to 1.4.0 along with the required
Kotlin 2.1.0 upgrade.
positionProvider = TooltipDefaults.rememberRichTooltipPositionProvider(),
tooltip = {
RichTooltip(
caretSize = DpSize(PADDING_SIZE.dp, PADDING_SIZE.dp),
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The RichTooltip in Material 3 1.4.0 uses its own internal default caret size that follows Material Design 3 specifications. The visual appearance will still include a caret (the small triangular pointer), but its size is now determined by the library rather than the application code.

Remove explanatory comments about kotlinCompilerExtensionVersion removal from:
- libs/SalesforceSDK/build.gradle.kts
- native/NativeSampleApps/AuthFlowTester/build.gradle.kts

These comments were unnecessary as the change is self-evident from the absence
of the configuration block and is already documented in the commit messages.

@Suppress("UnstableApiUsage")
composeOptions {
kotlinCompilerExtensionVersion = "1.5.14"
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Note: With Kotlin 2.0+, Compose Compiler is integrated into the Kotlin compiler and kotlinCompilerExtensionVersion is no longer needed

}

composeOptions {
kotlinCompilerExtensionVersion = "1.5.14"
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Note: With Kotlin 2.0+, Compose Compiler is integrated into the Kotlin compiler and kotlinCompilerExtensionVersion is no longer needed

@github-actions
Copy link
Copy Markdown

1 Warning
⚠️ libs/MobileSync/build.gradle.kts#L16 - A newer version of androidx.core:core-ktx than 1.16.0 is available: 1.18.0

Generated by 🚫 Danger

@github-actions
Copy link
Copy Markdown

2 Warnings
⚠️ libs/SalesforceReact/build.gradle.kts#L25 - A newer version of com.facebook.react:react-android than 0.79.3 is available: 0.85.2
⚠️ libs/SalesforceReact/build.gradle.kts#L26 - A newer version of androidx.core:core-ktx than 1.16.0 is available: 1.18.0

Generated by 🚫 Danger

@github-actions
Copy link
Copy Markdown

4 Warnings
⚠️ libs/SalesforceHybrid/build.gradle.kts#L16 - A newer version of org.apache.cordova:framework than 14.0.1 is available: 15.0.0
⚠️ libs/SalesforceHybrid/build.gradle.kts#L19 - A newer version of androidx.webkit:webkit than 1.14.0 is available: 1.15.0
⚠️ libs/SalesforceHybrid/build.gradle.kts#L20 - A newer version of androidx.core:core-splashscreen than 1.0.1 is available: 1.2.0
⚠️ libs/SalesforceHybrid/build.gradle.kts#L21 - A newer version of androidx.core:core-ktx than 1.16.0 is available: 1.18.0

Generated by 🚫 Danger

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 23, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 65.64%. Comparing base (535d8e4) to head (a6f79ad).
⚠️ Report is 1 commits behind head on dev.

Additional details and impacted files
@@             Coverage Diff              @@
##                dev    #2871      +/-   ##
============================================
+ Coverage     64.92%   65.64%   +0.71%     
- Complexity     2976     3024      +48     
============================================
  Files           223      223              
  Lines         17467    17594     +127     
  Branches       2490     2295     -195     
============================================
+ Hits          11341    11550     +209     
- Misses         4922     4975      +53     
+ Partials       1204     1069     -135     
Components Coverage Δ
Analytics 48.71% <ø> (ø)
SalesforceSDK 61.22% <ø> (+1.38%) ⬆️
Hybrid 59.05% <ø> (ø)
SmartStore 78.20% <ø> (ø)
MobileSync 81.70% <ø> (+0.01%) ⬆️
React 51.50% <ø> (ø)
Files with missing lines Coverage Δ
...m/salesforce/androidsdk/ui/components/LoginView.kt 54.47% <ø> (+10.75%) ⬆️

... and 41 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

- Update AGP to 9.1.1, Kotlin to 2.2.10, Gradle to 9.3.1
- Migrate kotlinOptions to compilerOptions DSL (required by Kotlin 2.2.10)
- Update Kotlin language version from 1.6 to 1.8 (1.6 no longer supported)
- Fix publish-module.gradle.kts for AGP 9.1.1 compatibility:
  - Remove duplicate kotlin("android") plugin (now included in android-library)
  - Use new LibraryExtension API (com.android.build.api.dsl)
  - Use withPlugin() timing to ensure extension availability
  - Fix closing brace structure
- Add AGP 9.1.1 configuration properties to gradle.properties
- Update compiler argument from -Xopt-in to -opt-in
- Kotlin serialization plugin: 2.1.0 → 2.2.10 (match Kotlin version)
- kotlinx-serialization-json: 1.6.3 → 1.11.0
- androidx.window: 1.4.0 → 1.5.1
- androidx.window-core: 1.4.0 → 1.5.1
- Replace deprecated lifecycle-extensions:2.2.0 with lifecycle-process:2.8.7
  (lifecycle-extensions is officially deprecated; lifecycle-process provides ProcessLifecycleOwner)

All updates tested and verified with full build.
Tested with full build across all modules - no compilation errors or
new warnings introduced. OkHttp 5.x maintains API compatibility with
existing SDK usage patterns.

Changes:
- OkHttp: 4.12.0 → 5.3.2 (major version update)

Impact:
- Core networking library used throughout SDK
- Declared as API dependency in SalesforceSDK
- All dependent modules (SmartStore, MobileSync, Hybrid, React, sample apps)
  build successfully
- No deprecation warnings for OkHttp API usage
- All existing code patterns remain compatible

Build verification:
✅ SalesforceSDK: BUILD SUCCESSFUL (156 tasks)
✅ Full workspace: BUILD SUCCESSFUL (1148 tasks)
✅ No OkHttp-related warnings or errors
- Firebase Messaging: 25.0.0 → 25.0.1
- androidx.work: 2.10.3 → 2.11.2
- MockK: 1.14.0 → 1.14.9

Already at latest versions (confirmed):
- Material Design: 1.13.0
- androidx.test (runner, rules, espresso): 1.7.0
- androidx.test.ext:junit: 1.3.0
- androidx.appcompat: 1.7.1
- Accompanist: 0.37.3

All updates tested with full build (1148 tasks). No compilation errors
or new warnings introduced.
…nspector

Test Dependencies:
- RestExplorer: androidx.test 1.5.x/3.5.0 → 1.7.0/3.7.0
  - runner: 1.5.1 → 1.7.0
  - rules: 1.5.0 → 1.7.0
  - espresso-core: 3.5.0 → 3.7.0
- AuthFlowTester: androidx.test:rules 1.6.1 → 1.7.0

Core Libraries:
- androidx.sqlite: 2.2.0 → 2.6.2 (SmartStore)
- SQLCipher Android: 4.10.0 → 4.14.0 (SmartStore)
  Note: SQLCipher 4.14.0 officially recommends androidx.sqlite 2.6.2
- androidx.webkit: 1.14.0 → 1.15.0 (SalesforceHybrid)
- androidx.core:core-splashscreen: 1.0.1 → 1.2.0 (SalesforceHybrid)

Compose Libraries:
- androidx.compose.runtime:runtime-android: 1.10.0 → 1.11.0 (AuthFlowTester)
- androidx.compose.ui:ui-test: 1.10.3 → 1.11.0 (AuthFlowTester)

All updates tested with full build (1148 tasks, 2m 48s).
BUILD SUCCESSFUL - no compilation errors or warnings.
- Update Android Gradle Plugin from 9.1.1 to 9.2.0
- Update Jacoco from 0.8.13 to 0.8.14
- Replace deprecated srcDirs() and srcDir() with directories.add()
  across all build.gradle.kts files to resolve AGP 9.x deprecation warnings

The srcDirs() method is deprecated in AGP 9.x in favor of using the
directories mutable set. This change updates all sourceSet configurations
across libraries and sample apps to use the new API.

Files modified:
- Root build.gradle.kts and buildSrc/build.gradle.kts (version updates)
- All library build files (SalesforceSDK, SmartStore, MobileSync, etc.)
- All sample app build files (RestExplorer, AccountEditor, etc.)
- Remove renderScript = true from buildFeatures in all build files
- Remove renderscript.directories from sourceSets configurations
- No functional impact as RenderScript is not used in the codebase

RenderScript has been deprecated since Android 12 (API 31) and will be
removed in AGP 10.0. The SDK does not use RenderScript anywhere - no
.rs files, no renderscript imports, and build tasks show NO-SOURCE.

This change eliminates 12 deprecation warnings per build and removes
unnecessary RenderScript compilation tasks, improving build performance.

Files modified:
- All 6 library modules (SalesforceSDK, SmartStore, MobileSync, etc.)
- All 5 native sample apps (RestExplorer, AuthFlowTester, etc.)
- 2 hybrid sample apps (AccountEditor, MobileSyncExplorerHybrid)

Verified: Build succeeds with no RenderScript warnings or errors.
- Comprehensive step-by-step migration document
- Addresses ~17 deprecation warnings per build
- Required before AGP 10.0 upgrade
- Includes troubleshooting, rollback procedures, and testing strategy

This document provides a complete guide for enabling android.newDsl=true,
which will eliminate android {} block and variant API deprecation warnings.

The migration is estimated at 2-4 hours with low-medium risk.
- Replace task<Exec>("buildReactTestBundle") with tasks.register<Exec>()
- Replace task("buildReactTestBundleIfNotExists") with tasks.register()
- Refactor conditional logic to use onlyIf{} and doFirst{} for lazy evaluation

The old task() API has been deprecated since Gradle 4.9 (2018) and uses
eager task configuration which impacts build performance. The new
tasks.register() API provides lazy task configuration, only configuring
tasks when they are actually needed.

Changes:
- Line 120: task<Exec>() → tasks.register<Exec>()
- Lines 158-164: Moved file existence check to onlyIf{}, directory
  creation to doFirst{}, and dependsOn() stays in configuration block

This eliminates 2 deprecation warnings:
- 'fun task(name: String, configureAction: Action<in Task>): Task' is deprecated

Verified:
- Tasks appear in task list (buildReactTestBundle, buildReactTestBundleIfNotExists)
- No task deprecation warnings in build output
- Tasks properly registered with preDebugAndroidTestBuild dependency

Note: The tasks themselves may fail at execution time if React Native
dependencies are not installed, but this is a pre-existing condition
unrelated to this API migration.
Add inline documentation for the android.newDsl=false deprecation that
was analyzed and deferred for future resolution.

Changes:
- gradle.properties: Add TODO comment noting newDsl migration should be
  done in dedicated work item
- All build.gradle.kts files: Add TODO comments on android {} blocks
  indicating they cannot be resolved until newDsl=true is enabled
- publish-module.gradle.kts: Fix indentation in pom{} block and
  restructure signing{} block placement for consistency

Background:
The android.newDsl=false setting causes ~17 deprecation warnings:
- 12× android {} block deprecation warnings
- 4× variant API warnings (libraryVariants, testVariants, etc.)
- 1× newDsl property deprecation warning

This migration was analyzed and documented in MIGRATION_android_newDsl.md
(commit 92dbece) but explicitly deferred per user request. The TODO
comments ensure this technical debt is visible in the code until the
migration is completed.

The migration will be required before upgrading to AGP 10.0, which will
remove support for the old DSL entirely.

Related: MIGRATION_android_newDsl.md
The android.newDsl=true migration was attempted but is BLOCKED due to
incompatibility between Kotlin Gradle Plugin 2.2.10 and AGP 9.2.0's
new DSL when android.builtInKotlin=false.

Blocker Details:
- Kotlin plugin with newDsl=true attempts cast to BaseExtension
- AGP with newDsl=true provides LibraryExtensionImpl (new DSL type)
- Cast fails with ClassCastException

Alternative approach (AGP built-in Kotlin) also fails:
- Kotlin compilation shows NO-SOURCE
- Java compilation fails due to missing Kotlin classes

Migration cannot proceed until:
1. Kotlin Gradle Plugin is updated to support AGP 9.x new DSL, OR
2. AGP's built-in Kotlin support is properly configured, OR
3. Migration is deferred until AGP 10.0 (which removes old DSL entirely)

See MIGRATION_android_newDsl_BLOCKER.md for complete analysis.

Impact: ~17 deprecation warnings remain until blocker is resolved.
@github-actions
Copy link
Copy Markdown

1 Warning
⚠️ Big PR, try to keep changes smaller if you can.

Generated by 🚫 Danger

@github-actions
Copy link
Copy Markdown

Job Summary for Gradle

Pull Request :: test-android
Gradle Root Project Requested Tasks Gradle Version Build Outcome Build Scan®
SalesforceMobileSDK-Android native:NativeSampleApps:AuthFlowTester:assembleDebug 9.4.1 Build Scan not published

Documents second migration attempt using Kotlin Gradle Plugin 2.3.21 which
provided clearer error messages. Root cause confirmed: AGP 9.0's built-in
Kotlin support is incompatible with the project's non-standard source layout
(src/ instead of src/main/java). Migration remains blocked until source
directories are restructured to standard Android layout.
Updated hardcoded version assertions to match SQLCipher Android 4.14.1:
- SQLCipher version: 4.14.0 community (runtime version)
- Cipher provider version: 1.18.2 (LibTomCrypt)

Values verified through actual test execution on Pixel_9_Pro_XL_API_36.
Note: SQLCipher dependency 4.14.1 reports itself as 4.14.0 at runtime.
SQLCipher 4.14.x uses LibTomCrypt instead of OpenSSL.
Remove explicit version specifications from Compose artifacts to allow
the Compose BOM (2026.04.01) to manage versions automatically.

Changes:
- Remove composeVersion variable (was set to non-existent 1.13.0)
- Remove explicit versions from Compose dependencies
- Let BOM provide compatible versions (1.11.0) for all Compose artifacts

This fixes dependency resolution failures where version 1.13.0 was
specified but doesn't exist in Maven repositories. The BOM pattern
ensures all Compose libraries use compatible versions without
version conflicts.

Verified: App builds successfully, installs, and runs without errors.
@github-actions
Copy link
Copy Markdown

Job Summary for Gradle

Pull Request :: test-android
Gradle Root Project Requested Tasks Gradle Version Build Outcome Build Scan®
SalesforceMobileSDK-Android native:NativeSampleApps:AuthFlowTester:assembleDebug 9.4.1 Build Scan not published
SalesforceMobileSDK-Android native:NativeSampleApps:AuthFlowTester:assembleAndroidTest 9.4.1 Build Scan not published

Add Compose BOM to androidTestImplementation configuration to allow
BOM-managed Compose test dependencies to resolve properly.

Problem:
- androidx.compose.ui:ui-test-junit4 and ui-test were failing with
  empty versions (e.g., "androidx.compose.ui:ui-test-junit4:.")
- The BOM was only declared for implementation, not androidTest

Solution:
- Add androidTestImplementation(platform("androidx.compose:compose-bom:2026.04.01"))
- This allows Compose test artifacts to inherit versions from the BOM

Verified:
- debugAndroidTestRuntimeClasspath now resolves all dependencies
- compileDebugAndroidTestSources: BUILD SUCCESSFUL
- assembleDebugAndroidTest: BUILD SUCCESSFUL
- Updated kotlin-gradle-plugin to 2.3.20 in build.gradle.kts and buildSrc
- Updated compose-compiler-gradle-plugin to 2.3.20
- Updated kotlin serialization plugin to 2.3.20 in AuthFlowTester and SalesforceSDK
- Removed redundant kotlin-stdlib dependency from buildSrc (let gradle plugin provide it)
- Updated language/API version from 1.8 to 2.1 to match Kotlin 2.3.20 requirements

This resolves the 'Cannot access Serializable' lint error in AuthFlowTester
build.gradle.kts line 78, which was caused by version mismatch between
kotlin-gradle-plugin 2.2.10 and kotlin-stdlib 2.3.20.

Fixes: Version conflict between Kotlin gradle plugin and stdlib
Fixes: Language version 1.8 no longer supported in Kotlin 2.3.20
Fixes: Lint error on packaging resources block in AuthFlowTester
…ains.kotlin:compose-compiler-gradle-plugin:2.3.21ˆ Dependency And Whitespace Cleanup)
@github-actions
Copy link
Copy Markdown

Job Summary for Gradle

Pull Request :: test-android
Gradle Root Project Requested Tasks Gradle Version Build Outcome Build Scan®
SalesforceMobileSDK-Android libs:SalesforceHybrid:convertCodeCoverage 9.4.1 Build Scan not published
SalesforceMobileSDK-Android libs:SalesforceHybrid:lint 9.4.1 Build Scan not published
SalesforceMobileSDK-Android libs:SalesforceHybrid:assembleAndroidTest 9.4.1 Build Scan not published
SalesforceMobileSDK-Android native:NativeSampleApps:RestExplorer:assembleDebug 9.4.1 Build Scan not published

@github-actions
Copy link
Copy Markdown

Job Summary for Gradle

Pull Request :: test-android
Gradle Root Project Requested Tasks Gradle Version Build Outcome Build Scan®
SalesforceMobileSDK-Android libs:SalesforceHybrid:convertCodeCoverage 9.4.1 Build Scan not published
SalesforceMobileSDK-Android libs:SalesforceHybrid:lint 9.4.1 Build Scan not published
SalesforceMobileSDK-Android libs:SalesforceHybrid:assembleAndroidTest 9.4.1 Build Scan not published
SalesforceMobileSDK-Android native:NativeSampleApps:RestExplorer:assembleDebug 9.4.1 Build Scan not published

2 similar comments
@github-actions
Copy link
Copy Markdown

Job Summary for Gradle

Pull Request :: test-android
Gradle Root Project Requested Tasks Gradle Version Build Outcome Build Scan®
SalesforceMobileSDK-Android libs:SalesforceHybrid:convertCodeCoverage 9.4.1 Build Scan not published
SalesforceMobileSDK-Android libs:SalesforceHybrid:lint 9.4.1 Build Scan not published
SalesforceMobileSDK-Android libs:SalesforceHybrid:assembleAndroidTest 9.4.1 Build Scan not published
SalesforceMobileSDK-Android native:NativeSampleApps:RestExplorer:assembleDebug 9.4.1 Build Scan not published

@github-actions
Copy link
Copy Markdown

Job Summary for Gradle

Pull Request :: test-android
Gradle Root Project Requested Tasks Gradle Version Build Outcome Build Scan®
SalesforceMobileSDK-Android libs:SalesforceHybrid:convertCodeCoverage 9.4.1 Build Scan not published
SalesforceMobileSDK-Android libs:SalesforceHybrid:lint 9.4.1 Build Scan not published
SalesforceMobileSDK-Android libs:SalesforceHybrid:assembleAndroidTest 9.4.1 Build Scan not published
SalesforceMobileSDK-Android native:NativeSampleApps:RestExplorer:assembleDebug 9.4.1 Build Scan not published

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.

1 participant