From 5afc614a27eb0e3d37a6ab2f64abde55490b6811 Mon Sep 17 00:00:00 2001
From: AlexisTabin <alexis.tabin@gmail.com>
Date: Thu, 4 Jun 2020 12:37:30 +0200
Subject: [PATCH 1/4] Add mock implementation on MissionProgress

---
 .../data_manager/HeatmapDataManagerTest.kt    |   4 +-
 .../java/ch/epfl/sdp/drone/DroneErrorTest.kt  |  45 +++-----
 .../ch/epfl/sdp/drone/DroneInstanceMock.kt    |  16 ++-
 .../java/ch/epfl/sdp/drone/DroneTest.kt       |  21 +++-
 .../sdp/ui/drone/DroneStatusFragmentTest.kt   |   1 -
 app/src/main/java/ch/epfl/sdp/drone/Drone.kt  | 102 +++++++-----------
 .../java/ch/epfl/sdp/ui/maps/MapActivity.kt   |   5 +-
 .../ui/search_group/edition/UserViewHolder.kt |   1 -
 8 files changed, 82 insertions(+), 113 deletions(-)

diff --git a/app/src/androidTest/java/ch/epfl/sdp/database/data_manager/HeatmapDataManagerTest.kt b/app/src/androidTest/java/ch/epfl/sdp/database/data_manager/HeatmapDataManagerTest.kt
index 4fa5b8bb9..5de1e6088 100644
--- a/app/src/androidTest/java/ch/epfl/sdp/database/data_manager/HeatmapDataManagerTest.kt
+++ b/app/src/androidTest/java/ch/epfl/sdp/database/data_manager/HeatmapDataManagerTest.kt
@@ -40,7 +40,7 @@ class HeatmapDataManagerTest {
         Mockito.`when`(repo.getGroupHeatmaps(expectedGroupId)).thenReturn(MutableLiveData(mutableMapOf()))
 
         HeatmapRepositoryProvider.provide = { repo }
-        HeatmapDataManager().addMeasureToHeatmap(DUMMY_GROUP_ID, DUMMY_HEATMAP_ID, DUMMY_LOCATION, DUMMY_INTENSITY)
+        HeatmapDataManager().addMeasureToHeatmap(DUMMY_GROUP_ID, DUMMY_LOCATION, DUMMY_INTENSITY)
 
         Mockito.verify(repo, Mockito.times(1)).getGroupHeatmaps(expectedGroupId)
         Mockito.verify(repo, Mockito.times(1)).updateHeatmap(expectedGroupId, expectedHeatMapData)
@@ -60,7 +60,7 @@ class HeatmapDataManagerTest {
         Mockito.`when`(repo.getGroupHeatmaps(expectedGroupId)).thenReturn(MutableLiveData(mutableMapOf(Pair(DUMMY_HEATMAP_ID, MutableLiveData(previousHeatMapData)))))
 
         HeatmapRepositoryProvider.provide = { repo }
-        HeatmapDataManager().addMeasureToHeatmap(DUMMY_GROUP_ID, DUMMY_HEATMAP_ID, DUMMY_LOCATION, DUMMY_INTENSITY)
+        HeatmapDataManager().addMeasureToHeatmap(DUMMY_GROUP_ID, DUMMY_LOCATION, DUMMY_INTENSITY)
 
         Mockito.verify(repo, Mockito.times(1)).getGroupHeatmaps(expectedGroupId)
         Mockito.verify(repo, Mockito.times(1)).updateHeatmap(expectedGroupId, expectedHeatMapData)
diff --git a/app/src/androidTest/java/ch/epfl/sdp/drone/DroneErrorTest.kt b/app/src/androidTest/java/ch/epfl/sdp/drone/DroneErrorTest.kt
index 51d5b09ac..b7c582e5d 100644
--- a/app/src/androidTest/java/ch/epfl/sdp/drone/DroneErrorTest.kt
+++ b/app/src/androidTest/java/ch/epfl/sdp/drone/DroneErrorTest.kt
@@ -1,28 +1,16 @@
 package ch.epfl.sdp.drone
 
-import android.content.Intent
-import androidx.test.espresso.Espresso
-import androidx.test.espresso.assertion.ViewAssertions
-import androidx.test.espresso.intent.rule.IntentsTestRule
-import androidx.test.espresso.matcher.RootMatchers
-import androidx.test.espresso.matcher.ViewMatchers
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.internal.runner.junit4.statement.UiThreadStatement.runOnUiThread
-import ch.epfl.sdp.MainApplication
-import ch.epfl.sdp.R
-import ch.epfl.sdp.drone.Drone
-import ch.epfl.sdp.drone.DroneUtils
-import ch.epfl.sdp.ui.MainActivity
 import ch.epfl.sdp.utils.CentralLocationManager
 import com.mapbox.mapboxsdk.geometry.LatLng
 import io.mavsdk.telemetry.Telemetry
 import io.reactivex.Completable
-import org.hamcrest.CoreMatchers
+import io.reactivex.Flowable
 import org.hamcrest.MatcherAssert.assertThat
 import org.hamcrest.Matchers.`is`
 import org.hamcrest.Matchers.nullValue
 import org.junit.Before
-import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.ArgumentMatchers
@@ -34,6 +22,7 @@ class DroneErrorTest {
 
     companion object {
         private const val DEFAULT_ALTITUDE = 10f
+        private const val DUMMY_GROUP_ID = "dummy_group_id"
         val someLocationsList = listOf(
                 LatLng(47.398979, 8.543434),
                 LatLng(47.398279, 8.543934),
@@ -42,12 +31,6 @@ class DroneErrorTest {
         )
     }
 
-    @get:Rule
-    val mActivityRule = IntentsTestRule(
-            MainActivity::class.java,
-            true,
-            false)
-
     @Before
     fun before() {
         DroneInstanceMock.setupDefaultMocks()
@@ -64,12 +47,14 @@ class DroneErrorTest {
                 .thenReturn(Completable.error(Throwable("Error StartMission")))
         `when`(DroneInstanceMock.droneMission.clearMission())
                 .thenReturn(Completable.error(Throwable("Error Clear Mission")))
+        `when`(DroneInstanceMock.droneMission.missionProgress)
+                .thenReturn(Flowable.empty())
     }
 
     @Test
     fun failToStartMissionResetMission() {
         runOnUiThread {
-            Drone.startMission(DroneUtils.makeDroneMission(someLocationsList, DEFAULT_ALTITUDE))
+            Drone.startMission(DroneUtils.makeDroneMission(someLocationsList, DEFAULT_ALTITUDE), DUMMY_GROUP_ID)
         }
 
         assertThat(Drone.isMissionPausedLiveData.value, `is`(true))
@@ -91,7 +76,7 @@ class DroneErrorTest {
     }
 
     @Test
-    fun failToRestartMissionResetsMissionStatus() {
+    fun failToResumeMissionResetsMissionStatus() {
         runOnUiThread {
             Drone.isFlyingLiveData.value = true
             Drone.isMissionPausedLiveData.value = true
@@ -113,12 +98,7 @@ class DroneErrorTest {
     }
 
     @Test
-    fun failToReturnToUserShowsToast() {
-        runOnUiThread{
-            CentralLocationManager.currentUserPosition.value = LatLng(0.0, 0.0)
-        }
-        mActivityRule.launchActivity(Intent())
-
+    fun failToReturnToUserResetMission() {
         Mockito.reset(DroneInstanceMock.droneAction)
 
         //Action mocks
@@ -135,11 +115,10 @@ class DroneErrorTest {
         `when`(DroneInstanceMock.droneAction.land())
                 .thenReturn(Completable.complete())
 
-        Drone.returnToUserLocationAndLand()
-
-        // Test that the toast is displayed
-        Espresso.onView(ViewMatchers.withText(MainApplication.applicationContext().getString(R.string.drone_user_error)))
-                .inRoot(RootMatchers.withDecorView(CoreMatchers.not(mActivityRule.activity.window.decorView)))
-                .check(ViewAssertions.matches(ViewMatchers.isDisplayed()))
+        runOnUiThread {
+            CentralLocationManager.currentUserPosition.value = LatLng(0.0, 0.0)
+            Drone.returnToUserLocationAndLand()
+        }
+        assertThat(Drone.missionLiveData.value, `is`(nullValue()))
     }
 }
\ No newline at end of file
diff --git a/app/src/androidTest/java/ch/epfl/sdp/drone/DroneInstanceMock.kt b/app/src/androidTest/java/ch/epfl/sdp/drone/DroneInstanceMock.kt
index ced0a41d5..bceea4bf1 100644
--- a/app/src/androidTest/java/ch/epfl/sdp/drone/DroneInstanceMock.kt
+++ b/app/src/androidTest/java/ch/epfl/sdp/drone/DroneInstanceMock.kt
@@ -41,7 +41,8 @@ object DroneInstanceMock {
                 .thenReturn(Flowable.fromArray(
                         Telemetry.FlightMode.LAND,
                         Telemetry.FlightMode.MISSION,
-                        Telemetry.FlightMode.HOLD
+                        Telemetry.FlightMode.HOLD,
+                        Telemetry.FlightMode.MISSION
                 ))
         `when`(droneTelemetry.armed)
                 .thenReturn(Flowable.fromArray(
@@ -49,7 +50,10 @@ object DroneInstanceMock {
                 ))
         `when`(droneTelemetry.position)
                 .thenReturn(Flowable.fromArray(
-                        Telemetry.Position(0.0, 0.0, 0.0f, 0.0f)
+                        Telemetry.Position(0.0, 0.0, 0.0f, 0.0f),
+                        Telemetry.Position(0.1, 0.0, 0.0f, 0.0f),
+                        Telemetry.Position(0.2, 0.0, 0.0f, 0.0f),
+                        Telemetry.Position(0.3, 0.0, 0.0f, 0.0f)
                 ))
         `when`(droneTelemetry.battery)
                 .thenReturn(Flowable.fromArray(
@@ -89,7 +93,13 @@ object DroneInstanceMock {
         `when`(droneMission.clearMission())
                 .thenReturn(Completable.complete())
         `when`(droneMission.missionProgress)
-                .thenReturn(Flowable.empty())
+                .thenReturn(Flowable.fromArray(
+                        Mission.MissionProgress(0, 4),
+                        Mission.MissionProgress(1, 4),
+                        Mission.MissionProgress(2, 4),
+                        Mission.MissionProgress(3, 4),
+                        Mission.MissionProgress(4, 4)
+                ))
 
         //Action mocks
         `when`(droneAction.arm())
diff --git a/app/src/androidTest/java/ch/epfl/sdp/drone/DroneTest.kt b/app/src/androidTest/java/ch/epfl/sdp/drone/DroneTest.kt
index 0732e66fe..860bb4e37 100644
--- a/app/src/androidTest/java/ch/epfl/sdp/drone/DroneTest.kt
+++ b/app/src/androidTest/java/ch/epfl/sdp/drone/DroneTest.kt
@@ -1,26 +1,37 @@
 package ch.epfl.sdp.drone
 
+import android.util.Log
 import androidx.arch.core.executor.testing.InstantTaskExecutorRule
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import ch.epfl.sdp.database.data_manager.MainDataManager
 import ch.epfl.sdp.utils.CentralLocationManager
 import com.mapbox.mapboxsdk.geometry.LatLng
 import io.mavsdk.telemetry.Telemetry
+import io.reactivex.Flowable
 import org.hamcrest.MatcherAssert.assertThat
 import org.hamcrest.Matchers.*
 import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
+import org.mockito.Mockito
 
 
 @RunWith(AndroidJUnit4::class)
 class DroneTest {
 
+    private fun <T> any(): T {
+        Mockito.any<T>()
+        return uninitialized()
+    }
+
+    private fun <T> uninitialized(): T = null as T
+
     companion object {
         const val SIGNAL_STRENGTH = 1.0
         private const val EPSILON = 1e-5
         private const val DEFAULT_ALTITUDE = 10f
+        private const val DUMMY_GROUP_ID = "dummy_group_id"
         val someLocationsList = listOf(
                 LatLng(47.398979, 8.543434),
                 LatLng(47.398279, 8.543934),
@@ -46,13 +57,13 @@ class DroneTest {
     }
 
     @Test
-    fun missionTestDoesNotCrash() {
+    fun startMissionUpdatesLiveData() {
         Drone.missionLiveData.value = null
         assertThat(Drone.missionLiveData.value, `is`(nullValue()))
 
-        Drone.startMission(DroneUtils.makeDroneMission(someLocationsList, DEFAULT_ALTITUDE))
+        Drone.startMission(DroneUtils.makeDroneMission(someLocationsList, DEFAULT_ALTITUDE), DUMMY_GROUP_ID)
 
-        // This assert prevent the app to crash in cash the mission has not been updated
+        // This assert prevent the app to crase in cash the mission has not been updated
         assertThat(Drone.missionLiveData.value, `is`(notNullValue()))
         assertThat(Drone.missionLiveData.value?.isEmpty(), `is`(false))
     }
@@ -64,7 +75,7 @@ class DroneTest {
         Drone.positionLiveData.value = expectedLatLng
         Drone.homeLocationLiveData.value =
                 Telemetry.Position(expectedLatLng.latitude, expectedLatLng.longitude, 400f, 50f)
-        Drone.startMission(DroneUtils.makeDroneMission(someLocationsList, DEFAULT_ALTITUDE))
+        Drone.startMission(DroneUtils.makeDroneMission(someLocationsList, DEFAULT_ALTITUDE), DUMMY_GROUP_ID)
 
         Drone.returnToHomeLocationAndLand()
 
@@ -87,7 +98,7 @@ class DroneTest {
         val expectedLatLng = LatLng(47.297428, 8.445369) //Position near the takeoff
         CentralLocationManager.currentUserPosition.value = expectedLatLng
 
-        Drone.startMission(DroneUtils.makeDroneMission(someLocationsList, DEFAULT_ALTITUDE))
+        Drone.startMission(DroneUtils.makeDroneMission(someLocationsList, DEFAULT_ALTITUDE), DUMMY_GROUP_ID)
 
         assertThat(CentralLocationManager.currentUserPosition.value, `is`(notNullValue()))
         Drone.returnToUserLocationAndLand()
diff --git a/app/src/androidTest/java/ch/epfl/sdp/ui/drone/DroneStatusFragmentTest.kt b/app/src/androidTest/java/ch/epfl/sdp/ui/drone/DroneStatusFragmentTest.kt
index cfb0fb0ce..3c03850cc 100644
--- a/app/src/androidTest/java/ch/epfl/sdp/ui/drone/DroneStatusFragmentTest.kt
+++ b/app/src/androidTest/java/ch/epfl/sdp/ui/drone/DroneStatusFragmentTest.kt
@@ -48,7 +48,6 @@ class DroneStatusFragmentTest {
         private const val DEFAULT_ALTITUDE_DISPLAY = " 0.0 m"
         private const val FAKE_ACCOUNT_ID = "fake_account_id"
         private const val DUMMY_GROUP_ID = "DummyGroupId"
-        private const val MAP_LOADING_TIMEOUT = 1000L
     }
 
     private lateinit var preferencesEditor: SharedPreferences.Editor
diff --git a/app/src/main/java/ch/epfl/sdp/drone/Drone.kt b/app/src/main/java/ch/epfl/sdp/drone/Drone.kt
index 19bd6f2ea..621105b79 100644
--- a/app/src/main/java/ch/epfl/sdp/drone/Drone.kt
+++ b/app/src/main/java/ch/epfl/sdp/drone/Drone.kt
@@ -25,6 +25,11 @@ import kotlin.math.roundToInt
 import kotlin.math.sqrt
 
 object Drone {
+    // Maximum distance between passes in the strategy
+    const val GROUND_SENSOR_SCOPE: Double = 15.0
+    const val DEFAULT_ALTITUDE: Float = 10.0F
+    const val MAX_DISTANCE_BETWEEN_POINTS_IN_AREA = 1000 //meters
+
     private const val WAIT_TIME_S: Long = 1
 
     private val heatmapDataManager = HeatmapDataManager()
@@ -44,7 +49,7 @@ object Drone {
 
     /*Will be useful later on*/
     val debugGetSignalStrength: () -> Double = {
-        positionLiveData.value!!.distanceTo(LatLng(47.3975, 8.5445))
+        positionLiveData.value!!.distanceTo(LatLng(46.303407, 7.528529))
     }
 
     private val instance: System = DroneInstanceProvider.provide()
@@ -55,6 +60,7 @@ object Drone {
         disposables.add(instance.telemetry.flightMode.distinctUntilChanged()
                 .subscribe(
                         { flightMode ->
+                            Log.d("DEBUG22", "fm : " + flightMode)
                             if (flightMode == Telemetry.FlightMode.HOLD) isMissionPausedLiveData.postValue(true)
                             if (flightMode == Telemetry.FlightMode.MISSION) isMissionPausedLiveData.postValue(false)
                         },
@@ -115,30 +121,10 @@ object Drone {
      * @param missionPlan : the MissionPlan the drone will follow
      */
     fun startMission(missionPlan: Mission.MissionPlan, groupId: String) {
-        Timber.w("startMission Drone")
-        this.missionLiveData.value = missionPlan.missionItems
-
-        val isConnectedCompletable = instance.core.connectionState
-                .filter { state -> state.isConnected }
-                .firstOrError()
-                .toCompletable()
-
         val missionCallBack = { location: LatLng, signalStrength: Double ->
-            Log.w("DRONE", "Mission Callback")
             heatmapDataManager.addMeasureToHeatmap(groupId, location, signalStrength)
         }
 
-        disposables.add(isConnectedCompletable
-                .andThen(instance.mission.setReturnToLaunchAfterMission(true))
-                .andThen(instance.mission.uploadMission(missionPlan))
-                .andThen(instance.action.arm())
-                .andThen {
-                    onMeasureTakenCallbacks.add(missionCallBack)
-                    Timber.w("Add callback for measure !")
-                }
-                .andThen(instance.mission.startMission())
-                .subscribe())
-
         disposables.add(
                 getConnectedInstance()
                         .andThen(instance.mission.setReturnToLaunchAfterMission(true))
@@ -146,30 +132,39 @@ object Drone {
                         .andThen(instance.action.arm())
                         .andThen {
                             onMeasureTakenCallbacks.add(missionCallBack)
-                            Log.w("DRONE", "Add callback")
                             it.onComplete()
                         }
                         .andThen(instance.mission.startMission())
                         .subscribe(
-                                { ToastHandler().showToast(R.string.drone_mission_success, Toast.LENGTH_SHORT) },
+                                {
+                                    this.missionLiveData.postValue(missionPlan.missionItems)
+                                    this.isMissionPausedLiveData.postValue(false)
+                                    ToastHandler().showToast(R.string.drone_mission_success, Toast.LENGTH_SHORT)
+                                    takeMeasure(missionCallBack)
+                                },
                                 { ToastHandler().showToast(R.string.drone_mission_error, Toast.LENGTH_SHORT) }
                         )
         )
+        // TODO("See what to do with added disposables")
+    }
 
-        disposables.add(instance.mission.missionProgress.subscribe { missionProgress ->
-            if (missionProgress.current == missionProgress.total) {
-                Log.w("DRONE", "Remove callback")
-                onMeasureTakenCallbacks.remove(missionCallBack)
-            }
-            Log.w("DRONE", "Mission progress  YEAH !")
-            val missionItem = missionLiveData.value?.getOrNull(missionProgress.current - 1)
-            val location = missionItem?.longitudeDeg?.let { it1 -> LatLng(missionItem.latitudeDeg, it1) }
-            val signal = getSignalStrength()
-            Log.w("DRONE", "Signal strength $signal")
-            Log.w("DRONE", "Location $location")
-            location?.let { it1 -> onMeasureTaken(it1, signal) }
-        })
-        //TODO See what to do with disposables added
+    private fun takeMeasure(missionCallBack : (LatLng, Double) -> Unit){
+        disposables.add(
+                getConnectedInstance()
+                        .andThen(instance.mission.missionProgress)
+                        .subscribe(
+                                { missionProgress ->
+                                    if (missionProgress.current == missionProgress.total) {
+                                        onMeasureTakenCallbacks.remove(missionCallBack)
+                                    }
+                                    val missionItem = missionLiveData.value?.getOrNull(missionProgress.current - 1)
+                                    val location = missionItem?.longitudeDeg?.let { it1 -> LatLng(missionItem.latitudeDeg, it1) }
+                                    val signal = getSignalStrength()
+                                    location?.let { it1 -> onMeasureTaken(it1, signal) }
+                                },
+                                {}
+                        )
+        )
     }
 
     private fun onMeasureTaken(location: LatLng, signalStrength: Double) {
@@ -215,25 +210,7 @@ object Drone {
                             ToastHandler().showToast(R.string.drone_mission_error, Toast.LENGTH_SHORT)
                         }
                 )
-<<<<<<< HEAD
         )
-=======
-    }
-
-    /**
-     * If the drone is not flying, it starts a mission with
-     * @param missionPlan
-     *
-     * If the drone is already flying, but paused, it restarts it
-     * If the drone is already flying and doing a mission, it pauses the mission
-     */
-    fun startOrPauseMission(missionPlan: Mission.MissionPlan, groupId: String) {
-        if (this.isFlyingLiveData.value!!) {
-            disposables.add(if (this.isMissionPausedLiveData.value!!) restartMission() else pauseMission())
-        } else {
-            startMission(missionPlan, groupId)
-        }
->>>>>>> 54705bc3... Fix issues when new heatmps are added or removed and nothing change on screen
     }
 
     /**
@@ -259,15 +236,12 @@ object Drone {
                         .andThen(instance.action.returnToLaunch())
                         .subscribe(
                                 {
-                                    this.missionLiveData.value = listOf(DroneUtils.generateMissionItem(returnLocation.latitude, returnLocation.longitude, returnLocation.altitude.toFloat()))
+                                    this.missionLiveData.postValue(listOf(DroneUtils.generateMissionItem(returnLocation.latitude, returnLocation.longitude, returnLocation.altitude.toFloat())))
                                     ToastHandler().showToast(R.string.drone_home_success, Toast.LENGTH_SHORT)
                                 },
                                 {
+                                    this.missionLiveData.postValue(null)
                                     ToastHandler().showToast(R.string.drone_home_error, Toast.LENGTH_SHORT)
-<<<<<<< HEAD
-=======
-                                    this.missionLiveData.value = null
->>>>>>> 54705bc3... Fix issues when new heatmps are added or removed and nothing change on screen
                                 }
                         )
         )
@@ -286,18 +260,14 @@ object Drone {
                         .andThen(instance.mission.clearMission())
                         .andThen(instance.action.gotoLocation(returnLocation.latitude, returnLocation.longitude, 20.0F, 0F))
                         .subscribe(
-<<<<<<< HEAD
                                 {
-                                    this.missionLiveData.value = listOf(DroneUtils.generateMissionItem(returnLocation.latitude, returnLocation.longitude, returnLocation.altitude.toFloat()))
+                                    this.missionLiveData.postValue(listOf(DroneUtils.generateMissionItem(returnLocation.latitude, returnLocation.longitude, returnLocation.altitude.toFloat())))
                                     ToastHandler().showToast(R.string.drone_user_success, Toast.LENGTH_SHORT)
                                 },
                                 {
+                                    this.missionLiveData.postValue(null)
                                     ToastHandler().showToast(R.string.drone_user_error, Toast.LENGTH_SHORT)
                                 }
-=======
-                                { ToastHandler().showToast(R.string.drone_user_success, Toast.LENGTH_SHORT) },
-                                { ToastHandler().showToast(R.string.drone_user_error, Toast.LENGTH_SHORT) }
->>>>>>> 54705bc3... Fix issues when new heatmps are added or removed and nothing change on screen
                         )
         )
 
diff --git a/app/src/main/java/ch/epfl/sdp/ui/maps/MapActivity.kt b/app/src/main/java/ch/epfl/sdp/ui/maps/MapActivity.kt
index 7cd824af4..86b80f7ce 100644
--- a/app/src/main/java/ch/epfl/sdp/ui/maps/MapActivity.kt
+++ b/app/src/main/java/ch/epfl/sdp/ui/maps/MapActivity.kt
@@ -16,6 +16,7 @@ import ch.epfl.sdp.R
 import ch.epfl.sdp.database.data.Role
 import ch.epfl.sdp.database.data_manager.HeatmapDataManager
 import ch.epfl.sdp.database.data_manager.MainDataManager
+import ch.epfl.sdp.database.data_manager.MainDataManager.groupId
 import ch.epfl.sdp.database.data_manager.MarkerDataManager
 import ch.epfl.sdp.drone.Drone
 import ch.epfl.sdp.drone.DroneUtils
@@ -272,7 +273,7 @@ class MapActivity : MapViewBaseActivity(), OnMapReadyCallback, MapboxMap.OnMapLo
      */
     fun addPointToHeatMap(location: LatLng, intensity: Double) {
         if (isMapReady) {
-            heatmapManager.addMeasureToHeatmap(groupId, location, intensity)
+            heatmapManager.addMeasureToHeatmap(groupId.value!!, location, intensity)
         }
     }
 
@@ -317,7 +318,7 @@ class MapActivity : MapViewBaseActivity(), OnMapReadyCallback, MapboxMap.OnMapLo
     fun launchMission() {
         val altitude = PreferenceManager.getDefaultSharedPreferences(this)
                 .getString(this.getString(R.string.pref_key_drone_altitude), Drone.DEFAULT_ALTITUDE.toString()).toString().toFloat()
-        Drone.startMission(DroneUtils.makeDroneMission(missionBuilder.build(), altitude), groupId)
+        Drone.startMission(DroneUtils.makeDroneMission(missionBuilder.build(), altitude), groupId.value!!)
         searchAreaBuilder.reset()
     }
 
diff --git a/app/src/main/java/ch/epfl/sdp/ui/search_group/edition/UserViewHolder.kt b/app/src/main/java/ch/epfl/sdp/ui/search_group/edition/UserViewHolder.kt
index d03de901f..c66b17d5d 100644
--- a/app/src/main/java/ch/epfl/sdp/ui/search_group/edition/UserViewHolder.kt
+++ b/app/src/main/java/ch/epfl/sdp/ui/search_group/edition/UserViewHolder.kt
@@ -18,6 +18,5 @@ class UserViewHolder(inflater: LayoutInflater, parent: ViewGroup) :
         //TODO change this to username
         name.text = user.email
         removeUserButton.setOnClickListener { onRemoveListener.onItemClicked(user) }
-
     }
 }
\ No newline at end of file

From 13f054c533fadd7d70d4089c4945769dcac072a5 Mon Sep 17 00:00:00 2001
From: Bastien Wermeille <5320541+Ph0tonic@users.noreply.github.com>
Date: Fri, 5 Jun 2020 14:37:19 +0200
Subject: [PATCH 2/4] Small demo modifs

---
 .../epfl/sdp/database/data_manager/MainDataManager.kt  |  4 ++++
 app/src/main/java/ch/epfl/sdp/drone/Drone.kt           |  9 ++++++---
 .../main/java/ch/epfl/sdp/map/MapboxHeatmapPainter.kt  | 10 +++++-----
 app/src/main/java/ch/epfl/sdp/ui/camera/VlcFragment.kt |  3 ++-
 app/src/main/java/ch/epfl/sdp/ui/maps/MapActivity.kt   |  2 +-
 5 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/app/src/main/java/ch/epfl/sdp/database/data_manager/MainDataManager.kt b/app/src/main/java/ch/epfl/sdp/database/data_manager/MainDataManager.kt
index 15de4e497..ae2e80da8 100644
--- a/app/src/main/java/ch/epfl/sdp/database/data_manager/MainDataManager.kt
+++ b/app/src/main/java/ch/epfl/sdp/database/data_manager/MainDataManager.kt
@@ -10,6 +10,7 @@ import ch.epfl.sdp.database.dao.OfflineMarkerDao
 import ch.epfl.sdp.database.data.Role
 import ch.epfl.sdp.database.repository.HeatmapRepository
 import ch.epfl.sdp.database.repository.MarkerRepository
+import ch.epfl.sdp.utils.Auth
 
 object MainDataManager {
 
@@ -50,6 +51,9 @@ object MainDataManager {
             cachedUserIdWhileOffline = groupId.value
             cachedUserRoleWhileOffline = role.value!!
         }
+        if (Auth.accountId.value == null) {
+            Auth.accountId.value = OFFLINE_MODE_USER_ID
+        }
         groupId.value = OFFLINE_MODE_USER_ID
         role.value = Role.OPERATOR
         offlineMode = true
diff --git a/app/src/main/java/ch/epfl/sdp/drone/Drone.kt b/app/src/main/java/ch/epfl/sdp/drone/Drone.kt
index 621105b79..ed28df0ae 100644
--- a/app/src/main/java/ch/epfl/sdp/drone/Drone.kt
+++ b/app/src/main/java/ch/epfl/sdp/drone/Drone.kt
@@ -26,7 +26,7 @@ import kotlin.math.sqrt
 
 object Drone {
     // Maximum distance between passes in the strategy
-    const val GROUND_SENSOR_SCOPE: Double = 15.0
+    const val GROUND_SENSOR_SCOPE: Double = 5.0
     const val DEFAULT_ALTITUDE: Float = 10.0F
     const val MAX_DISTANCE_BETWEEN_POINTS_IN_AREA = 1000 //meters
 
@@ -49,7 +49,8 @@ object Drone {
 
     /*Will be useful later on*/
     val debugGetSignalStrength: () -> Double = {
-        positionLiveData.value!!.distanceTo(LatLng(46.303407, 7.528529))
+//        1000 / positionLiveData.value!!.distanceTo(LatLng(46.303407, 7.528529)).pow(2)
+        1000 / positionLiveData.value!!.distanceTo(LatLng(47.303584, 7.159724)).pow(2)
     }
 
     private val instance: System = DroneInstanceProvider.provide()
@@ -148,7 +149,7 @@ object Drone {
         // TODO("See what to do with added disposables")
     }
 
-    private fun takeMeasure(missionCallBack : (LatLng, Double) -> Unit){
+    private fun takeMeasure(missionCallBack: (LatLng, Double) -> Unit) {
         disposables.add(
                 getConnectedInstance()
                         .andThen(instance.mission.missionProgress)
@@ -170,7 +171,9 @@ object Drone {
     private fun onMeasureTaken(location: LatLng, signalStrength: Double) {
         GlobalScope.launch {
             withContext(Dispatchers.Main) {
+                Log.w("DRONE", "$signalStrength")
                 onMeasureTakenCallbacks.forEach {
+                    Log.w("DRONE", "CALL")
                     it(location, signalStrength)
                 }
             }
diff --git a/app/src/main/java/ch/epfl/sdp/map/MapboxHeatmapPainter.kt b/app/src/main/java/ch/epfl/sdp/map/MapboxHeatmapPainter.kt
index f55247738..f69756480 100644
--- a/app/src/main/java/ch/epfl/sdp/map/MapboxHeatmapPainter.kt
+++ b/app/src/main/java/ch/epfl/sdp/map/MapboxHeatmapPainter.kt
@@ -30,11 +30,11 @@ class MapboxHeatmapPainter(val style: Style,
             unclustered.setProperties(
                     PropertyFactory.circleColor(
                             Expression.interpolate(Expression.linear(), Expression.get("intensity"),
-                                    Expression.stop(8, BLUE),
-                                    Expression.stop(8.5, CYAN),
-                                    Expression.stop(9, GREEN),
-                                    Expression.stop(9.5, ORANGE),
-                                    Expression.stop(10.0, RED)
+                                    Expression.stop(1, BLUE),
+                                    Expression.stop(3, CYAN),
+                                    Expression.stop(5, GREEN),
+                                    Expression.stop(7, ORANGE),
+                                    Expression.stop(9, RED)
                             )
                     ),
                     PropertyFactory.circleRadius(25f),
diff --git a/app/src/main/java/ch/epfl/sdp/ui/camera/VlcFragment.kt b/app/src/main/java/ch/epfl/sdp/ui/camera/VlcFragment.kt
index 943692ee8..99f995a86 100644
--- a/app/src/main/java/ch/epfl/sdp/ui/camera/VlcFragment.kt
+++ b/app/src/main/java/ch/epfl/sdp/ui/camera/VlcFragment.kt
@@ -19,7 +19,7 @@ class VlcFragment : Fragment() {
     companion object {
         private const val USE_TEXTURE_VIEW = false
         private const val ENABLE_SUBTITLES = false
-        private const val RTSP_SOURCE = "rtsp://192.168.1.131:8554/live" //must be your IP
+        private const val RTSP_SOURCE = "rtsp://192.168.1.120:8554/live" //must be your IP
         private val libvlcArguments = arrayListOf("-vvv")//, "--live-caching=200")
     }
 
@@ -49,6 +49,7 @@ class VlcFragment : Fragment() {
     override fun onStart() {
         super.onStart()
         mMediaPlayer.attachViews(mVideoLayout, null, ENABLE_SUBTITLES, USE_TEXTURE_VIEW)
+        startVideo()
     }
 
     fun switchVideo(v: View) {
diff --git a/app/src/main/java/ch/epfl/sdp/ui/maps/MapActivity.kt b/app/src/main/java/ch/epfl/sdp/ui/maps/MapActivity.kt
index 86b80f7ce..f824325cb 100644
--- a/app/src/main/java/ch/epfl/sdp/ui/maps/MapActivity.kt
+++ b/app/src/main/java/ch/epfl/sdp/ui/maps/MapActivity.kt
@@ -112,7 +112,7 @@ class MapActivity : MapViewBaseActivity(), OnMapReadyCallback, MapboxMap.OnMapLo
 
     private var droneConnectionStatusObserver = Observer<Boolean> {
         if (!it) {
-            Toast.makeText(this, getString(R.string.not_connected_message), Toast.LENGTH_SHORT).show()
+//            Toast.makeText(this, getString(R.string.not_connected_message), Toast.LENGTH_SHORT).show()
         }
         startOrPauseButton.isEnabled = it
         returnHomeOrUserButton.isEnabled = it

From 062ed28eda1f55f152f9a7fec4bf76ba2a15ad50 Mon Sep 17 00:00:00 2001
From: Bastien Wermeille <5320541+Ph0tonic@users.noreply.github.com>
Date: Fri, 5 Jun 2020 16:31:19 +0200
Subject: [PATCH 3/4] Fix issue with mission progress tracking

---
 app/src/main/java/ch/epfl/sdp/drone/Drone.kt | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/app/src/main/java/ch/epfl/sdp/drone/Drone.kt b/app/src/main/java/ch/epfl/sdp/drone/Drone.kt
index ed28df0ae..f486a2ad7 100644
--- a/app/src/main/java/ch/epfl/sdp/drone/Drone.kt
+++ b/app/src/main/java/ch/epfl/sdp/drone/Drone.kt
@@ -26,7 +26,7 @@ import kotlin.math.sqrt
 
 object Drone {
     // Maximum distance between passes in the strategy
-    const val GROUND_SENSOR_SCOPE: Double = 5.0
+    const val GROUND_SENSOR_SCOPE: Double = 7.5
     const val DEFAULT_ALTITUDE: Float = 10.0F
     const val MAX_DISTANCE_BETWEEN_POINTS_IN_AREA = 1000 //meters
 
@@ -50,7 +50,7 @@ object Drone {
     /*Will be useful later on*/
     val debugGetSignalStrength: () -> Double = {
 //        1000 / positionLiveData.value!!.distanceTo(LatLng(46.303407, 7.528529)).pow(2)
-        1000 / positionLiveData.value!!.distanceTo(LatLng(47.303584, 7.159724)).pow(2)
+        1000 / positionLiveData.value!!.distanceTo(LatLng(47.301836, 7.156145)).pow(2)
     }
 
     private val instance: System = DroneInstanceProvider.provide()
@@ -116,6 +116,7 @@ object Drone {
                         { error -> Timber.e("Error connectionState : $error") }
                 )
         )
+        setupMeasureTracking()
     }
 
     /**
@@ -141,27 +142,29 @@ object Drone {
                                     this.missionLiveData.postValue(missionPlan.missionItems)
                                     this.isMissionPausedLiveData.postValue(false)
                                     ToastHandler().showToast(R.string.drone_mission_success, Toast.LENGTH_SHORT)
-                                    takeMeasure(missionCallBack)
                                 },
-                                { ToastHandler().showToast(R.string.drone_mission_error, Toast.LENGTH_SHORT) }
+                                {
+                                    ToastHandler().showToast(R.string.drone_mission_error, Toast.LENGTH_SHORT)
+                                    onMeasureTakenCallbacks.clear()
+                                }
                         )
         )
         // TODO("See what to do with added disposables")
     }
 
-    private fun takeMeasure(missionCallBack: (LatLng, Double) -> Unit) {
+    private fun setupMeasureTracking() {
         disposables.add(
                 getConnectedInstance()
                         .andThen(instance.mission.missionProgress)
                         .subscribe(
                                 { missionProgress ->
-                                    if (missionProgress.current == missionProgress.total) {
-                                        onMeasureTakenCallbacks.remove(missionCallBack)
-                                    }
                                     val missionItem = missionLiveData.value?.getOrNull(missionProgress.current - 1)
                                     val location = missionItem?.longitudeDeg?.let { it1 -> LatLng(missionItem.latitudeDeg, it1) }
                                     val signal = getSignalStrength()
                                     location?.let { it1 -> onMeasureTaken(it1, signal) }
+                                    if (missionProgress.current == missionProgress.total) {
+                                        onMeasureTakenCallbacks.clear()
+                                    }
                                 },
                                 {}
                         )

From 761d6d47bb76f679f7a07df62eeb817717e2ebee Mon Sep 17 00:00:00 2001
From: Bastien Wermeille <5320541+Ph0tonic@users.noreply.github.com>
Date: Fri, 5 Jun 2020 16:40:08 +0200
Subject: [PATCH 4/4] Uncomment toast

---
 app/src/main/java/ch/epfl/sdp/ui/maps/MapActivity.kt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/src/main/java/ch/epfl/sdp/ui/maps/MapActivity.kt b/app/src/main/java/ch/epfl/sdp/ui/maps/MapActivity.kt
index 655b72a2f..c7340c919 100644
--- a/app/src/main/java/ch/epfl/sdp/ui/maps/MapActivity.kt
+++ b/app/src/main/java/ch/epfl/sdp/ui/maps/MapActivity.kt
@@ -111,7 +111,7 @@ class MapActivity : MapViewBaseActivity(), OnMapReadyCallback, MapboxMap.OnMapLo
 
     private var droneConnectionStatusObserver = Observer<Boolean> {
         if (!it) {
-//            Toast.makeText(this, getString(R.string.not_connected_message), Toast.LENGTH_SHORT).show()
+            Toast.makeText(this, getString(R.string.not_connected_message), Toast.LENGTH_SHORT).show()
         }
         startOrPauseButton.isEnabled = it
         returnHomeOrUserButton.isEnabled = it