From ae6040e01e271d40427bec4a1536199c2b51cd49 Mon Sep 17 00:00:00 2001 From: Maxime Naturel Date: Mon, 14 Mar 2022 14:31:16 +0100 Subject: [PATCH 1/7] Adding changelog entry --- changelog.d/5536.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/5536.feature diff --git a/changelog.d/5536.feature b/changelog.d/5536.feature new file mode 100644 index 0000000000..bd0160f2fe --- /dev/null +++ b/changelog.d/5536.feature @@ -0,0 +1 @@ +Live location sharing: adding build config field and show permission dialog From 9c6cd9f63004839919e15e60052fff65aaebce4a Mon Sep 17 00:00:00 2001 From: Maxime Naturel Date: Mon, 14 Mar 2022 14:48:18 +0100 Subject: [PATCH 2/7] Adding build config field --- vector/build.gradle | 2 ++ .../location/LocationSharingFragment.kt | 22 +++++++++++-------- .../option/LocationSharingOptionPickerView.kt | 2 +- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/vector/build.gradle b/vector/build.gradle index 2d9c097da8..8eda029472 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -229,6 +229,7 @@ android { buildConfigField "boolean", "LOW_PRIVACY_LOG_ENABLE", "false" // Set to true if you want to enable strict mode in debug buildConfigField "boolean", "ENABLE_STRICT_MODE_LOGS", "false" + buildConfigField "Boolean", "ENABLE_LIVE_LOCATION_SHARING", "true" signingConfig signingConfigs.debug } @@ -238,6 +239,7 @@ android { buildConfigField "boolean", "LOW_PRIVACY_LOG_ENABLE", "false" buildConfigField "boolean", "ENABLE_STRICT_MODE_LOGS", "false" + buildConfigField "Boolean", "ENABLE_LIVE_LOCATION_SHARING", "false" postprocessing { removeUnusedCode true diff --git a/vector/src/main/java/im/vector/app/features/location/LocationSharingFragment.kt b/vector/src/main/java/im/vector/app/features/location/LocationSharingFragment.kt index e9e96e676c..399f8e4419 100644 --- a/vector/src/main/java/im/vector/app/features/location/LocationSharingFragment.kt +++ b/vector/src/main/java/im/vector/app/features/location/LocationSharingFragment.kt @@ -27,6 +27,7 @@ import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.mapbox.mapboxsdk.maps.MapView +import im.vector.app.BuildConfig import im.vector.app.R import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorBaseFragment @@ -170,16 +171,19 @@ class LocationSharingFragment @Inject constructor( private fun updateMap(state: LocationSharingViewState) { // first, update the options view - when (state.areTargetAndUserLocationEqual) { - // TODO activate USER_LIVE option when implemented - true -> views.shareLocationOptionsPicker.render( - LocationSharingOption.USER_CURRENT - ) - false -> views.shareLocationOptionsPicker.render( - LocationSharingOption.PINNED - ) - else -> views.shareLocationOptionsPicker.render() + val options: Set = when (state.areTargetAndUserLocationEqual) { + true -> { + if (BuildConfig.ENABLE_LIVE_LOCATION_SHARING) { + setOf(LocationSharingOption.USER_CURRENT, LocationSharingOption.USER_LIVE) + } else { + setOf(LocationSharingOption.USER_CURRENT) + } + } + false -> setOf(LocationSharingOption.PINNED) + else -> emptySet() } + views.shareLocationOptionsPicker.render(options) + // then, update the map using the height of the options view after it has been rendered views.shareLocationOptionsPicker.post { val mapState = state diff --git a/vector/src/main/java/im/vector/app/features/location/option/LocationSharingOptionPickerView.kt b/vector/src/main/java/im/vector/app/features/location/option/LocationSharingOptionPickerView.kt index 1aea1ff613..8a603a1a56 100644 --- a/vector/src/main/java/im/vector/app/features/location/option/LocationSharingOptionPickerView.kt +++ b/vector/src/main/java/im/vector/app/features/location/option/LocationSharingOptionPickerView.kt @@ -58,7 +58,7 @@ class LocationSharingOptionPickerView @JvmOverloads constructor( applyBackground() } - fun render(vararg options: LocationSharingOption) { + fun render(options: Set = emptySet()) { val optionsNumber = options.toSet().size val isPinnedVisible = options.contains(LocationSharingOption.PINNED) val isUserCurrentVisible = options.contains(LocationSharingOption.USER_CURRENT) From 6f6bb3dbfea2f94a72efb9793d5deae5fb36b13e Mon Sep 17 00:00:00 2001 From: Maxime Naturel Date: Mon, 14 Mar 2022 17:20:15 +0100 Subject: [PATCH 3/7] Adding method to show dialog when permission is missing --- .../location/ILocationSharingNavigator.kt | 22 +++++++++++++ .../location/LocationSharingFragment.kt | 18 +++++++++-- .../location/LocationSharingNavigator.kt | 31 +++++++++++++++++++ vector/src/main/res/values/strings.xml | 2 ++ 4 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/features/location/ILocationSharingNavigator.kt create mode 100644 vector/src/main/java/im/vector/app/features/location/LocationSharingNavigator.kt diff --git a/vector/src/main/java/im/vector/app/features/location/ILocationSharingNavigator.kt b/vector/src/main/java/im/vector/app/features/location/ILocationSharingNavigator.kt new file mode 100644 index 0000000000..f86f622712 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/location/ILocationSharingNavigator.kt @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.location + +interface ILocationSharingNavigator { + fun quit() + fun goToAppSettings() +} diff --git a/vector/src/main/java/im/vector/app/features/location/LocationSharingFragment.kt b/vector/src/main/java/im/vector/app/features/location/LocationSharingFragment.kt index 399f8e4419..7e7303c1f3 100644 --- a/vector/src/main/java/im/vector/app/features/location/LocationSharingFragment.kt +++ b/vector/src/main/java/im/vector/app/features/location/LocationSharingFragment.kt @@ -50,6 +50,8 @@ class LocationSharingFragment @Inject constructor( private val viewModel: LocationSharingViewModel by fragmentViewModel() + private val viewNavigator: ILocationSharingNavigator by lazy { LocationSharingNavigator(activity) } + // Keep a ref to handle properly the onDestroy callback private var mapView: WeakReference? = null @@ -78,7 +80,7 @@ class LocationSharingFragment @Inject constructor( viewModel.observeViewEvents { when (it) { LocationSharingViewEvents.LocationNotAvailableError -> handleLocationNotAvailableError() - LocationSharingViewEvents.Close -> activity?.finish() + LocationSharingViewEvents.Close -> viewNavigator.quit() is LocationSharingViewEvents.ZoomToUserLocation -> handleZoomToUserLocationEvent(it) }.exhaustive } @@ -138,12 +140,24 @@ class LocationSharingFragment @Inject constructor( .setTitle(R.string.location_not_available_dialog_title) .setMessage(R.string.location_not_available_dialog_content) .setPositiveButton(R.string.ok) { _, _ -> - activity?.finish() + viewNavigator.quit() } .setCancelable(false) .show() } + private fun handleMissingBackgroundLocationPermission() { + MaterialAlertDialogBuilder(requireActivity()) + .setTitle(R.string.location_in_background_missing_permission_dialog_title) + .setMessage(R.string.location_in_background_missing_permission_dialog_content) + .setPositiveButton(R.string.settings) { _, _ -> + viewNavigator.goToAppSettings() + } + .setNegativeButton(R.string.action_not_now, null) + .setCancelable(false) + .show() + } + private fun initLocateButton() { views.mapView.locateButton.setOnClickListener { viewModel.handle(LocationSharingAction.ZoomToUserLocation) diff --git a/vector/src/main/java/im/vector/app/features/location/LocationSharingNavigator.kt b/vector/src/main/java/im/vector/app/features/location/LocationSharingNavigator.kt new file mode 100644 index 0000000000..c474cd6b58 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/location/LocationSharingNavigator.kt @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.location + +import android.app.Activity +import im.vector.app.core.utils.openAppSettingsPage + +class LocationSharingNavigator constructor(val activity: Activity?): ILocationSharingNavigator { + + override fun quit() { + activity?.finish() + } + + override fun goToAppSettings() { + activity?.let { openAppSettingsPage(it) } + } +} diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index 162ab3e119..9ec2cda85f 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -2937,6 +2937,8 @@ Share live location Share this location Share this location + Allow access + If you’d like to share your Live location, ${app_name} needs location access when the app is in the background.\nWe will only access your location for the duration that you choose. ${app_name} could not access your location ${app_name} could not access your location. Please try again later. Open with From d776f0c09cf7d84a8f59cdf0c0c01f7157f486c8 Mon Sep 17 00:00:00 2001 From: Maxime Naturel Date: Tue, 15 Mar 2022 13:30:57 +0100 Subject: [PATCH 4/7] Check permission for background location (OS version <= Android 10 case) --- vector/src/main/AndroidManifest.xml | 1 + .../vector/app/core/utils/PermissionsTools.kt | 11 +++-- .../attachments/AttachmentTypeSelectorView.kt | 4 +- .../location/ILocationSharingNavigator.kt | 1 + .../location/LocationSharingAction.kt | 1 + .../location/LocationSharingFragment.kt | 46 ++++++++++++++++++- .../location/LocationSharingNavigator.kt | 9 +++- .../location/LocationSharingViewModel.kt | 7 +++ 8 files changed, 71 insertions(+), 9 deletions(-) diff --git a/vector/src/main/AndroidManifest.xml b/vector/src/main/AndroidManifest.xml index 58b1bc177c..1d99fba91a 100644 --- a/vector/src/main/AndroidManifest.xml +++ b/vector/src/main/AndroidManifest.xml @@ -45,6 +45,7 @@ + diff --git a/vector/src/main/java/im/vector/app/core/utils/PermissionsTools.kt b/vector/src/main/java/im/vector/app/core/utils/PermissionsTools.kt index dabf11b9d3..d2e69a87e9 100644 --- a/vector/src/main/java/im/vector/app/core/utils/PermissionsTools.kt +++ b/vector/src/main/java/im/vector/app/core/utils/PermissionsTools.kt @@ -19,6 +19,7 @@ package im.vector.app.core.utils import android.Manifest import android.app.Activity import android.content.pm.PackageManager +import android.os.Build import androidx.activity.ComponentActivity import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.contract.ActivityResultContracts @@ -32,6 +33,7 @@ import im.vector.app.R import im.vector.app.core.platform.VectorBaseActivity // Permissions sets +val PERMISSIONS_EMPTY = emptyList() val PERMISSIONS_FOR_AUDIO_IP_CALL = listOf(Manifest.permission.RECORD_AUDIO) val PERMISSIONS_FOR_VIDEO_IP_CALL = listOf(Manifest.permission.RECORD_AUDIO, Manifest.permission.CAMERA) val PERMISSIONS_FOR_VOICE_MESSAGE = listOf(Manifest.permission.RECORD_AUDIO) @@ -40,9 +42,12 @@ val PERMISSIONS_FOR_MEMBERS_SEARCH = listOf(Manifest.permission.READ_CONTACTS) val PERMISSIONS_FOR_ROOM_AVATAR = listOf(Manifest.permission.CAMERA) val PERMISSIONS_FOR_WRITING_FILES = listOf(Manifest.permission.WRITE_EXTERNAL_STORAGE) val PERMISSIONS_FOR_PICKING_CONTACT = listOf(Manifest.permission.READ_CONTACTS) -val PERMISSIONS_FOR_LOCATION_SHARING = listOf(Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION) - -val PERMISSIONS_EMPTY = emptyList() +val PERMISSIONS_FOR_FOREGROUND_LOCATION_SHARING = listOf(Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION) +val PERMISSIONS_FOR_BACKGROUND_LOCATION_SHARING = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + listOf(Manifest.permission.ACCESS_BACKGROUND_LOCATION) +} else { + PERMISSIONS_EMPTY +} // This is not ideal to store the value like that, but it works private var permissionDialogDisplayed = false diff --git a/vector/src/main/java/im/vector/app/features/attachments/AttachmentTypeSelectorView.kt b/vector/src/main/java/im/vector/app/features/attachments/AttachmentTypeSelectorView.kt index a15bd52174..7fcbb6bae6 100644 --- a/vector/src/main/java/im/vector/app/features/attachments/AttachmentTypeSelectorView.kt +++ b/vector/src/main/java/im/vector/app/features/attachments/AttachmentTypeSelectorView.kt @@ -37,7 +37,7 @@ import androidx.core.view.isVisible import im.vector.app.R import im.vector.app.core.epoxy.onClick import im.vector.app.core.utils.PERMISSIONS_EMPTY -import im.vector.app.core.utils.PERMISSIONS_FOR_LOCATION_SHARING +import im.vector.app.core.utils.PERMISSIONS_FOR_FOREGROUND_LOCATION_SHARING import im.vector.app.core.utils.PERMISSIONS_FOR_PICKING_CONTACT import im.vector.app.core.utils.PERMISSIONS_FOR_TAKING_PHOTO import im.vector.app.databinding.ViewAttachmentTypeSelectorBinding @@ -215,6 +215,6 @@ class AttachmentTypeSelectorView(context: Context, STICKER(PERMISSIONS_EMPTY, R.string.tooltip_attachment_sticker), CONTACT(PERMISSIONS_FOR_PICKING_CONTACT, R.string.tooltip_attachment_contact), POLL(PERMISSIONS_EMPTY, R.string.tooltip_attachment_poll), - LOCATION(PERMISSIONS_FOR_LOCATION_SHARING, R.string.tooltip_attachment_location) + LOCATION(PERMISSIONS_FOR_FOREGROUND_LOCATION_SHARING, R.string.tooltip_attachment_location) } } diff --git a/vector/src/main/java/im/vector/app/features/location/ILocationSharingNavigator.kt b/vector/src/main/java/im/vector/app/features/location/ILocationSharingNavigator.kt index f86f622712..91c62618dd 100644 --- a/vector/src/main/java/im/vector/app/features/location/ILocationSharingNavigator.kt +++ b/vector/src/main/java/im/vector/app/features/location/ILocationSharingNavigator.kt @@ -17,6 +17,7 @@ package im.vector.app.features.location interface ILocationSharingNavigator { + var goingToAppSettings: Boolean fun quit() fun goToAppSettings() } diff --git a/vector/src/main/java/im/vector/app/features/location/LocationSharingAction.kt b/vector/src/main/java/im/vector/app/features/location/LocationSharingAction.kt index ec47c23ea7..d7d686ee60 100644 --- a/vector/src/main/java/im/vector/app/features/location/LocationSharingAction.kt +++ b/vector/src/main/java/im/vector/app/features/location/LocationSharingAction.kt @@ -23,4 +23,5 @@ sealed class LocationSharingAction : VectorViewModelAction { data class PinnedLocationSharing(val locationData: LocationData?) : LocationSharingAction() data class LocationTargetChange(val locationData: LocationData) : LocationSharingAction() object ZoomToUserLocation : LocationSharingAction() + object StartLiveLocationSharing : LocationSharingAction() } diff --git a/vector/src/main/java/im/vector/app/features/location/LocationSharingFragment.kt b/vector/src/main/java/im/vector/app/features/location/LocationSharingFragment.kt index 7e7303c1f3..bbef06c11e 100644 --- a/vector/src/main/java/im/vector/app/features/location/LocationSharingFragment.kt +++ b/vector/src/main/java/im/vector/app/features/location/LocationSharingFragment.kt @@ -31,6 +31,10 @@ import im.vector.app.BuildConfig import im.vector.app.R import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorBaseFragment +import im.vector.app.core.utils.PERMISSIONS_FOR_BACKGROUND_LOCATION_SHARING +import im.vector.app.core.utils.PERMISSIONS_FOR_FOREGROUND_LOCATION_SHARING +import im.vector.app.core.utils.checkPermissions +import im.vector.app.core.utils.registerForPermissionsResult import im.vector.app.databinding.FragmentLocationSharingBinding import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.room.detail.timeline.helper.MatrixItemColorProvider @@ -79,8 +83,8 @@ class LocationSharingFragment @Inject constructor( viewModel.observeViewEvents { when (it) { - LocationSharingViewEvents.LocationNotAvailableError -> handleLocationNotAvailableError() LocationSharingViewEvents.Close -> viewNavigator.quit() + LocationSharingViewEvents.LocationNotAvailableError -> handleLocationNotAvailableError() is LocationSharingViewEvents.ZoomToUserLocation -> handleZoomToUserLocationEvent(it) }.exhaustive } @@ -89,6 +93,11 @@ class LocationSharingFragment @Inject constructor( override fun onResume() { super.onResume() views.mapView.onResume() + if (viewNavigator.goingToAppSettings) { + viewNavigator.goingToAppSettings = false + // retry to start live location + tryStartLiveLocationSharing() + } } override fun onPause() { @@ -179,10 +188,43 @@ class LocationSharingFragment @Inject constructor( viewModel.handle(LocationSharingAction.CurrentUserLocationSharing) } views.shareLocationOptionsPicker.optionUserLive.debouncedClicks { - // TODO + tryStartLiveLocationSharing() } } + private val foregroundLocationResultLauncher = registerForPermissionsResult { allGranted, deniedPermanently -> + if (allGranted && checkPermissions(PERMISSIONS_FOR_BACKGROUND_LOCATION_SHARING, requireActivity(), backgroundLocationResultLauncher)) { + startLiveLocationSharing() + } else if (deniedPermanently) { + handleMissingBackgroundLocationPermission() + } + } + + private val backgroundLocationResultLauncher = registerForPermissionsResult { allGranted, deniedPermanently -> + if (allGranted) { + startLiveLocationSharing() + } else if (deniedPermanently) { + handleMissingBackgroundLocationPermission() + } + } + + private fun tryStartLiveLocationSharing() { + // TODO handle Android 11+ case => cannot ask runtime permission for background location + // when ActivityCompat.shouldShowRequestPermissionRationale() returns true + // show dialog to redirect to app settings (handleMissingBackgroundLocationPermission()) + + // TODO test with Android 6, Android 10 and Android 11 + // we need to re-check foreground location to be sure it has not changed after landing on this screen + if (checkPermissions(PERMISSIONS_FOR_FOREGROUND_LOCATION_SHARING, requireActivity(), foregroundLocationResultLauncher) && + checkPermissions(PERMISSIONS_FOR_BACKGROUND_LOCATION_SHARING, requireActivity(), backgroundLocationResultLauncher)) { + startLiveLocationSharing() + } + } + + private fun startLiveLocationSharing() { + viewModel.handle(LocationSharingAction.StartLiveLocationSharing) + } + private fun updateMap(state: LocationSharingViewState) { // first, update the options view val options: Set = when (state.areTargetAndUserLocationEqual) { diff --git a/vector/src/main/java/im/vector/app/features/location/LocationSharingNavigator.kt b/vector/src/main/java/im/vector/app/features/location/LocationSharingNavigator.kt index c474cd6b58..b4412710e3 100644 --- a/vector/src/main/java/im/vector/app/features/location/LocationSharingNavigator.kt +++ b/vector/src/main/java/im/vector/app/features/location/LocationSharingNavigator.kt @@ -19,13 +19,18 @@ package im.vector.app.features.location import android.app.Activity import im.vector.app.core.utils.openAppSettingsPage -class LocationSharingNavigator constructor(val activity: Activity?): ILocationSharingNavigator { +class LocationSharingNavigator constructor(val activity: Activity?) : ILocationSharingNavigator { + + override var goingToAppSettings: Boolean = false override fun quit() { activity?.finish() } override fun goToAppSettings() { - activity?.let { openAppSettingsPage(it) } + activity?.let { + goingToAppSettings = true + openAppSettingsPage(it) + } } } diff --git a/vector/src/main/java/im/vector/app/features/location/LocationSharingViewModel.kt b/vector/src/main/java/im/vector/app/features/location/LocationSharingViewModel.kt index 25bc482412..639666e63f 100644 --- a/vector/src/main/java/im/vector/app/features/location/LocationSharingViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/location/LocationSharingViewModel.kt @@ -38,6 +38,7 @@ import kotlinx.coroutines.launch import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.util.toMatrixItem +import timber.log.Timber /** * Sampling period to compare target location and user location. @@ -120,6 +121,7 @@ class LocationSharingViewModel @AssistedInject constructor( is LocationSharingAction.PinnedLocationSharing -> handlePinnedLocationSharingAction(action) is LocationSharingAction.LocationTargetChange -> handleLocationTargetChangeAction(action) LocationSharingAction.ZoomToUserLocation -> handleZoomToUserLocationAction() + LocationSharingAction.StartLiveLocationSharing -> handleStartLiveLocationSharingAction() }.exhaustive } @@ -157,6 +159,11 @@ class LocationSharingViewModel @AssistedInject constructor( } } + private fun handleStartLiveLocationSharingAction() { + // TODO start sharing live location and update view state + Timber.d("live location sharing started") + } + override fun onLocationUpdate(locationData: LocationData) { setState { copy(lastKnownUserLocation = locationData) From 575d62a35476d216ee4e9534b1ec9ea5a1cfe6c8 Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Wed, 16 Mar 2022 16:34:48 +0300 Subject: [PATCH 5/7] Naming convention fix. --- ...kt => DefaultLocationSharingSettingsNavigator.kt} | 2 +- .../app/features/location/LocationSharingFragment.kt | 12 ++++++------ ...igator.kt => LocationSharingSettingsNavigator.kt} | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) rename vector/src/main/java/im/vector/app/features/location/{LocationSharingNavigator.kt => DefaultLocationSharingSettingsNavigator.kt} (89%) rename vector/src/main/java/im/vector/app/features/location/{ILocationSharingNavigator.kt => LocationSharingSettingsNavigator.kt} (94%) diff --git a/vector/src/main/java/im/vector/app/features/location/LocationSharingNavigator.kt b/vector/src/main/java/im/vector/app/features/location/DefaultLocationSharingSettingsNavigator.kt similarity index 89% rename from vector/src/main/java/im/vector/app/features/location/LocationSharingNavigator.kt rename to vector/src/main/java/im/vector/app/features/location/DefaultLocationSharingSettingsNavigator.kt index b4412710e3..5b8ae5b01a 100644 --- a/vector/src/main/java/im/vector/app/features/location/LocationSharingNavigator.kt +++ b/vector/src/main/java/im/vector/app/features/location/DefaultLocationSharingSettingsNavigator.kt @@ -19,7 +19,7 @@ package im.vector.app.features.location import android.app.Activity import im.vector.app.core.utils.openAppSettingsPage -class LocationSharingNavigator constructor(val activity: Activity?) : ILocationSharingNavigator { +class DefaultLocationSharingSettingsNavigator constructor(val activity: Activity?) : LocationSharingSettingsNavigator { override var goingToAppSettings: Boolean = false diff --git a/vector/src/main/java/im/vector/app/features/location/LocationSharingFragment.kt b/vector/src/main/java/im/vector/app/features/location/LocationSharingFragment.kt index bbef06c11e..12a84ac147 100644 --- a/vector/src/main/java/im/vector/app/features/location/LocationSharingFragment.kt +++ b/vector/src/main/java/im/vector/app/features/location/LocationSharingFragment.kt @@ -54,7 +54,7 @@ class LocationSharingFragment @Inject constructor( private val viewModel: LocationSharingViewModel by fragmentViewModel() - private val viewNavigator: ILocationSharingNavigator by lazy { LocationSharingNavigator(activity) } + private val locationSharingNavigator: LocationSharingSettingsNavigator by lazy { DefaultLocationSharingSettingsNavigator(activity) } // Keep a ref to handle properly the onDestroy callback private var mapView: WeakReference? = null @@ -83,7 +83,7 @@ class LocationSharingFragment @Inject constructor( viewModel.observeViewEvents { when (it) { - LocationSharingViewEvents.Close -> viewNavigator.quit() + LocationSharingViewEvents.Close -> locationSharingNavigator.quit() LocationSharingViewEvents.LocationNotAvailableError -> handleLocationNotAvailableError() is LocationSharingViewEvents.ZoomToUserLocation -> handleZoomToUserLocationEvent(it) }.exhaustive @@ -93,8 +93,8 @@ class LocationSharingFragment @Inject constructor( override fun onResume() { super.onResume() views.mapView.onResume() - if (viewNavigator.goingToAppSettings) { - viewNavigator.goingToAppSettings = false + if (locationSharingNavigator.goingToAppSettings) { + locationSharingNavigator.goingToAppSettings = false // retry to start live location tryStartLiveLocationSharing() } @@ -149,7 +149,7 @@ class LocationSharingFragment @Inject constructor( .setTitle(R.string.location_not_available_dialog_title) .setMessage(R.string.location_not_available_dialog_content) .setPositiveButton(R.string.ok) { _, _ -> - viewNavigator.quit() + locationSharingNavigator.quit() } .setCancelable(false) .show() @@ -160,7 +160,7 @@ class LocationSharingFragment @Inject constructor( .setTitle(R.string.location_in_background_missing_permission_dialog_title) .setMessage(R.string.location_in_background_missing_permission_dialog_content) .setPositiveButton(R.string.settings) { _, _ -> - viewNavigator.goToAppSettings() + locationSharingNavigator.goToAppSettings() } .setNegativeButton(R.string.action_not_now, null) .setCancelable(false) diff --git a/vector/src/main/java/im/vector/app/features/location/ILocationSharingNavigator.kt b/vector/src/main/java/im/vector/app/features/location/LocationSharingSettingsNavigator.kt similarity index 94% rename from vector/src/main/java/im/vector/app/features/location/ILocationSharingNavigator.kt rename to vector/src/main/java/im/vector/app/features/location/LocationSharingSettingsNavigator.kt index 91c62618dd..6298bf312b 100644 --- a/vector/src/main/java/im/vector/app/features/location/ILocationSharingNavigator.kt +++ b/vector/src/main/java/im/vector/app/features/location/LocationSharingSettingsNavigator.kt @@ -16,7 +16,7 @@ package im.vector.app.features.location -interface ILocationSharingNavigator { +interface LocationSharingSettingsNavigator { var goingToAppSettings: Boolean fun quit() fun goToAppSettings() From 33e5a206bd8361c25cc007a2f2c8eb1c6840a40c Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Thu, 17 Mar 2022 12:29:46 +0300 Subject: [PATCH 6/7] Fix background location permission for Android > 10. --- .../app/features/location/LocationSharingFragment.kt | 12 ++++++------ vector/src/main/res/values/strings.xml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/location/LocationSharingFragment.kt b/vector/src/main/java/im/vector/app/features/location/LocationSharingFragment.kt index 12a84ac147..479ffd796d 100644 --- a/vector/src/main/java/im/vector/app/features/location/LocationSharingFragment.kt +++ b/vector/src/main/java/im/vector/app/features/location/LocationSharingFragment.kt @@ -209,14 +209,14 @@ class LocationSharingFragment @Inject constructor( } private fun tryStartLiveLocationSharing() { - // TODO handle Android 11+ case => cannot ask runtime permission for background location - // when ActivityCompat.shouldShowRequestPermissionRationale() returns true - // show dialog to redirect to app settings (handleMissingBackgroundLocationPermission()) - - // TODO test with Android 6, Android 10 and Android 11 // we need to re-check foreground location to be sure it has not changed after landing on this screen if (checkPermissions(PERMISSIONS_FOR_FOREGROUND_LOCATION_SHARING, requireActivity(), foregroundLocationResultLauncher) && - checkPermissions(PERMISSIONS_FOR_BACKGROUND_LOCATION_SHARING, requireActivity(), backgroundLocationResultLauncher)) { + checkPermissions( + PERMISSIONS_FOR_BACKGROUND_LOCATION_SHARING, + requireActivity(), + backgroundLocationResultLauncher, + R.string.location_in_background_missing_permission_dialog_content + )) { startLiveLocationSharing() } } diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index 9ec2cda85f..428be3209f 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -2938,7 +2938,7 @@ Share this location Share this location Allow access - If you’d like to share your Live location, ${app_name} needs location access when the app is in the background.\nWe will only access your location for the duration that you choose. + If you’d like to share your Live location, ${app_name} needs location access all the time when the app is in the background.\nWe will only access your location for the duration that you choose. ${app_name} could not access your location ${app_name} could not access your location. Please try again later. Open with From a13ba13fb54d36d08150f39b2f20bb2ebea78990 Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Thu, 17 Mar 2022 18:30:39 +0300 Subject: [PATCH 7/7] Code review fixes. --- .../src/main/java/im/vector/app/core/utils/PermissionsTools.kt | 1 + ...gSettingsNavigator.kt => DefaultLocationSharingNavigator.kt} | 2 +- .../im/vector/app/features/location/LocationSharingFragment.kt | 2 +- ...nSharingSettingsNavigator.kt => LocationSharingNavigator.kt} | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) rename vector/src/main/java/im/vector/app/features/location/{DefaultLocationSharingSettingsNavigator.kt => DefaultLocationSharingNavigator.kt} (89%) rename vector/src/main/java/im/vector/app/features/location/{LocationSharingSettingsNavigator.kt => LocationSharingNavigator.kt} (94%) diff --git a/vector/src/main/java/im/vector/app/core/utils/PermissionsTools.kt b/vector/src/main/java/im/vector/app/core/utils/PermissionsTools.kt index d2e69a87e9..eada3a4f25 100644 --- a/vector/src/main/java/im/vector/app/core/utils/PermissionsTools.kt +++ b/vector/src/main/java/im/vector/app/core/utils/PermissionsTools.kt @@ -128,6 +128,7 @@ fun checkPermissions(permissionsToBeGranted: List, .setPositiveButton(R.string.ok) { _, _ -> activityResultLauncher.launch(missingPermissions.toTypedArray()) } + .setNegativeButton(R.string.action_not_now, null) .show() } else { // some permissions are not granted, ask permissions diff --git a/vector/src/main/java/im/vector/app/features/location/DefaultLocationSharingSettingsNavigator.kt b/vector/src/main/java/im/vector/app/features/location/DefaultLocationSharingNavigator.kt similarity index 89% rename from vector/src/main/java/im/vector/app/features/location/DefaultLocationSharingSettingsNavigator.kt rename to vector/src/main/java/im/vector/app/features/location/DefaultLocationSharingNavigator.kt index 5b8ae5b01a..8f424af9ec 100644 --- a/vector/src/main/java/im/vector/app/features/location/DefaultLocationSharingSettingsNavigator.kt +++ b/vector/src/main/java/im/vector/app/features/location/DefaultLocationSharingNavigator.kt @@ -19,7 +19,7 @@ package im.vector.app.features.location import android.app.Activity import im.vector.app.core.utils.openAppSettingsPage -class DefaultLocationSharingSettingsNavigator constructor(val activity: Activity?) : LocationSharingSettingsNavigator { +class DefaultLocationSharingNavigator constructor(val activity: Activity?) : LocationSharingNavigator { override var goingToAppSettings: Boolean = false diff --git a/vector/src/main/java/im/vector/app/features/location/LocationSharingFragment.kt b/vector/src/main/java/im/vector/app/features/location/LocationSharingFragment.kt index 479ffd796d..c4dccc1b73 100644 --- a/vector/src/main/java/im/vector/app/features/location/LocationSharingFragment.kt +++ b/vector/src/main/java/im/vector/app/features/location/LocationSharingFragment.kt @@ -54,7 +54,7 @@ class LocationSharingFragment @Inject constructor( private val viewModel: LocationSharingViewModel by fragmentViewModel() - private val locationSharingNavigator: LocationSharingSettingsNavigator by lazy { DefaultLocationSharingSettingsNavigator(activity) } + private val locationSharingNavigator: LocationSharingNavigator by lazy { DefaultLocationSharingNavigator(activity) } // Keep a ref to handle properly the onDestroy callback private var mapView: WeakReference? = null diff --git a/vector/src/main/java/im/vector/app/features/location/LocationSharingSettingsNavigator.kt b/vector/src/main/java/im/vector/app/features/location/LocationSharingNavigator.kt similarity index 94% rename from vector/src/main/java/im/vector/app/features/location/LocationSharingSettingsNavigator.kt rename to vector/src/main/java/im/vector/app/features/location/LocationSharingNavigator.kt index 6298bf312b..8927da9239 100644 --- a/vector/src/main/java/im/vector/app/features/location/LocationSharingSettingsNavigator.kt +++ b/vector/src/main/java/im/vector/app/features/location/LocationSharingNavigator.kt @@ -16,7 +16,7 @@ package im.vector.app.features.location -interface LocationSharingSettingsNavigator { +interface LocationSharingNavigator { var goingToAppSettings: Boolean fun quit() fun goToAppSettings()