diff --git a/changelog.d/6642.misc b/changelog.d/6642.misc new file mode 100644 index 0000000000..a32b20716a --- /dev/null +++ b/changelog.d/6642.misc @@ -0,0 +1 @@ +[Location Share] Open maximized map on tapping on live sharing notification diff --git a/vector/src/main/AndroidManifest.xml b/vector/src/main/AndroidManifest.xml index fa89013707..63c713d9e6 100644 --- a/vector/src/main/AndroidManifest.xml +++ b/vector/src/main/AndroidManifest.xml @@ -377,7 +377,7 @@ 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 17e53e63d1..ca524a0126 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 @@ -42,6 +42,7 @@ import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.room.detail.timeline.helper.MatrixItemColorProvider import im.vector.app.features.location.live.LiveLocationLabsFlagPromotionBottomSheet import im.vector.app.features.location.live.duration.ChooseLiveDurationBottomSheet +import im.vector.app.features.location.live.tracking.LocationSharingAndroidService import im.vector.app.features.location.option.LocationSharingOption import im.vector.app.features.settings.VectorPreferences import org.matrix.android.sdk.api.util.MatrixItem diff --git a/vector/src/main/java/im/vector/app/features/location/LocationSharingServiceConnection.kt b/vector/src/main/java/im/vector/app/features/location/LocationSharingServiceConnection.kt index 3be73e9fd4..9e905060d9 100644 --- a/vector/src/main/java/im/vector/app/features/location/LocationSharingServiceConnection.kt +++ b/vector/src/main/java/im/vector/app/features/location/LocationSharingServiceConnection.kt @@ -22,6 +22,7 @@ import android.content.Intent import android.content.ServiceConnection import android.os.IBinder import im.vector.app.core.di.ActiveSessionHolder +import im.vector.app.features.location.live.tracking.LocationSharingAndroidService import im.vector.app.features.session.coroutineScope import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.launchIn diff --git a/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewActivity.kt b/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewActivity.kt index c0f07dba57..fabdda49d8 100644 --- a/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewActivity.kt +++ b/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewActivity.kt @@ -24,6 +24,7 @@ import im.vector.app.R import im.vector.app.core.extensions.addFragment import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.databinding.ActivityLocationSharingBinding +import im.vector.app.features.MainActivity import kotlinx.parcelize.Parcelize @Parcelize @@ -59,10 +60,15 @@ class LocationLiveMapViewActivity : VectorBaseActivity() + private val liveInfoSet = linkedSetOf() var callback: Callback? = null private val jobs = mutableListOf() private var startInProgress = false + private var foregroundModeStarted = false private val _roomIdsOfActiveLives = MutableSharedFlow>(replay = 1) val roomIdsOfActiveLives = _roomIdsOfActiveLives.asSharedFlow() @@ -76,7 +76,6 @@ class LocationSharingAndroidService : VectorAndroidService(), LocationTracker.Ca override fun onCreate() { super.onCreate() Timber.i("onCreate") - initLocationTracking() } @@ -102,8 +101,13 @@ class LocationSharingAndroidService : VectorAndroidService(), LocationTracker.Ca if (roomArgs != null) { // Show a sticky notification - val notification = notificationUtils.buildLiveLocationSharingNotification() - startForeground(roomArgs.roomId.hashCode(), notification) + val notification = liveLocationNotificationBuilder.buildLiveLocationSharingNotification(roomArgs.roomId) + if (foregroundModeStarted) { + NotificationManagerCompat.from(this).notify(FOREGROUND_SERVICE_NOTIFICATION_ID, notification) + } else { + startForeground(FOREGROUND_SERVICE_NOTIFICATION_ID, notification) + foregroundModeStarted = true + } // Send beacon info state event launchWithActiveSession { session -> @@ -148,15 +152,24 @@ class LocationSharingAndroidService : VectorAndroidService(), LocationTracker.Ca private fun stopSharingLocation(beaconEventId: String) { Timber.i("stopSharingLocation for beacon $beaconEventId") removeRoomArgs(beaconEventId) + updateNotification() tryToDestroyMe() } + private fun updateNotification() { + if (liveInfoSet.isNotEmpty()) { + val roomId = liveInfoSet.last().roomArgs.roomId + val notification = liveLocationNotificationBuilder.buildLiveLocationSharingNotification(roomId) + NotificationManagerCompat.from(this).notify(FOREGROUND_SERVICE_NOTIFICATION_ID, notification) + } + } + private fun onLocationUpdate(locationData: LocationData) { Timber.i("onLocationUpdate. Uncertainty: ${locationData.uncertainty}") // Emit location update to all rooms in which live location sharing is active - roomArgsMap.toMap().forEach { item -> - sendLiveLocation(item.value.roomId, item.key, locationData) + liveInfoSet.toSet().forEach { liveInfo -> + sendLiveLocation(liveInfo.roomArgs.roomId, liveInfo.beaconEventId, locationData) } } @@ -183,7 +196,7 @@ class LocationSharingAndroidService : VectorAndroidService(), LocationTracker.Ca } private fun tryToDestroyMe() { - if (startInProgress.not() && roomArgsMap.isEmpty()) { + if (startInProgress.not() && liveInfoSet.isEmpty()) { Timber.i("Destroying self, time is up for all rooms") stopSelf() } @@ -199,13 +212,14 @@ class LocationSharingAndroidService : VectorAndroidService(), LocationTracker.Ca private fun addRoomArgs(beaconEventId: String, roomArgs: RoomArgs) { Timber.i("adding roomArgs for beaconEventId: $beaconEventId") - roomArgsMap[beaconEventId] = roomArgs + liveInfoSet.removeAll { it.beaconEventId == beaconEventId } + liveInfoSet.add(LiveInfo(beaconEventId, roomArgs)) launchWithActiveSession { _roomIdsOfActiveLives.emit(getRoomIdsOfActiveLives()) } } private fun removeRoomArgs(beaconEventId: String) { Timber.i("removing roomArgs for beaconEventId: $beaconEventId") - roomArgsMap.remove(beaconEventId) + liveInfoSet.removeAll { it.beaconEventId == beaconEventId } launchWithActiveSession { _roomIdsOfActiveLives.emit(getRoomIdsOfActiveLives()) } } @@ -234,7 +248,7 @@ class LocationSharingAndroidService : VectorAndroidService(), LocationTracker.Ca } fun getRoomIdsOfActiveLives(): Set { - return roomArgsMap.map { it.value.roomId }.toSet() + return liveInfoSet.map { it.roomArgs.roomId }.toSet() } override fun onBind(intent: Intent?): IBinder { @@ -251,5 +265,11 @@ class LocationSharingAndroidService : VectorAndroidService(), LocationTracker.Ca companion object { const val EXTRA_ROOM_ARGS = "EXTRA_ROOM_ARGS" + private const val FOREGROUND_SERVICE_NOTIFICATION_ID = 300 } + + private data class LiveInfo( + val beaconEventId: String, + val roomArgs: RoomArgs + ) } diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt index 2948565d58..b5bd02b9d5 100755 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt @@ -105,7 +105,7 @@ class NotificationUtils @Inject constructor( const val SMART_REPLY_ACTION = "${BuildConfig.APPLICATION_ID}.NotificationActions.SMART_REPLY_ACTION" const val DISMISS_SUMMARY_ACTION = "${BuildConfig.APPLICATION_ID}.NotificationActions.DISMISS_SUMMARY_ACTION" const val DISMISS_ROOM_NOTIF_ACTION = "${BuildConfig.APPLICATION_ID}.NotificationActions.DISMISS_ROOM_NOTIF_ACTION" - private const val TAP_TO_VIEW_ACTION = "${BuildConfig.APPLICATION_ID}.NotificationActions.TAP_TO_VIEW_ACTION" + const val TAP_TO_VIEW_ACTION = "${BuildConfig.APPLICATION_ID}.NotificationActions.TAP_TO_VIEW_ACTION" const val DIAGNOSTIC_ACTION = "${BuildConfig.APPLICATION_ID}.NotificationActions.DIAGNOSTIC" const val PUSH_ACTION = "${BuildConfig.APPLICATION_ID}.PUSH" @@ -118,7 +118,7 @@ class NotificationUtils @Inject constructor( private const val NOISY_NOTIFICATION_CHANNEL_ID = "DEFAULT_NOISY_NOTIFICATION_CHANNEL_ID" - private const val SILENT_NOTIFICATION_CHANNEL_ID = "DEFAULT_SILENT_NOTIFICATION_CHANNEL_ID_V2" + const val SILENT_NOTIFICATION_CHANNEL_ID = "DEFAULT_SILENT_NOTIFICATION_CHANNEL_ID_V2" private const val CALL_NOTIFICATION_CHANNEL_ID = "CALL_NOTIFICATION_CHANNEL_ID_V2" fun supportNotificationChannels() = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) @@ -540,20 +540,6 @@ class NotificationUtils @Inject constructor( return builder.build() } - /** - * Creates a notification that indicates the application is retrieving location even if it is in background or killed. - */ - fun buildLiveLocationSharingNotification(): Notification { - return NotificationCompat.Builder(context, SILENT_NOTIFICATION_CHANNEL_ID) - .setContentTitle(stringProvider.getString(R.string.live_location_sharing_notification_title)) - .setContentText(stringProvider.getString(R.string.live_location_sharing_notification_description)) - .setSmallIcon(R.drawable.ic_attachment_location_live_white) - .setColor(ThemeUtils.getColor(context, android.R.attr.colorPrimary)) - .setCategory(NotificationCompat.CATEGORY_LOCATION_SHARING) - .setContentIntent(buildOpenHomePendingIntentForSummary()) - .build() - } - /** * Creates a notification that indicates the application is capturing the screen. */