Skip to content

Conversation

@JohnsonEricAtSalesforce
Copy link
Contributor

@JohnsonEricAtSalesforce JohnsonEricAtSalesforce commented Feb 4, 2026

🎸 Ready For Review 🥁

This updates the screen lock setup activity to support right-to-left text layouts along with a much heftier effort to migrate from Java to Kotlin, layout using Jetpack Compose and provide comprehensive unit tests.

All deprecations are resolved as well and the sources should have no inspector warnings.

To test, provide the strings used by the activity in an RTL language such as Arabic. Then, set the system language to that language.

@github-actions
Copy link

github-actions bot commented Feb 4, 2026

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

Generated by 🚫 Danger

@@ -22,6 +22,7 @@ dependencies {
api("androidx.browser:browser:1.8.0") // Update requires API 36 compileSdk
Copy link

@github-actions github-actions bot Feb 5, 2026

Choose a reason for hiding this comment

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

⚠️ A newer version of androidx.browser:browser than 1.8.0 is available: 1.9.0

@@ -22,6 +22,7 @@ dependencies {
api("androidx.browser:browser:1.8.0") // Update requires API 36 compileSdk
api("androidx.work:work-runtime-ktx:2.10.3")
Copy link

@github-actions github-actions bot Feb 5, 2026

Choose a reason for hiding this comment

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

⚠️ A newer version of androidx.work:work-runtime-ktx than 2.10.3 is available: 2.11.1

@github-actions
Copy link

github-actions bot commented Feb 5, 2026

23 Warnings
⚠️ libs/SalesforceSDK/build.gradle.kts#L19 - A newer version of com.squareup.okhttp3:okhttp than 4.12.0 is available: 5.3.2
⚠️ libs/SalesforceSDK/build.gradle.kts#L20 - A newer version of com.google.firebase:firebase-messaging than 25.0.0 is available: 25.0.1
⚠️ libs/SalesforceSDK/build.gradle.kts#L21 - A newer version of androidx.core:core than 1.16.0 is available: 1.17.0
⚠️ libs/SalesforceSDK/build.gradle.kts#L30 - A newer version of androidx.core:core-ktx than 1.16.0 is available: 1.17.0
⚠️ libs/SalesforceSDK/build.gradle.kts#L31 - A newer version of androidx.activity:activity-ktx than 1.10.1 is available: 1.12.4
⚠️ libs/SalesforceSDK/build.gradle.kts#L32 - A newer version of androidx.activity:activity-compose than 1.10.1 is available: 1.12.4
⚠️ libs/SalesforceSDK/build.gradle.kts#L33 - A newer version of androidx.lifecycle:lifecycle-viewmodel-ktx than 2.8.7 is available: 2.10.0
⚠️ libs/SalesforceSDK/build.gradle.kts#L34 - A newer version of androidx.lifecycle:lifecycle-viewmodel-compose than 2.8.7 is available: 2.10.0
⚠️ libs/SalesforceSDK/build.gradle.kts#L35 - A newer version of androidx.lifecycle:lifecycle-viewmodel-savedstate than 2.8.7 is available: 2.10.0
⚠️ libs/SalesforceSDK/build.gradle.kts#L36 - A newer version of androidx.lifecycle:lifecycle-service than 2.8.7 is available: 2.10.0
⚠️ libs/SalesforceSDK/build.gradle.kts#L37 - A newer version of org.jetbrains.kotlinx:kotlinx-serialization-json than 1.6.3 is available: 1.10.0
⚠️ libs/SalesforceSDK/build.gradle.kts#L38 - A newer version of androidx.window:window than 1.4.0 is available: 1.5.1
⚠️ libs/SalesforceSDK/build.gradle.kts#L39 - A newer version of androidx.window:window-core than 1.4.0 is available: 1.5.1
⚠️ libs/SalesforceSDK/build.gradle.kts#L40 - A newer version of androidx.compose.material3:material3-android than 1.3.2 is available: 1.4.0
⚠️ libs/SalesforceSDK/build.gradle.kts#L41 - A newer version of androidx.compose:compose-bom than 2025.07.00 is available: 2026.02.00
⚠️ libs/SalesforceSDK/build.gradle.kts#L42 - A newer version of androidx.compose.foundation:foundation-android than 1.8.2 is available: 1.10.3
⚠️ libs/SalesforceSDK/build.gradle.kts#L43 - A newer version of androidx.compose.runtime:runtime-livedata than 1.8.2 is available: 1.10.3
⚠️ libs/SalesforceSDK/build.gradle.kts#L44 - A newer version of androidx.compose.ui:ui-tooling-preview-android than 1.8.2 is available: 1.10.3
⚠️ libs/SalesforceSDK/build.gradle.kts#L45 - A newer version of androidx.compose.material:material than 1.8.2 is available: 1.10.3
⚠️ libs/SalesforceSDK/build.gradle.kts#L47 - A newer version of androidx.compose.ui:ui-tooling than 1.8.2 is available: 1.10.3
⚠️ libs/SalesforceSDK/build.gradle.kts#L48 - A newer version of androidx.compose.ui:ui-test-manifest than 1.8.2 is available: 1.10.3
⚠️ libs/SalesforceSDK/build.gradle.kts#L54 - A newer version of androidx.compose.ui:ui-test-junit4 than 1.8.2 is available: 1.10.3
⚠️ libs/SalesforceSDK/build.gradle.kts#L55 - A newer version of io.mockk:mockk-android than 1.14.0 is available: 1.14.9

Generated by 🚫 Danger

@codecov
Copy link

codecov bot commented Feb 5, 2026

Codecov Report

❌ Patch coverage is 97.08738% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 63.90%. Comparing base (c9e962d) to head (bfefa75).
⚠️ Report is 6 commits behind head on dev.

Files with missing lines Patch % Lines
...com/salesforce/androidsdk/ui/ScreenLockActivity.kt 97.85% 0 Missing and 3 partials ⚠️
...esforce/androidsdk/ui/components/ScreenLockView.kt 93.75% 0 Missing and 3 partials ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##                dev    #2835      +/-   ##
============================================
+ Coverage     63.24%   63.90%   +0.66%     
- Complexity     2825     2875      +50     
============================================
  Files           216      219       +3     
  Lines         16982    17064      +82     
  Branches       2418     2423       +5     
============================================
+ Hits          10740    10905     +165     
+ Misses         5073     4990      -83     
  Partials       1169     1169              
Components Coverage Δ
Analytics 47.92% <ø> (ø)
SalesforceSDK 57.65% <97.08%> (+1.31%) ⬆️
Hybrid 59.05% <ø> (ø)
SmartStore 78.20% <ø> (ø)
MobileSync 81.68% <ø> (ø)
React 52.36% <ø> (ø)
Files with missing lines Coverage Δ
...rc/com/salesforce/androidsdk/ui/DevInfoActivity.kt 59.43% <ø> (ø)
...m/salesforce/androidsdk/ui/LoginOptionsActivity.kt 87.62% <ø> (ø)
...om/salesforce/androidsdk/ui/ScreenLockViewModel.kt 100.00% <100.00%> (ø)
...salesforce/androidsdk/ui/UserInterfaceConstants.kt 100.00% <100.00%> (ø)
...ce/androidsdk/ui/components/LoginServerListItem.kt 61.48% <ø> (ø)
...m/salesforce/androidsdk/ui/components/LoginView.kt 43.83% <ø> (ø)
...orce/androidsdk/ui/components/PickerBottomSheet.kt 76.04% <ø> (ø)
...ce/androidsdk/ui/components/UserAccountListItem.kt 54.28% <ø> (ø)
...com/salesforce/androidsdk/ui/ScreenLockActivity.kt 97.85% <97.85%> (ø)
...esforce/androidsdk/ui/components/ScreenLockView.kt 93.75% <93.75%> (ø)

... and 1 file 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.

@JohnsonEricAtSalesforce JohnsonEricAtSalesforce force-pushed the feature/w-19368426_msdk-rewrite-android-screen-lock_a.k.a-passcode_for-rtl-ui branch 2 times, most recently from bcf7c35 to 282337b Compare February 5, 2026 21:23
Copy link
Contributor

@brandonpage brandonpage left a comment

Choose a reason for hiding this comment

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

Just a couple high level comments while you are in draft. 👍

import com.salesforce.androidsdk.R.string.sf__server_remove_content_description
import com.salesforce.androidsdk.R.string.sf__server_url_delete
import com.salesforce.androidsdk.config.LoginServerManager.LoginServer
import com.salesforce.androidsdk.ui.PADDING_SIZE
Copy link
Contributor

@brandonpage brandonpage Feb 5, 2026

Choose a reason for hiding this comment

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

The local PADDING_SIZE is not removed.

Copy link
Contributor Author

@JohnsonEricAtSalesforce JohnsonEricAtSalesforce Feb 7, 2026

Choose a reason for hiding this comment

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

When I was basing the new ScreenLockActivity off other recent Compose implementations, I noticed this PADDING_SIZE and CORNER_RADIUS where used in a lot of disparate sources though still defined in LoginView.kt. Doesn't it seem they should be in a common location? I created UserInterfaceConstants.kt but we could do something different. There may be other values as well.

* An activity that locks the app behind the operating system's provided
* authentication.
*/
internal class ScreenLockActivity : FragmentActivity() {
Copy link
Contributor

Choose a reason for hiding this comment

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

Technically for Semver this should be open class ScreenLockActivity (public). It wasn't possible for us to use a subclass so it shouldn't matter. I don't think this was a bad decision, just throwing it out there for the sake of completeness and conversation.

Copy link
Contributor Author

@JohnsonEricAtSalesforce JohnsonEricAtSalesforce Feb 6, 2026

Choose a reason for hiding this comment

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

I went ahead and made it public again as I'm getting ready to mark this ready for review soon ✅

Comment on lines 50 to 54
internal class ScreenLockViewModel(
build: Int = SDK_INT,
// TODO: Test coverage needed. ECJ20260205
val appName: String = getInstance().appName ?: "App",
) : ViewModel() {
Copy link
Contributor

Choose a reason for hiding this comment

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

A ViewModel seems like overkill IMO. Is there a reason it is needed?

Throwing that out for consideration before you spend a ton of time writing tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was wondering as well since at first the view model was relatively light and much of the logic related to screen lock is at the activity/view level. That said, there are some observables and they will benefit from the life cycle management the view model offers. It will also be ready should this grow in complexity. So, I'm leaning towards keeping the view model unless we feel a compelling reason not to.

@JohnsonEricAtSalesforce JohnsonEricAtSalesforce force-pushed the feature/w-19368426_msdk-rewrite-android-screen-lock_a.k.a-passcode_for-rtl-ui branch 2 times, most recently from a69d97c to a29609b Compare February 5, 2026 22:24
@github-actions
Copy link

github-actions bot commented Feb 5, 2026

Job Summary for Gradle

Pull Request :: test-android
Gradle Root Project Requested Tasks Gradle Version Build Outcome Build Scan®
SalesforceMobileSDK-Android libs:SalesforceSDK:convertCodeCoverage 8.14.3 Build Scan not published
SalesforceMobileSDK-Android libs:SalesforceSDK:lint 8.14.3 Build Scan not published
SalesforceMobileSDK-Android libs:SalesforceSDK:assembleAndroidTest 8.14.3 Build Scan not published

@JohnsonEricAtSalesforce JohnsonEricAtSalesforce force-pushed the feature/w-19368426_msdk-rewrite-android-screen-lock_a.k.a-passcode_for-rtl-ui branch 15 times, most recently from 692a6f3 to 954c6b2 Compare February 6, 2026 21:07
@@ -1,3 +1,29 @@
/*
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I added the copyright header here since it was missing. We do want those everywhere, correct?

EdgeToEdge.enable(this);

// Protect against screenshots.
getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I carefully migrated all the logic from the previous activity line-by-line and method-by-method to the new activity in a best attempt to avoid missing anything.

@Override
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
create()
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I really wanted to be able to pull the data levers on the create logic for top-notch onCreate unit tests and coverage, but being a lifecycle method there's no opening to it. So, I moved all the logic to a private/VisibleForTest method with parameters. That really worked like a charm, I thought.

Copy link
Contributor

Choose a reason for hiding this comment

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

ActivityScenario is used in most of our other test to exercise onCreate.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

True, though all the tests I'd used on LoginActivity were able to manipulate intent extras or data to exercise logic in the activity instance. In this case, ScreenLockActivity doesn't have any external API to accomplish that.


/**
* Implements the creation of the activity.
* @param build The Android SDK build. This parameter is intended for
Copy link
Contributor Author

@JohnsonEricAtSalesforce JohnsonEricAtSalesforce Feb 7, 2026

Choose a reason for hiding this comment

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

The commentary is verbose, yes, but being professional open source I'm really hoping it helps others know the intent and not abuse the contract of the code. I have often felt it is difficult to interpret the idea behind much of the code in the library, so this could help.

@SuppressLint("NewApi")
@VisibleForTesting
internal fun create(
build: Int = SDK_INT,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This activity has a lot of SDK-dependent logic, so I added testable parameters where needed. The bad thing is that it also requires a "suppress". Used with discipline, it seems alright and gets that path automatically tested. I'd be open to hear other ideas on that, though.

internal fun create(
build: Int = SDK_INT,
packageManager: PackageManager = this.packageManager,
sdkManager: SalesforceSDKManager = getInstance(),
Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's too big a topic for a pull request thread, but I'll go on a limb and wonder if this level of testability might require a dependency injection tool like Hilt. I used it quite a bit and it was a love 'n hate experience. It automates this type of test set up a lot, though. It could a great retro topic after this pull request.

build: Int = SDK_INT,
) {
when (biometricManager.canAuthenticate(viewModel.biometricAuthenticators())) {
BIOMETRIC_ERROR_NO_HARDWARE, BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED, BIOMETRIC_ERROR_UNSUPPORTED, BIOMETRIC_STATUS_UNKNOWN -> {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

These codes are not a type safe enumeration. Should we just make this an else so it cannot fall through? @brandonpage, thoughts?

Copy link
Contributor

Choose a reason for hiding this comment

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

Looking at BiometricManger.java the return type has an @IntDef annotation:

Denotes that the annotated element of integer type, represents a logical type and that its value should be one of the explicitly named constants. If the IntDef#flag() attribute is set to true, multiple constants can be combined.

So if a new Android API level added a new value we would get an compile time error when we updated to target it. So what you have is fine as is.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Perfect-O. Thanks for looking at that.

/**
* An empty function.
*/
internal fun noOp() {}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Here's a dandy, code-covered no-op function (which Kotlin doesn't provide) so we can reduce JaCoCo noise. Perhaps this could live in the new UserInterfaceConstants.kt or elsewhere?

Copy link
Contributor

Choose a reason for hiding this comment

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

Having this in a centralized place sounds good to me.

* SalesforceSDKManager instance
* @return The displayed name of the app
*/
fun appName(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This became more testable as a function than a computed property.

* @param build The Android SDK build. This parameter is intended for
* testing purposes only. Defaults to the current Android SDK build
*/
fun biometricAuthenticators(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This also became more testable as a function than a computed property.

<uses-permission android:name="android.permission.USE_BIOMETRIC" />

<application>
<application android:supportsRtl="true">
Copy link
Contributor Author

@JohnsonEricAtSalesforce JohnsonEricAtSalesforce Feb 7, 2026

Choose a reason for hiding this comment

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

Wow, so after the Jetpack Compose migration this was actually the only task left. Note, without this the app gets into a strange state where it will use the RTL text but used the LTR layout. It looks really odd.

I reckon this will resource-merge through to the applications and in this case that means all application modules that depend on SalesforceSDK. Is that acceptable? Would we want to leave this off here and let the app modules take responsibility for adding it? Is there a case where an app module could be negatively affected? They could override as needed. I always consider that when updating a library module such as this.

api("androidx.browser:browser:1.8.0") // Update requires API 36 compileSdk
api("androidx.work:work-runtime-ktx:2.10.3")

implementation("com.google.accompanist:accompanist-drawablepainter:0.37.3")
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Here's some Google code that lets us "remember" the programmatically-derived Drawable for the app icon.

Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need a 3PP for this? If it is from Google maybe not?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We should check. Can you direct message any instructions you have on how I can review or request that?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That 3PP is approved ✅

assertTrue(sendAccessibilityCapturingSlot.captured.contains(activity.getString(sf__screen_lock_auth_failed)))
}

private fun Drawable.renderToBitmap(): Bitmap {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

For asserting the content of the app icon, here's a utility method that helps.

@JohnsonEricAtSalesforce JohnsonEricAtSalesforce force-pushed the feature/w-19368426_msdk-rewrite-android-screen-lock_a.k.a-passcode_for-rtl-ui branch from 70ae413 to 33fc0b1 Compare February 7, 2026 00:35
import com.salesforce.androidsdk.ui.components.ScreenLockView
import com.salesforce.androidsdk.util.test.ExcludeFromJacocoGeneratedReport

@ExcludeFromJacocoGeneratedReport
Copy link
Contributor

Choose a reason for hiding this comment

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

If the Previews aren't in the same file as the view code then why even have them? The whole point is that you can see the changes you are making live as you edit. You could have ScreenLockView and ScreenLockViewPreview open side by side but I don't understand the point.

appName: String,
innerPadding: PaddingValues,
logoutAction: () -> Unit,
viewModel: ScreenLockViewModel,
Copy link
Contributor

Choose a reason for hiding this comment

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

Passing ViewModels is not recommended. If it is necessary for testing we should have a viewModel(factory = ViewModelFactory) default value so it isn't passed in production.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We do already have lifecycle-viewmodel-compose-android as a dependency and screen lock only has a top-level composable. If this parameter defaulted to viewModel() from that dependency, it would seem to match Thinking in Compose better.

I'd interpreted the style guide to mean a "screen level" composable was allowed access to the view model while "component level" composables called from other composables were not in order to preserve the "skip as much as possible" guideline.

I'll push a quick commit so we can review what that looks like.

Text(
fontSize = 14.sp,
modifier = Modifier.align(CenterHorizontally),
text = viewModel.setupMessageText.value ?: stringResource(sf__screen_lock_setup_required, appName),
Copy link
Contributor

Choose a reason for hiding this comment

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

Huh? ScreenLockViewModel is internal and setupMessageText never set (outside of tests).

viewModel.setupButtonAction.value()
},
shape = RoundedCornerShape(CORNER_RADIUS.dp),
) { Text(color = colorScheme.onPrimary, fontSize = 14.sp, fontWeight = Normal, text = viewModel.setupButtonLabel.value ?: stringResource(sf__screen_lock_setup_button)) }
Copy link
Contributor

Choose a reason for hiding this comment

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

NIT: fontSize (3 times in this file) and icon size should probably reference a common const value.

@Override
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
create()
Copy link
Contributor

Choose a reason for hiding this comment

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

ActivityScenario is used in most of our other test to exercise onCreate.

enableEdgeToEdge()

// Protect against screenshots.
window.setFlags(FLAG_SECURE, FLAG_SECURE)
Copy link
Contributor

Choose a reason for hiding this comment

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

I would not mind this being in a if (!SalesforceSDKManager.getInstance().isDebugBuild). The OS prompts are blocked regardless so it might not be needed at all.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'd kept this exactly as it was. Should we keep the functionality the same for a point release such as 13.2?

build: Int = SDK_INT,
) {
when (biometricManager.canAuthenticate(viewModel.biometricAuthenticators())) {
BIOMETRIC_ERROR_NO_HARDWARE, BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED, BIOMETRIC_ERROR_UNSUPPORTED, BIOMETRIC_STATUS_UNKNOWN -> {
Copy link
Contributor

Choose a reason for hiding this comment

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

Looking at BiometricManger.java the return type has an @IntDef annotation:

Denotes that the annotated element of integer type, represents a logical type and that its value should be one of the explicitly named constants. If the IntDef#flag() attribute is set to true, multiple constants can be combined.

So if a new Android API level added a new value we would get an compile time error when we updated to target it. So what you have is fine as is.

/**
* An empty function.
*/
internal fun noOp() {}
Copy link
Contributor

Choose a reason for hiding this comment

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

Having this in a centralized place sounds good to me.

@VisibleForTesting
internal inner class BiometricAuthenticationCallback(
private val activity: ScreenLockActivity = this@ScreenLockActivity,
) : AuthenticationCallback() {
Copy link
Contributor

Choose a reason for hiding this comment

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

Could this just be an inline lambda now? If that makes testing a lot harder than nbd.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You're correct that it's an extracted class for testing ✅

api("androidx.browser:browser:1.8.0") // Update requires API 36 compileSdk
api("androidx.work:work-runtime-ktx:2.10.3")

implementation("com.google.accompanist:accompanist-drawablepainter:0.37.3")
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need a 3PP for this? If it is from Google maybe not?

// Disable back navigation.
if (build >= TIRAMISU) {
getOnBackInvokedDispatcher().registerOnBackInvokedCallback(
PRIORITY_DEFAULT, ::noOp
Copy link

@github-actions github-actions bot Feb 10, 2026

Choose a reason for hiding this comment

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

⚠️ Field requires API level 33 (current min is 28): android.window.OnBackInvokedDispatcher#PRIORITY_DEFAULT

// Prompts the user to setup the operating system screen lock and biometrics.
if (build >= R) { // TODO: Remove when min API > 29.
viewModel.setupButtonAction.value = {
biometricSetupActivityResultLauncher.launch(Intent(ACTION_BIOMETRIC_ENROLL).apply {
Copy link

@github-actions github-actions bot Feb 10, 2026

Choose a reason for hiding this comment

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

⚠️ Field requires API level 30 (current min is 28): android.provider.Settings#ACTION_BIOMETRIC_ENROLL

if (build >= R) { // TODO: Remove when min API > 29.
viewModel.setupButtonAction.value = {
biometricSetupActivityResultLauncher.launch(Intent(ACTION_BIOMETRIC_ENROLL).apply {
putExtra(EXTRA_BIOMETRIC_AUTHENTICATORS_ALLOWED, viewModel.biometricAuthenticators())
Copy link

@github-actions github-actions bot Feb 10, 2026

Choose a reason for hiding this comment

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

⚠️ Field requires API level 30 (current min is 28): android.provider.Settings#EXTRA_BIOMETRIC_AUTHENTICATORS_ALLOWED

packageManager: PackageManager = this.packageManager,
): PromptInfo {
val hasFaceUnlock = if (build >= Q) { // TODO: Remove when min API > 28.
packageManager.hasSystemFeature(FEATURE_FACE) || (packageManager.hasSystemFeature(FEATURE_IRIS))
Copy link

@github-actions github-actions bot Feb 10, 2026

Choose a reason for hiding this comment

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

⚠️ Field requires API level 29 (current min is 28): android.content.pm.PackageManager#FEATURE_FACE

packageManager: PackageManager = this.packageManager,
): PromptInfo {
val hasFaceUnlock = if (build >= Q) { // TODO: Remove when min API > 28.
packageManager.hasSystemFeature(FEATURE_FACE) || (packageManager.hasSystemFeature(FEATURE_IRIS))
Copy link

@github-actions github-actions bot Feb 10, 2026

Choose a reason for hiding this comment

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

⚠️ Field requires API level 29 (current min is 28): android.content.pm.PackageManager#FEATURE_IRIS

// TODO: Remove this when min API > 33
// Disable back navigation.
if (build >= TIRAMISU) {
getOnBackInvokedDispatcher().registerOnBackInvokedCallback(
Copy link

@github-actions github-actions bot Feb 10, 2026

Choose a reason for hiding this comment

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

🚫 Call requires API level 33 (current min is 28): android.app.Activity#getOnBackInvokedDispatcher

// TODO: Remove this when min API > 33
// Disable back navigation.
if (build >= TIRAMISU) {
getOnBackInvokedDispatcher().registerOnBackInvokedCallback(
Copy link

@github-actions github-actions bot Feb 10, 2026

Choose a reason for hiding this comment

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

🚫 Call requires API level 33 (current min is 28): android.window.OnBackInvokedDispatcher#registerOnBackInvokedCallback

if (accessibilityManager.isEnabled) {
accessibilityManager.sendAccessibilityEvent(
if (build >= R) {
AccessibilityEvent()
Copy link

@github-actions github-actions bot Feb 10, 2026

Choose a reason for hiding this comment

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

🚫 Call requires API level 30 (current min is 28): android.view.accessibility.AccessibilityEvent()

}.apply {
setEventType(TYPE_WINDOW_STATE_CHANGED)
setClassName(this@ScreenLockActivity.javaClass.getName())
setPackageName(this@ScreenLockActivity::javaClass.get().packageName)
Copy link

@github-actions github-actions bot Feb 10, 2026

Choose a reason for hiding this comment

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

🚫 Call requires API level 31 (current min is 28): java.lang.Class#getPackageName

@JohnsonEricAtSalesforce JohnsonEricAtSalesforce force-pushed the feature/w-19368426_msdk-rewrite-android-screen-lock_a.k.a-passcode_for-rtl-ui branch from f9deadb to b8c78ad Compare February 11, 2026 20:54
@github-actions
Copy link

Job Summary for Gradle

Pull Request :: test-android
Gradle Root Project Requested Tasks Gradle Version Build Outcome Build Scan®
SalesforceMobileSDK-Android libs:SalesforceSDK:convertCodeCoverage 8.14.3 Build Scan not published
SalesforceMobileSDK-Android libs:SalesforceSDK:lint 8.14.3 Build Scan not published
SalesforceMobileSDK-Android libs:SalesforceSDK:assembleAndroidTest 8.14.3 Build Scan not published

@JohnsonEricAtSalesforce JohnsonEricAtSalesforce force-pushed the feature/w-19368426_msdk-rewrite-android-screen-lock_a.k.a-passcode_for-rtl-ui branch from b8c78ad to bfefa75 Compare February 11, 2026 21:17
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