From 33393dcc089d00b57848bff4b958e4d8a172b6f9 Mon Sep 17 00:00:00 2001 From: Nikita Evdokimov Date: Wed, 15 May 2024 14:18:14 +0300 Subject: [PATCH 1/2] TECH: pass SystemLanguage instance through Device class --- .../kaspersky/kaspresso/device/languages/Language.kt | 10 ++++++++++ .../kaspresso/device/languages/LanguageImpl.kt | 4 ++++ .../com/kaspersky/kaspresso/kaspresso/Kaspresso.kt | 6 +++++- .../systemlanguage/ChangeSystemLanguageMidTestCase.kt | 6 ++---- 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/device/languages/Language.kt b/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/device/languages/Language.kt index 666faf2a3..be010701d 100644 --- a/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/device/languages/Language.kt +++ b/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/device/languages/Language.kt @@ -18,4 +18,14 @@ interface Language { */ @MainThread fun switchInApp(locale: Locale) + + /** + * Changes locale for Android OS Settings. + * Under the hood grants CHANGE_CONFIGURATION permission + * (without this permission, it's impossible to change system language) + * + * @throws Throwable if something went wrong + */ + @MainThread + fun switchInSystem(locale: Locale) } diff --git a/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/device/languages/LanguageImpl.kt b/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/device/languages/LanguageImpl.kt index 7260644c0..d4f6d1416 100644 --- a/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/device/languages/LanguageImpl.kt +++ b/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/device/languages/LanguageImpl.kt @@ -9,6 +9,7 @@ import android.os.LocaleList import androidx.appcompat.app.AppCompatDelegate import androidx.core.os.ConfigurationCompat import androidx.core.os.LocaleListCompat +import com.kaspersky.kaspresso.docloc.SystemLanguage import com.kaspersky.kaspresso.logger.UiTestLogger import java.util.Locale @@ -18,6 +19,7 @@ import java.util.Locale class LanguageImpl( private val logger: UiTestLogger, private val instrumentation: Instrumentation, + private val systemLanguage: SystemLanguage, ) : Language { override fun switchInApp(locale: Locale) { @@ -45,6 +47,8 @@ class LanguageImpl( } } + override fun switchInSystem(locale: Locale) = systemLanguage.switch(locale) + private fun getCurrentLocale(): Locale? = ConfigurationCompat.getLocales(instrumentation.targetContext.resources.configuration).get(0) diff --git a/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/kaspresso/Kaspresso.kt b/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/kaspresso/Kaspresso.kt index 710422f92..9a17041db 100644 --- a/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/kaspresso/Kaspresso.kt +++ b/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/kaspresso/Kaspresso.kt @@ -50,6 +50,7 @@ import com.kaspersky.kaspresso.device.video.VideosImpl import com.kaspersky.kaspresso.device.video.recorder.VideoRecorderImpl import com.kaspersky.kaspresso.device.viewhierarchy.ViewHierarchyDumper import com.kaspersky.kaspresso.device.viewhierarchy.ViewHierarchyDumperImpl +import com.kaspersky.kaspresso.docloc.SystemLanguage import com.kaspersky.kaspresso.failure.LoggingFailureHandler import com.kaspersky.kaspresso.files.dirs.DefaultDirsProvider import com.kaspersky.kaspresso.files.dirs.DirsProvider @@ -742,7 +743,10 @@ data class Kaspresso( instrumentalDependencyProviderFactory.getComponentProvider(instrumentation), adbServer ) - if (!::language.isInitialized) language = LanguageImpl(libLogger, instrumentation) + if (!::language.isInitialized) { + val systemLanguage = SystemLanguage(instrumentation.targetContext, testLogger, hackPermissions) + language = LanguageImpl(libLogger, instrumentation, systemLanguage) + } if (!::logcat.isInitialized) logcat = LogcatImpl(libLogger, adbServer) if (!::flakySafetyParams.isInitialized) flakySafetyParams = FlakySafetyParams.default() diff --git a/samples/kaspresso-sample/src/androidTest/kotlin/com/kaspersky/kaspressample/systemlanguage/ChangeSystemLanguageMidTestCase.kt b/samples/kaspresso-sample/src/androidTest/kotlin/com/kaspersky/kaspressample/systemlanguage/ChangeSystemLanguageMidTestCase.kt index 9b03d1c46..79e016009 100644 --- a/samples/kaspresso-sample/src/androidTest/kotlin/com/kaspersky/kaspressample/systemlanguage/ChangeSystemLanguageMidTestCase.kt +++ b/samples/kaspresso-sample/src/androidTest/kotlin/com/kaspersky/kaspressample/systemlanguage/ChangeSystemLanguageMidTestCase.kt @@ -6,7 +6,6 @@ import androidx.test.rule.GrantPermissionRule import com.kaspersky.kaspressample.MainActivity import com.kaspersky.kaspressample.screen.ChangeLocaleScreen import com.kaspersky.kaspressample.screen.MainScreen -import com.kaspersky.kaspresso.docloc.SystemLanguage import com.kaspersky.kaspresso.testcases.api.testcase.TestCase import org.junit.Rule import org.junit.Test @@ -24,20 +23,19 @@ class ChangeSystemLanguageMidTestCase : TestCase() { @Test fun checkLocaleChangeMidTest() = run { - val systemLanguage = SystemLanguage(device.targetContext, testLogger, device.hackPermissions) step("Open change locale screen") { MainScreen { changeLocaleButton { click() } } } step("Check EN locale text") { - systemLanguage.switch(Locale.ENGLISH) + device.language.switchInSystem(Locale.ENGLISH) ChangeLocaleScreen { text { containsText("123") } } } step("Check RU locale text") { - systemLanguage.switch(Locale.forLanguageTag("RU")) + device.language.switchInSystem(Locale.forLanguageTag("RU")) ChangeLocaleScreen { text { containsText("321") } } From 8db30c5d3b779e3c6677856af2e62d1642f5ccc7 Mon Sep 17 00:00:00 2001 From: Nikita Evdokimov Date: Thu, 16 May 2024 13:34:09 +0300 Subject: [PATCH 2/2] TECH: make SystemLanguage internal --- .../com/kaspersky/kaspresso/device/languages/LanguageImpl.kt | 2 +- .../kotlin/com/kaspersky/kaspresso/docloc/SystemLanguage.kt | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/device/languages/LanguageImpl.kt b/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/device/languages/LanguageImpl.kt index d4f6d1416..557961ade 100644 --- a/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/device/languages/LanguageImpl.kt +++ b/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/device/languages/LanguageImpl.kt @@ -16,7 +16,7 @@ import java.util.Locale /** * The implementation of [Language] */ -class LanguageImpl( +internal class LanguageImpl( private val logger: UiTestLogger, private val instrumentation: Instrumentation, private val systemLanguage: SystemLanguage, diff --git a/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/docloc/SystemLanguage.kt b/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/docloc/SystemLanguage.kt index 5253e70af..8eb4aaff9 100644 --- a/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/docloc/SystemLanguage.kt +++ b/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/docloc/SystemLanguage.kt @@ -10,7 +10,7 @@ import com.kaspersky.kaspresso.device.permissions.HackPermissions import com.kaspersky.kaspresso.logger.UiTestLogger import java.util.Locale -class SystemLanguage( +internal class SystemLanguage( private val context: Context, private val logger: UiTestLogger, private val hackPermissions: HackPermissions @@ -40,7 +40,7 @@ class SystemLanguage( Failed to change system locale due to API restrictions. To fix this execute one of the following commands. For Android 10 (API level 29) or higher: "adb shell settings put global hidden_api_policy 1" - For Android 9 (API level 28): + For Android 9 (API level 28): "adb shell settings put global hidden_api_policy_pre_p_apps 1" "adb shell settings put global hidden_api_policy_p_apps 1" To rollback these settings execute @@ -62,6 +62,7 @@ class SystemLanguage( * Try to grant permission CHANGE_CONFIGURATION if the permission was not granted * @throws DocLocException In case of a failure to grant one */ + @Suppress("DEPRECATION") private fun grantPermissionsIfNeed() { val permissionStateAtTheBeginning = context.checkPermission(Manifest.permission.CHANGE_CONFIGURATION, Process.myPid(), Process.myUid()) if (permissionStateAtTheBeginning == PackageManager.PERMISSION_GRANTED) {