EN: Display warnings in settings when not operating correctly

This commit is contained in:
Marvin W 2020-12-06 11:00:09 +01:00
parent ce43256812
commit 0c321fd1eb
No known key found for this signature in database
GPG Key ID: 072E9235DB996F2A
9 changed files with 151 additions and 43 deletions

View File

@ -5,24 +5,34 @@
package org.microg.gms.nearby.core.ui package org.microg.gms.nearby.core.ui
import android.bluetooth.BluetoothAdapter
import android.content.Context.LOCATION_SERVICE
import android.content.Intent
import android.location.LocationManager
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
import android.provider.Settings
import androidx.core.os.bundleOf import androidx.core.os.bundleOf
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.findNavController
import androidx.preference.Preference import androidx.preference.Preference
import androidx.preference.PreferenceCategory import androidx.preference.PreferenceCategory
import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceFragmentCompat
import kotlinx.coroutines.Dispatchers import org.microg.gms.nearby.exposurenotification.AdvertiserService
import kotlinx.coroutines.withContext
import org.microg.gms.nearby.exposurenotification.ExposureDatabase import org.microg.gms.nearby.exposurenotification.ExposureDatabase
import org.microg.gms.nearby.exposurenotification.ScannerService
import org.microg.gms.nearby.exposurenotification.getExposureNotificationsServiceInfo import org.microg.gms.nearby.exposurenotification.getExposureNotificationsServiceInfo
import org.microg.gms.ui.AppIconPreference import org.microg.gms.ui.AppIconPreference
import org.microg.gms.ui.getApplicationInfoIfExists import org.microg.gms.ui.getApplicationInfoIfExists
import org.microg.gms.ui.navigate import org.microg.gms.ui.navigate
class ExposureNotificationsPreferencesFragment : PreferenceFragmentCompat() { class ExposureNotificationsPreferencesFragment : PreferenceFragmentCompat() {
private lateinit var exposureEnableInfo: Preference private lateinit var exposureEnableInfo: Preference
private lateinit var exposureBluetoothOff: Preference
private lateinit var exposureLocationOff: Preference
private lateinit var exposureBluetoothUnsupported: Preference
private lateinit var exposureBluetoothNoAdvertisement: Preference
private lateinit var exposureApps: PreferenceCategory private lateinit var exposureApps: PreferenceCategory
private lateinit var exposureAppsNone: Preference private lateinit var exposureAppsNone: Preference
private lateinit var collectedRpis: Preference private lateinit var collectedRpis: Preference
@ -37,10 +47,27 @@ class ExposureNotificationsPreferencesFragment : PreferenceFragmentCompat() {
override fun onBindPreferences() { override fun onBindPreferences() {
exposureEnableInfo = preferenceScreen.findPreference("pref_exposure_enable_info") ?: exposureEnableInfo exposureEnableInfo = preferenceScreen.findPreference("pref_exposure_enable_info") ?: exposureEnableInfo
exposureBluetoothOff = preferenceScreen.findPreference("pref_exposure_error_bluetooth_off") ?: exposureBluetoothOff
exposureLocationOff = preferenceScreen.findPreference("pref_exposure_error_location_off") ?: exposureLocationOff
exposureBluetoothUnsupported = preferenceScreen.findPreference("pref_exposure_error_bluetooth_unsupported") ?: exposureBluetoothUnsupported
exposureBluetoothNoAdvertisement = preferenceScreen.findPreference("pref_exposure_error_bluetooth_no_advertise") ?: exposureBluetoothNoAdvertisement
exposureApps = preferenceScreen.findPreference("prefcat_exposure_apps") ?: exposureApps exposureApps = preferenceScreen.findPreference("prefcat_exposure_apps") ?: exposureApps
exposureAppsNone = preferenceScreen.findPreference("pref_exposure_apps_none") ?: exposureAppsNone exposureAppsNone = preferenceScreen.findPreference("pref_exposure_apps_none") ?: exposureAppsNone
collectedRpis = preferenceScreen.findPreference("pref_exposure_collected_rpis") ?: collectedRpis collectedRpis = preferenceScreen.findPreference("pref_exposure_collected_rpis") ?: collectedRpis
advertisingId = preferenceScreen.findPreference("pref_exposure_advertising_id") ?: advertisingId advertisingId = preferenceScreen.findPreference("pref_exposure_advertising_id") ?: advertisingId
exposureLocationOff.onPreferenceClickListener = Preference.OnPreferenceClickListener {
val intent = Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)
startActivity(intent)
true
}
exposureBluetoothOff.onPreferenceClickListener = Preference.OnPreferenceClickListener {
val intent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
startActivity(intent)
true
}
collectedRpis.onPreferenceClickListener = Preference.OnPreferenceClickListener { collectedRpis.onPreferenceClickListener = Preference.OnPreferenceClickListener {
findNavController().navigate(requireContext(), R.id.openExposureRpis) findNavController().navigate(requireContext(), R.id.openExposureRpis)
true true
@ -61,12 +88,38 @@ class ExposureNotificationsPreferencesFragment : PreferenceFragmentCompat() {
handler.removeCallbacks(updateContentRunnable) handler.removeCallbacks(updateContentRunnable)
} }
private fun isLocationEnabled(): Boolean {
val lm = requireContext().getSystemService(LOCATION_SERVICE) as LocationManager
var gpsEnabled = false
var networkEnabled = false
try {
gpsEnabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER)
} catch (ex: Exception) {
}
try {
networkEnabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER)
} catch (ex: Exception) {
}
return gpsEnabled || networkEnabled
}
private fun updateStatus() { private fun updateStatus() {
lifecycleScope.launchWhenResumed { lifecycleScope.launchWhenResumed {
handler.postDelayed(updateStatusRunnable, UPDATE_STATUS_INTERVAL) handler.postDelayed(updateStatusRunnable, UPDATE_STATUS_INTERVAL)
val enabled = getExposureNotificationsServiceInfo(requireContext()).configuration.enabled val enabled = getExposureNotificationsServiceInfo(requireContext()).configuration.enabled
exposureEnableInfo.isVisible = !enabled exposureEnableInfo.isVisible = !enabled
advertisingId.isVisible = enabled
val bluetoothSupported = ScannerService.isSupported(requireContext())
val advertisingSupported = if (bluetoothSupported == true) AdvertiserService.isSupported(requireContext()) else bluetoothSupported
exposureLocationOff.isVisible = enabled && bluetoothSupported != false && !isLocationEnabled()
exposureBluetoothOff.isVisible = enabled && bluetoothSupported == null
exposureBluetoothUnsupported.isVisible = enabled && bluetoothSupported == false
exposureBluetoothNoAdvertisement.isVisible = enabled && bluetoothSupported == true && advertisingSupported != true
advertisingId.isVisible = enabled && advertisingSupported == true
} }
} }

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ SPDX-FileCopyrightText: 2019, The Android Open Source Project
~ SPDX-FileCopyrightText: 2020, microG Project Team
~ SPDX-License-Identifier: Apache-2.0
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorAccent"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#000"
android:pathData="M13 14H11V9H13M13 18H11V16H13M1 21H23L12 2L1 21Z" />
</vector>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ SPDX-FileCopyrightText: 2019, The Android Open Source Project
~ SPDX-FileCopyrightText: 2020, microG Project Team
~ SPDX-License-Identifier: Apache-2.0
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorAccent"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#000"
android:pathData="M13,5.83L14.88,7.71L13.28,9.31L14.69,10.72L17.71,7.7L12,2H11V7.03L13,9.03M5.41,4L4,5.41L10.59,12L5,17.59L6.41,19L11,14.41V22H12L16.29,17.71L18.59,20L20,18.59M13,18.17V14.41L14.88,16.29" />
</vector>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ SPDX-FileCopyrightText: 2019, Austin Andrews
~ SPDX-FileCopyrightText: 2020, microG Project Team
~ SPDX-License-Identifier: Apache-2.0
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorAccent"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#000"
android:pathData="M16.37,16.1L11.75,11.47L11.64,11.36L3.27,3L2,4.27L5.18,7.45C5.06,7.95 5,8.46 5,9C5,14.25 12,22 12,22C12,22 13.67,20.15 15.37,17.65L18.73,21L20,19.72M12,6.5A2.5,2.5 0 0,1 14.5,9C14.5,9.73 14.17,10.39 13.67,10.85L17.3,14.5C18.28,12.62 19,10.68 19,9A7,7 0 0,0 12,2C10,2 8.24,2.82 6.96,4.14L10.15,7.33C10.61,6.82 11.26,6.5 12,6.5Z" />
</vector>

View File

@ -7,6 +7,10 @@
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="service_name_exposure">Exposure Notifications</string> <string name="service_name_exposure">Exposure Notifications</string>
<string name="pref_exposure_enable_info_summary">Öffne eine App, die Exposure Notifications unterstützt, um diese zu aktivieren.</string> <string name="pref_exposure_enable_info_summary">Öffne eine App, die Exposure Notifications unterstützt, um diese zu aktivieren.</string>
<string name="pref_exposure_error_bluetooth_off_summary">Aktiviere Bluetooth, um Exposure Notifications zu nutzen.</string>
<string name="pref_exposure_error_location_off_summary">Aktiviere Ortungsdienste, um Exposure Notifications zu nutzen.</string>
<string name="pref_exposure_error_bluetooth_unsupported_summary">Leider ist dein Gerät nicht mit Exposure Notifications kompatibel.</string>
<string name="pref_exposure_error_bluetooth_no_advertise_summary">Leider ist dein Gerät nicht vollständig mit Exposure Notifications kompatibel. Du wirst Warnungen über Risikokontakte erhalten, aber nicht andere Benachrichtigen können.</string>
<string name="prefcat_exposure_apps_title">Apps, die Exposure Notifications nutzen</string> <string name="prefcat_exposure_apps_title">Apps, die Exposure Notifications nutzen</string>
<string name="pref_exposure_collected_rpis_title">Gesammelte IDs</string> <string name="pref_exposure_collected_rpis_title">Gesammelte IDs</string>
<string name="pref_exposure_collected_rpis_summary"><xliff:g example="63">%1$d</xliff:g> IDs in den letzten 60 Minuten</string> <string name="pref_exposure_collected_rpis_summary"><xliff:g example="63">%1$d</xliff:g> IDs in den letzten 60 Minuten</string>

View File

@ -17,6 +17,10 @@
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="service_name_exposure">Exposure Notifications</string> <string name="service_name_exposure">Exposure Notifications</string>
<string name="pref_exposure_enable_info_summary">To enable Exposure Notifications, open any app supporting it.</string> <string name="pref_exposure_enable_info_summary">To enable Exposure Notifications, open any app supporting it.</string>
<string name="pref_exposure_error_bluetooth_off_summary">To use Exposure Notifications, enable Bluetooth in system settings.</string>
<string name="pref_exposure_error_location_off_summary">To use Exposure Notifications, enable Location access in system settings.</string>
<string name="pref_exposure_error_bluetooth_unsupported_summary">Unfortunately, your device is not compatible with Exposure Notifications.</string>
<string name="pref_exposure_error_bluetooth_no_advertise_summary">Unfortunately, your device is only partially compatible with Exposure Notifications. You can be notified for risk contacts but won\'t be able to notify others.</string>
<string name="prefcat_exposure_apps_title">Apps using Exposure Notifications</string> <string name="prefcat_exposure_apps_title">Apps using Exposure Notifications</string>
<string name="pref_exposure_collected_rpis_title">Collected IDs</string> <string name="pref_exposure_collected_rpis_title">Collected IDs</string>
<string name="pref_exposure_collected_rpis_summary"><xliff:g example="63">%1$d</xliff:g> IDs in last hour</string> <string name="pref_exposure_collected_rpis_summary"><xliff:g example="63">%1$d</xliff:g> IDs in last hour</string>

View File

@ -15,6 +15,36 @@
app:isPreferenceVisible="false" app:isPreferenceVisible="false"
tools:isPreferenceVisible="true" /> tools:isPreferenceVisible="true" />
<Preference
android:icon="@drawable/ic_bluetooth_off"
android:key="pref_exposure_error_bluetooth_off"
android:summary="@string/pref_exposure_error_bluetooth_off_summary"
app:isPreferenceVisible="false"
tools:isPreferenceVisible="true" />
<Preference
android:icon="@drawable/ic_location_off"
android:key="pref_exposure_error_location_off"
android:summary="@string/pref_exposure_error_location_off_summary"
app:isPreferenceVisible="false"
tools:isPreferenceVisible="true" />
<Preference
android:icon="@drawable/ic_alert"
android:key="pref_exposure_error_bluetooth_unsupported"
android:selectable="false"
android:summary="@string/pref_exposure_error_bluetooth_unsupported_summary"
app:isPreferenceVisible="false"
tools:isPreferenceVisible="true" />
<Preference
android:icon="@drawable/ic_alert"
android:key="pref_exposure_error_bluetooth_no_advertise"
android:selectable="false"
android:summary="@string/pref_exposure_error_bluetooth_no_advertise_summary"
app:isPreferenceVisible="false"
tools:isPreferenceVisible="true" />
<PreferenceCategory <PreferenceCategory
android:key="prefcat_exposure_apps" android:key="prefcat_exposure_apps"
android:title="@string/prefcat_exposure_apps_title"> android:title="@string/prefcat_exposure_apps_title">

View File

@ -236,26 +236,11 @@ class AdvertiserService : LifecycleService() {
fun isSupported(context: Context): Boolean? { fun isSupported(context: Context): Boolean? {
val adapter = BluetoothAdapter.getDefaultAdapter() val adapter = BluetoothAdapter.getDefaultAdapter()
return when { return when {
adapter == null -> { adapter == null -> false
Log.d(TAG, "LE advertising not supported via adapter") Build.VERSION.SDK_INT >= 26 && (adapter.isLeExtendedAdvertisingSupported || adapter.isLePeriodicAdvertisingSupported) -> true
false adapter.state != BluetoothAdapter.STATE_ON -> null
} adapter.bluetoothLeAdvertiser != null -> true
Build.VERSION.SDK_INT >= 26 && (adapter.isLeExtendedAdvertisingSupported || adapter.isLePeriodicAdvertisingSupported) -> { else -> false
Log.d(TAG, "LE advertising supported via feature")
true
}
adapter.state != BluetoothAdapter.STATE_ON -> {
Log.d(TAG, "LE advertising unknown via state")
null
}
adapter.bluetoothLeAdvertiser != null -> {
Log.d(TAG, "LE advertising supported via advertiser")
true
}
else -> {
Log.d(TAG, "LE advertising not supported via advertiser")
false
}
} }
} }
} }

View File

@ -174,28 +174,12 @@ class ScannerService : LifecycleService() {
} }
fun isSupported(context: Context): Boolean? { fun isSupported(context: Context): Boolean? {
if (AdvertiserService.isSupported(context) == true) {
Log.d(TAG, "LE scanning supported via advertiser")
return true
}
val adapter = BluetoothAdapter.getDefaultAdapter() val adapter = BluetoothAdapter.getDefaultAdapter()
return when { return when {
adapter == null -> { adapter == null -> false
Log.d(TAG, "LE scanning not supported via adapter") adapter.state != BluetoothAdapter.STATE_ON -> null
false adapter.bluetoothLeScanner != null -> true
} else -> false
adapter.state != BluetoothAdapter.STATE_ON -> {
Log.d(TAG, "LE scanning unknown via state")
null
}
adapter.bluetoothLeScanner != null -> {
Log.d(TAG, "LE scanning supported via scanner")
true
}
else -> {
Log.d(TAG, "LE scanning not supported via scanner")
false
}
} }
} }
} }