From 779e28e217a30daefa2686a52a3cdf9ce9507e1d Mon Sep 17 00:00:00 2001 From: MM20 <15646950+MM2-0@users.noreply.github.com> Date: Sat, 15 Jan 2022 20:17:18 +0100 Subject: [PATCH] Add build info screen --- i18n/src/main/res/values-de/strings.xml | 2 + i18n/src/main/res/values/strings.xml | 3 + .../launcher2/ui/settings/SettingsActivity.kt | 4 ++ .../ui/settings/about/AboutSettingsScreen.kt | 7 +++ .../buildinfo/BuildInfoSettingsScreen.kt | 59 +++++++++++++++++++ .../buildinfo/BuildInfoSettingsScreenVM.kt | 30 ++++++++++ .../launcher2/weather/WeatherRepository.kt | 28 ++++++++- 7 files changed, 130 insertions(+), 3 deletions(-) create mode 100644 ui/src/main/java/de/mm20/launcher2/ui/settings/buildinfo/BuildInfoSettingsScreen.kt create mode 100644 ui/src/main/java/de/mm20/launcher2/ui/settings/buildinfo/BuildInfoSettingsScreenVM.kt diff --git a/i18n/src/main/res/values-de/strings.xml b/i18n/src/main/res/values-de/strings.xml index 5e359cbb..5b097d03 100644 --- a/i18n/src/main/res/values-de/strings.xml +++ b/i18n/src/main/res/values-de/strings.xml @@ -453,6 +453,8 @@ Vorschau einer Webseite anzeigen wenn die Suchanfrage eine URL ist Websuchen Shortcuts zu verschiedenen Websuch-Engines anzeigen + Build-Information + Weitere Informationen über diesen Build dieser App Wikipedia-URL diff --git a/i18n/src/main/res/values/strings.xml b/i18n/src/main/res/values/strings.xml index 7e3f4c6b..8219b674 100644 --- a/i18n/src/main/res/values/strings.xml +++ b/i18n/src/main/res/values/strings.xml @@ -489,6 +489,9 @@ %1$d calendars selected + Build information + More information about this build of this app + Restrict to music apps Ignore media sessions of apps that are not music apps diff --git a/ui/src/main/java/de/mm20/launcher2/ui/settings/SettingsActivity.kt b/ui/src/main/java/de/mm20/launcher2/ui/settings/SettingsActivity.kt index 58899df8..ce0ddc0c 100644 --- a/ui/src/main/java/de/mm20/launcher2/ui/settings/SettingsActivity.kt +++ b/ui/src/main/java/de/mm20/launcher2/ui/settings/SettingsActivity.kt @@ -32,6 +32,7 @@ import de.mm20.launcher2.ui.settings.main.MainSettingsScreen import de.mm20.launcher2.ui.settings.musicwidget.MusicWidgetSettingsScreen import de.mm20.launcher2.ui.settings.search.SearchSettingsScreen import de.mm20.launcher2.ui.settings.accounts.AccountsSettingsScreen +import de.mm20.launcher2.ui.settings.buildinfo.BuildInfoSettingsScreen import de.mm20.launcher2.ui.settings.weatherwidget.WeatherWidgetSettingsScreen import de.mm20.launcher2.ui.settings.widgets.WidgetsSettingsScreen import de.mm20.launcher2.ui.settings.wikipedia.WikipediaSettingsScreen @@ -120,6 +121,9 @@ class SettingsActivity : BaseActivity() { composable("settings/about") { AboutSettingsScreen() } + composable("settings/about/buildinfo") { + BuildInfoSettingsScreen() + } composable("settings/debug") { DebugSettingsScreen() } diff --git a/ui/src/main/java/de/mm20/launcher2/ui/settings/about/AboutSettingsScreen.kt b/ui/src/main/java/de/mm20/launcher2/ui/settings/about/AboutSettingsScreen.kt index c83cd253..252e4eee 100644 --- a/ui/src/main/java/de/mm20/launcher2/ui/settings/about/AboutSettingsScreen.kt +++ b/ui/src/main/java/de/mm20/launcher2/ui/settings/about/AboutSettingsScreen.kt @@ -41,6 +41,13 @@ fun AboutSettingsScreen() { title = stringResource(R.string.preference_version), summary = appVersion ) + Preference( + title = stringResource(R.string.preference_screen_buildinfo), + summary = stringResource(R.string.preference_screen_buildinfo_summary), + onClick = { + navController?.navigate("settings/about/buildinfo") + } + ) } } item { diff --git a/ui/src/main/java/de/mm20/launcher2/ui/settings/buildinfo/BuildInfoSettingsScreen.kt b/ui/src/main/java/de/mm20/launcher2/ui/settings/buildinfo/BuildInfoSettingsScreen.kt new file mode 100644 index 00000000..d35d1b2c --- /dev/null +++ b/ui/src/main/java/de/mm20/launcher2/ui/settings/buildinfo/BuildInfoSettingsScreen.kt @@ -0,0 +1,59 @@ +package de.mm20.launcher2.ui.settings.buildinfo + +import android.content.pm.PackageManager +import android.os.Build +import android.util.Base64 +import androidx.compose.runtime.* +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource +import androidx.lifecycle.viewmodel.compose.viewModel +import de.mm20.launcher2.ui.BuildConfig +import de.mm20.launcher2.ui.R +import de.mm20.launcher2.ui.component.preferences.Preference +import de.mm20.launcher2.ui.component.preferences.PreferenceCategory +import de.mm20.launcher2.ui.component.preferences.PreferenceScreen +import java.security.MessageDigest + +@Composable +fun BuildInfoSettingsScreen() { + val viewModel: BuildInfoSettingsScreenVM = viewModel() + val context = LocalContext.current + PreferenceScreen(title = stringResource(R.string.preference_screen_buildinfo)) { + item { + Preference(title = "Build type", summary = BuildConfig.BUILD_TYPE) + var buildSignature by remember { mutableStateOf(null) } + LaunchedEffect(null) { + val signature = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + val pi = context.packageManager.getPackageInfo( + context.packageName, + PackageManager.GET_SIGNING_CERTIFICATES + ) + pi.signingInfo.apkContentsSigners.firstOrNull() + } else { + val pi = context.packageManager.getPackageInfo( + context.packageName, + PackageManager.GET_SIGNATURES + ) + pi.signatures.firstOrNull() + } + val signatureHash = if (signature != null) { + val digest = MessageDigest.getInstance("SHA") + digest.update(signature.toByteArray()) + Base64.encodeToString(digest.digest(), Base64.NO_WRAP) + } else "null" + buildSignature = signatureHash + } + Preference(title = "Signature hash", summary = buildSignature) + } + item { + PreferenceCategory(title = "Features") { + for (feature in viewModel.buildFeatures) { + Preference( + title = feature.key, + summary = if (feature.value) "YES" else "NO" + ) + } + } + } + } +} \ No newline at end of file diff --git a/ui/src/main/java/de/mm20/launcher2/ui/settings/buildinfo/BuildInfoSettingsScreenVM.kt b/ui/src/main/java/de/mm20/launcher2/ui/settings/buildinfo/BuildInfoSettingsScreenVM.kt new file mode 100644 index 00000000..587c9d8d --- /dev/null +++ b/ui/src/main/java/de/mm20/launcher2/ui/settings/buildinfo/BuildInfoSettingsScreenVM.kt @@ -0,0 +1,30 @@ +package de.mm20.launcher2.ui.settings.buildinfo + +import android.content.pm.PackageManager +import android.os.Build +import android.util.Base64 +import androidx.lifecycle.ViewModel +import androidx.lifecycle.liveData +import de.mm20.launcher2.accounts.AccountType +import de.mm20.launcher2.accounts.AccountsRepository +import de.mm20.launcher2.preferences.Settings.WeatherSettings.WeatherProvider +import de.mm20.launcher2.weather.WeatherRepository +import org.koin.core.component.KoinComponent +import org.koin.core.component.inject +import java.security.MessageDigest + +class BuildInfoSettingsScreenVM : ViewModel(), KoinComponent { + private val accountsRepository: AccountsRepository by inject() + private val weatherRepository: WeatherRepository by inject() + + private val availableWeatherProviders = weatherRepository.getAvailableProviders() + + val buildFeatures = mapOf( + "Accounts: Google" to accountsRepository.isSupported(AccountType.Google), + "Accounts: Microsoft" to accountsRepository.isSupported(AccountType.Microsoft), + "Weather providers: HERE" to availableWeatherProviders.contains(WeatherProvider.Here), + "Weather providers: Met No" to availableWeatherProviders.contains(WeatherProvider.MetNo), + "Weather providers: OpenWeatherMap" to availableWeatherProviders.contains(WeatherProvider.OpenWeatherMap), + "Weather providers: BrightSky" to availableWeatherProviders.contains(WeatherProvider.BrightSky), + ) +} \ No newline at end of file diff --git a/weather/src/main/java/de/mm20/launcher2/weather/WeatherRepository.kt b/weather/src/main/java/de/mm20/launcher2/weather/WeatherRepository.kt index 0bd8eecc..227b7323 100644 --- a/weather/src/main/java/de/mm20/launcher2/weather/WeatherRepository.kt +++ b/weather/src/main/java/de/mm20/launcher2/weather/WeatherRepository.kt @@ -2,13 +2,16 @@ package de.mm20.launcher2.weather import android.content.Context import android.util.Log -import androidx.datastore.dataStore import androidx.work.* import de.mm20.launcher2.database.AppDatabase import de.mm20.launcher2.permissions.PermissionGroup import de.mm20.launcher2.permissions.PermissionsManager import de.mm20.launcher2.preferences.LauncherDataStore import de.mm20.launcher2.preferences.Settings.WeatherSettings +import de.mm20.launcher2.weather.brightsky.BrightskyProvider +import de.mm20.launcher2.weather.here.HereProvider +import de.mm20.launcher2.weather.metno.MetNoProvider +import de.mm20.launcher2.weather.openweathermap.OpenWeatherMapProvider import kotlinx.coroutines.* import kotlinx.coroutines.flow.* import org.koin.core.component.KoinComponent @@ -31,6 +34,8 @@ interface WeatherRepository { fun setAutoLocation(autoLocation: Boolean) fun setLastLocation(lastLocation: WeatherLocation?) + fun getAvailableProviders(): List + fun selectProvider(provider: WeatherSettings.WeatherProvider) val selectedProvider: Flow @@ -133,7 +138,7 @@ class WeatherRepositoryImpl( } } hasLocationPermission.collectLatest { - if(it) requestUpdate() + if (it) requestUpdate() } } } @@ -194,11 +199,28 @@ class WeatherRepositoryImpl( } } } + + override fun getAvailableProviders(): List { + val providers = mutableListOf() + if (BrightskyProvider(context).isAvailable()) { + providers.add(WeatherSettings.WeatherProvider.BrightSky) + } + if (OpenWeatherMapProvider(context).isAvailable()) { + providers.add(WeatherSettings.WeatherProvider.OpenWeatherMap) + } + if (MetNoProvider(context).isAvailable()) { + providers.add(WeatherSettings.WeatherProvider.MetNo) + } + if (HereProvider(context).isAvailable()) { + providers.add(WeatherSettings.WeatherProvider.Here) + } + return providers + } } class WeatherUpdateWorker(val context: Context, params: WorkerParameters) : CoroutineWorker(context, params), KoinComponent { - val repository: WeatherRepository by inject() + val repository: WeatherRepository by inject() override suspend fun doWork(): Result { Log.d("MM20", "Requesting weather data")