Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate SSID dialog to Compose, move + rename prioritize internal #2662

Merged
merged 2 commits into from
Jul 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ import io.homeassistant.companion.android.settings.qs.ManageTilesFragment
import io.homeassistant.companion.android.settings.sensor.SensorSettingsFragment
import io.homeassistant.companion.android.settings.sensor.SensorUpdateFrequencyFragment
import io.homeassistant.companion.android.settings.shortcuts.ManageShortcutsSettingsFragment
import io.homeassistant.companion.android.settings.ssid.SsidDialogFragment
import io.homeassistant.companion.android.settings.ssid.SsidPreference
import io.homeassistant.companion.android.settings.ssid.SsidFragment
import io.homeassistant.companion.android.settings.wear.SettingsWearActivity
import io.homeassistant.companion.android.settings.websocket.WebsocketSettingFragment
import io.homeassistant.companion.android.settings.widgets.ManageWidgetsSettingsFragment
Expand All @@ -62,7 +61,6 @@ class SettingsFragment constructor(

companion object {
private const val TAG = "SettingsFragment"
private const val SSID_DIALOG_TAG = "${BuildConfig.APPLICATION_ID}.SSID_DIALOG_TAG"
private const val LOCATION_REQUEST_CODE = 0
private const val BACKGROUND_LOCATION_REQUEST_CODE = 1
}
Expand Down Expand Up @@ -145,6 +143,13 @@ class SettingsFragment constructor(
findPreference<EditTextPreference>("connection_external")?.onPreferenceChangeListener =
onChangeUrlValidator

findPreference<Preference>("connection_internal_ssids")?.let {
it.setOnPreferenceClickListener {
onDisplaySsidScreen()
return@setOnPreferenceClickListener true
}
}

findPreference<Preference>("sensors")?.setOnPreferenceClickListener {
parentFragmentManager
.beginTransaction()
Expand Down Expand Up @@ -342,18 +347,6 @@ class SettingsFragment constructor(
Log.e(TAG, "Unable to set the icon tint", e)
}
}

findPreference<SwitchPreference>("prioritize_internal")?.let {
it.isEnabled = false
try {
val unwrappedDrawable =
AppCompatResources.getDrawable(requireContext(), commonR.drawable.ic_priority)
unwrappedDrawable?.setTint(Color.DKGRAY)
it.icon = unwrappedDrawable
} catch (e: Exception) {
Log.e(TAG, "Unable to set the icon tint", e)
}
}
}

override fun enableInternalConnection() {
Expand All @@ -368,66 +361,66 @@ class SettingsFragment constructor(
Log.e(TAG, "Unable to set the icon tint", e)
}
}
}

findPreference<SwitchPreference>("prioritize_internal")?.let {
it.isEnabled = true
try {
val unwrappedDrawable =
AppCompatResources.getDrawable(requireContext(), commonR.drawable.ic_priority)
unwrappedDrawable?.setTint(resources.getColor(commonR.color.colorAccent))
it.icon = unwrappedDrawable
} catch (e: Exception) {
Log.e(TAG, "Unable to set the icon tint", e)
}
override fun updateSsids(ssids: Set<String>) {
findPreference<Preference>("connection_internal_ssids")?.let {
it.summary =
if (ssids.isEmpty()) getString(commonR.string.pref_connection_ssids_empty)
else ssids.joinToString()
}
}

override fun onLangSettingsChanged() {
requireActivity().recreate()
}

override fun onDisplayPreferenceDialog(preference: Preference) {
if (preference is SsidPreference) {
val permissionsToCheck: Array<String> = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_BACKGROUND_LOCATION)
} else {
arrayOf(Manifest.permission.ACCESS_COARSE_LOCATION)
}
private fun onDisplaySsidScreen() {
val permissionsToCheck: Array<String> = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_BACKGROUND_LOCATION)
} else {
arrayOf(Manifest.permission.ACCESS_COARSE_LOCATION)
}

if (DisabledLocationHandler.isLocationEnabled(requireContext())) {
var permissionsToRequest: Array<String>? = null
if (!permissionsToCheck.isNullOrEmpty() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
// For Android 11 we MUST NOT request Background Location permission with fine or coarse permissions
// as for Android 11 the background location request needs to be done separately
// See here: https://developer.android.com/about/versions/11/privacy/location#request-background-location-separately
permissionsToRequest = permissionsToCheck.toList().minus(Manifest.permission.ACCESS_BACKGROUND_LOCATION).toTypedArray()
}
if (DisabledLocationHandler.isLocationEnabled(requireContext())) {
var permissionsToRequest: Array<String>? = null
if (permissionsToCheck.isNotEmpty() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
// For Android 11 we MUST NOT request Background Location permission with fine or coarse permissions
// as for Android 11 the background location request needs to be done separately
// See here: https://developer.android.com/about/versions/11/privacy/location#request-background-location-separately
permissionsToRequest = permissionsToCheck.toList().minus(Manifest.permission.ACCESS_BACKGROUND_LOCATION).toTypedArray()
}

val hasPermission = checkPermission(permissionsToCheck)
if (permissionsToCheck.isNotEmpty() && !hasPermission) {
LocationPermissionInfoHandler.showLocationPermInfoDialogIfNeeded(
requireContext(), permissionsToCheck,
continueYesCallback = {
checkAndRequestPermissions(permissionsToCheck, LOCATION_REQUEST_CODE, permissionsToRequest, true)
// openSsidDialog() will be called in onRequestPermissionsResult if permission is granted
}
)
} else openSsidDialog()
} else {
if (presenter.isSsidUsed()) {
DisabledLocationHandler.showLocationDisabledWarnDialog(requireActivity(), arrayOf(getString(commonR.string.pref_connection_wifi)), showAsNotification = false, withDisableOption = true) {
presenter.clearSsids()
preference.setSsids(emptySet())
val hasPermission = checkPermission(permissionsToCheck)
if (permissionsToCheck.isNotEmpty() && !hasPermission) {
LocationPermissionInfoHandler.showLocationPermInfoDialogIfNeeded(
requireContext(), permissionsToCheck,
continueYesCallback = {
checkAndRequestPermissions(permissionsToCheck, LOCATION_REQUEST_CODE, permissionsToRequest, true)
// showSsidSettings() will be called in onRequestPermissionsResult if permission is granted
}
} else {
DisabledLocationHandler.showLocationDisabledWarnDialog(requireActivity(), arrayOf(getString(commonR.string.pref_connection_wifi)))
)
} else showSsidSettings()
} else {
if (presenter.isSsidUsed()) {
DisabledLocationHandler.showLocationDisabledWarnDialog(requireActivity(), arrayOf(getString(commonR.string.pref_connection_wifi)), showAsNotification = false, withDisableOption = true) {
presenter.clearSsids()
presenter.updateInternalUrlStatus()
}
} else {
DisabledLocationHandler.showLocationDisabledWarnDialog(requireActivity(), arrayOf(getString(commonR.string.pref_connection_wifi)))
}
} else {
super.onDisplayPreferenceDialog(preference)
}
}

private fun showSsidSettings() {
parentFragmentManager
.beginTransaction()
.replace(R.id.content, SsidFragment::class.java, null)
.addToBackStack(getString(commonR.string.manage_ssids))
.commit()
}

private fun authenticationResult(result: Int) {
val success = result == Authenticator.SUCCESS
val switchLock = findPreference<SwitchPreference>("app_lock")
Expand Down Expand Up @@ -511,18 +504,6 @@ class SettingsFragment constructor(
return true
}

private fun openSsidDialog() {
// check if dialog is already showing
val fm = parentFragmentManager
if (fm.findFragmentByTag(SSID_DIALOG_TAG) != null) {
return
}

val ssidDialog = SsidDialogFragment.newInstance("connection_internal_ssids")
ssidDialog.setTargetFragment(this, 0)
ssidDialog.show(fm, SSID_DIALOG_TAG)
}

private fun isIgnoringBatteryOptimizations(): Boolean {
return Build.VERSION.SDK_INT <= Build.VERSION_CODES.M ||
context?.getSystemService<PowerManager>()
Expand Down Expand Up @@ -552,13 +533,15 @@ class SettingsFragment constructor(
}
if ((requestCode == LOCATION_REQUEST_CODE && !isGreaterR || requestCode == BACKGROUND_LOCATION_REQUEST_CODE && isGreaterR) && grantResults.isNotEmpty()) {
if (grantResults.all { it == PackageManager.PERMISSION_GRANTED }) {
openSsidDialog()
showSsidSettings()
}
}
}

override fun onResume() {
super.onResume()
activity?.title = getString(commonR.string.companion_app)

presenter.updateInternalUrlStatus()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ interface SettingsPresenter {
fun getPreferenceDataStore(): PreferenceDataStore
fun onCreate()
fun onFinish()
fun updateInternalUrlStatus()
fun isLockEnabled(): Boolean
fun sessionTimeOut(): Int
suspend fun getNotificationRateLimits(): RateLimitResponse?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ class SettingsPresenterImpl @Inject constructor(
"pinch_to_zoom" -> integrationUseCase.isPinchToZoomEnabled()
"app_lock" -> authenticationUseCase.isLockEnabled()
"crash_reporting" -> prefsRepository.isCrashReporting()
"prioritize_internal" -> urlUseCase.isPrioritizeInternal()
"autoplay_video" -> integrationUseCase.isAutoPlayVideoEnabled()
"webview_debug" -> integrationUseCase.isWebViewDebugEnabled()
else -> throw IllegalArgumentException("No boolean found by this key: $key")
Expand All @@ -66,7 +65,6 @@ class SettingsPresenterImpl @Inject constructor(
"pinch_to_zoom" -> integrationUseCase.setPinchToZoomEnabled(value)
"app_lock" -> authenticationUseCase.setLockEnabled(value)
"crash_reporting" -> prefsRepository.setCrashReporting(value)
"prioritize_internal" -> urlUseCase.setPrioritizeInternal(value)
"autoplay_video" -> integrationUseCase.setAutoPlayVideo(value)
"webview_debug" -> integrationUseCase.setWebViewDebugEnabled(value)
else -> throw IllegalArgumentException("No boolean found by this key: $key")
Expand Down Expand Up @@ -117,27 +115,6 @@ class SettingsPresenterImpl @Inject constructor(
}
}

override fun getStringSet(key: String, defValues: Set<String>?): Set<String> {
return runBlocking {
when (key) {
"connection_internal_ssids" -> urlUseCase.getHomeWifiSsids()
else -> throw IllegalArgumentException("No stringSet found by this key: $key")
}
}
}

override fun putStringSet(key: String, values: Set<String>?) {
mainScope.launch {
when (key) {
"connection_internal_ssids" -> {
val ssids = values ?: emptySet()
urlUseCase.saveHomeWifiSsids(ssids)
handleInternalUrlStatus(ssids)
}
}
}
}

override fun getInt(key: String, defValue: Int): Int {
return runBlocking {
when (key) {
Expand Down Expand Up @@ -170,13 +147,20 @@ class SettingsPresenterImpl @Inject constructor(
mainScope.cancel()
}

override fun updateInternalUrlStatus() {
mainScope.launch {
handleInternalUrlStatus(urlUseCase.getHomeWifiSsids())
}
}

private suspend fun handleInternalUrlStatus(ssids: Set<String>) {
if (ssids.isEmpty()) {
settingsView.disableInternalConnection()
urlUseCase.saveUrl("", true)
} else {
settingsView.enableInternalConnection()
}
settingsView.updateSsids(ssids)
}

override fun isLockEnabled(): Boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,7 @@ interface SettingsView {

fun enableInternalConnection()

fun updateSsids(ssids: Set<String>)

fun onLangSettingsChanged()
}