Skip to content

Commit

Permalink
added single journey in multiple groups
Browse files Browse the repository at this point in the history
  • Loading branch information
cp-sneh-s committed Jan 20, 2025
1 parent f7ed458 commit 77c1250
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 60 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import com.canopas.yourspace.data.service.auth.AuthService
import com.canopas.yourspace.data.service.location.ApiJourneyService
import com.canopas.yourspace.data.service.location.ApiLocationService
import com.canopas.yourspace.data.service.location.LocationManager
import com.canopas.yourspace.data.storage.UserPreferences
import com.google.android.gms.location.LocationResult
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.CoroutineScope
Expand Down Expand Up @@ -37,6 +38,9 @@ class LocationUpdateReceiver : BroadcastReceiver() {
@Inject
lateinit var journeyRepository: JourneyRepository

@Inject
lateinit var userPreferences: UserPreferences

private val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO)

override fun onReceive(context: Context, intent: Intent) {
Expand All @@ -52,7 +56,7 @@ class LocationUpdateReceiver : BroadcastReceiver() {
extractedLocation.longitude,
System.currentTimeMillis()
)
journeyRepository.saveLocationJourney(extractedLocation, userId)
journeyRepository.saveLocationJourney(extractedLocation, userId, userPreferences)
}
} catch (e: Exception) {
Timber.e(e, "Error while saving location")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import com.canopas.yourspace.data.models.location.isSteady
import com.canopas.yourspace.data.models.location.toLocationFromMovingJourney
import com.canopas.yourspace.data.models.location.toLocationFromSteadyJourney
import com.canopas.yourspace.data.models.location.toRoute
import timber.log.Timber
import java.util.Calendar
import kotlin.math.sqrt

Expand All @@ -33,6 +34,7 @@ fun getJourney(
): JourneyResult? {
// 1. If there is no previous journey, create a new STEADY journey
if (lastKnownJourney == null) {
Timber.tag("XXX").e("No previous journey")
val newSteadyJourney = LocationJourney(
user_id = userId,
from_latitude = newLocation.latitude,
Expand All @@ -54,12 +56,14 @@ fun getJourney(
// 3. Determine how far the newLocation is from our reference point
val distance = if (lastKnownJourney.isSteady()) {
// Compare newLocation with "from" location
Timber.tag("xxx").e("LastKnownJourney = isSteady")
distanceBetween(
geometricMedian ?: newLocation,
lastKnownJourney.toLocationFromSteadyJourney()
)
} else {
// Compare newLocation with "to" location
Timber.tag("xxx").e("LastKnownJourney = isMoving")
distanceBetween(
geometricMedian ?: newLocation,
lastKnownJourney.toLocationFromMovingJourney()
Expand Down Expand Up @@ -102,6 +106,7 @@ fun getJourney(
// If distance > MIN_DISTANCE => user started moving
if (distance > MIN_DISTANCE) {
// 1. Update last STEADY journey with new "from" lat/lng
Timber.tag("xxx").e("lastKnownJourney = isSteady && Distance > MIN_DISTANCE")
val updatedJourney = lastKnownJourney.copy(
from_latitude = newLocation.latitude,
from_longitude = newLocation.longitude,
Expand Down Expand Up @@ -139,6 +144,7 @@ fun getJourney(
// If the user likely stopped moving => (timeDifference > MIN_TIME_DIFFERENCE)
if (timeDifference > MIN_TIME_DIFFERENCE) {
// 1. Update last moving journey
Timber.tag("xxx").e("timeDifference > MIN_TIME_DIFFERENCE")
val updatedJourney = lastKnownJourney.copy(
to_latitude = newLocation.latitude,
to_longitude = newLocation.longitude,
Expand All @@ -157,10 +163,12 @@ fun getJourney(
updated_at = System.currentTimeMillis(),
type = JourneyType.STEADY
)
Timber.e("XXX newSteadyJourney = $newSteadyJourney")
return JourneyResult(updatedJourney, newSteadyJourney)
}
// If user is still moving => distance > MIN_DISTANCE_FOR_MOVING, timeDifference > MIN_UPDATE_INTERVAL_MINUTE => update route
else if (distance > MIN_DISTANCE_FOR_MOVING && timeDifference > MIN_UPDATE_INTERVAL_MINUTE) {
Timber.e("XXX distance > MIN_DISTANCE_FOR_MOVING && timeDifference > MIN_UPDATE_INTERVAL_MINUTE")
val updatedJourney = lastKnownJourney.copy(
to_latitude = newLocation.latitude,
to_longitude = newLocation.longitude,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.location.Location
import com.canopas.yourspace.data.models.location.LocationJourney
import com.canopas.yourspace.data.service.location.ApiJourneyService
import com.canopas.yourspace.data.storage.LocationCache
import com.canopas.yourspace.data.storage.UserPreferences
import timber.log.Timber
import javax.inject.Inject
import javax.inject.Singleton
Expand All @@ -15,34 +16,40 @@ class JourneyRepository @Inject constructor(
) {
suspend fun saveLocationJourney(
extractedLocation: Location,
userId: String
userId: String,
userPreferences: UserPreferences
) {
try {
cacheLocations(extractedLocation, userId)

val lastKnownJourney = getLastKnownLocation(userId)

val result = getJourney(
userId = userId,
newLocation = extractedLocation,
lastKnownJourney = lastKnownJourney,
lastLocations = locationCache.getLastFiveLocations(userId) ?: emptyList()
)

result?.updatedJourney?.let { journey ->
locationCache.putLastJourney(journey, userId)
journeyService.updateJourney(
val spaceIds = userPreferences.currentUser?.space_ids ?: emptyList()
spaceIds.forEach { spaceId ->
val result = getJourney(
userId = userId,
journey = journey
newLocation = extractedLocation,
lastKnownJourney = lastKnownJourney,
lastLocations = locationCache.getLastFiveLocations(userId) ?: emptyList()
)
}

result?.newJourney?.let { journey ->
val currentJourney = journeyService.addJourney(
userId = userId,
newJourney = journey
)
locationCache.putLastJourney(currentJourney, userId)
result?.updatedJourney?.let { journey ->
locationCache.putLastJourney(journey, userId)
journeyService.updateJourney(
userId = userId,
journey = journey,
spaceId = spaceId
)
}

result?.newJourney?.let { journey ->
val currentJourney = journeyService.addJourney(
userId = userId,
newJourney = journey,
spaceId = spaceId
)
locationCache.putLastJourney(currentJourney, userId)
}
}
} catch (e: Exception) {
Timber.e(e, "Error while saving location journey")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,11 @@ class ApiJourneyService @Inject constructor(

return try {
GroupSessionBuilder(bufferedSenderKeyStore).process(groupAddress, distributionMessage)
Triple(distributionMessage, GroupCipher(bufferedSenderKeyStore, groupAddress), distribution.id)
Triple(
distributionMessage,
GroupCipher(bufferedSenderKeyStore, groupAddress),
distribution.id
)
} catch (e: Exception) {
Timber.e(e, "Error processing group session")
null
Expand Down Expand Up @@ -140,64 +144,89 @@ class ApiJourneyService @Inject constructor(
*/
suspend fun addJourney(
userId: String,
newJourney: LocationJourney
newJourney: LocationJourney,
spaceId: String
): LocationJourney {
var journey: LocationJourney = newJourney
userPreferences.currentUser?.space_ids?.forEach { spaceId ->
val groupKeysDoc = getGroupKeyDoc(spaceId) ?: return@forEach

val (distributionMessage, groupCipher, keyId) = getGroupCipherByKeyId(
spaceId,
userId,
null,
groupKeysDoc
)
?: run {
Timber.e("Failed to get group cipher")

// Iterate through all spaces the user belongs to
userPreferences.currentUser?.space_ids?.forEach { _ ->
val groupKeysDoc = getGroupKeyDoc(spaceId) ?: run {
Timber.e("xxx Failed to get group keys for space $spaceId")
return@forEach
}

groupKeysDoc.member_keys.forEach { memberId ->
// Fetch group cipher for the group and the user
val (distributionMessage, groupCipher, keyId) = getGroupCipherByKeyId(
spaceId,
userId,
null,
groupKeysDoc
) ?: run {
Timber.e("xxx Failed to get group cipher for group $memberId")
return@forEach
}

val docRef = spaceMemberJourneyRef(spaceId, userId).document(newJourney.id)
val docRef = spaceMemberJourneyRef(spaceId, userId).document(newJourney.id)

journey = newJourney.copy(id = docRef.id, key_id = keyId)
// Update the journey ID and key ID for the new space and member
journey = newJourney.copy(id = docRef.id, key_id = keyId)

val encryptedJourney =
journey.toEncryptedLocationJourney(groupCipher, distributionMessage.distributionId)
// Encrypt the journey
val encryptedJourney = journey.toEncryptedLocationJourney(
groupCipher,
distributionMessage.distributionId
)

encryptedJourney?.let { docRef.set(it).await() }
// Save the encrypted journey to the document
encryptedJourney?.let { docRef.set(it).await() }
Timber.d("xxx Added journey to group $memberId in space $spaceId")
}
}

// After the iteration, return the updated journey (could be updated multiple times for different spaces)
return journey
}

/**
* Updates the last [LocationJourney] for [userId].
*/
suspend fun updateJourney(userId: String, journey: LocationJourney) {
userPreferences.currentUser?.space_ids?.forEach { spaceId ->
val groupKeysDoc = getGroupKeyDoc(spaceId) ?: return@forEach

val (distributionMessage, groupCipher) = getGroupCipherByKeyId(
spaceId,
userId,
journey.key_id,
groupKeysDoc
)
?: run {
Timber.e("Failed to get group cipher")
suspend fun updateJourney(userId: String, journey: LocationJourney, spaceId: String) {
userPreferences.currentUser?.space_ids?.forEach { _ ->
val groupKeysDoc = getGroupKeyDoc(spaceId) ?: return

// Iterate through all the member groups in the space
val memberIds = groupKeysDoc.member_keys.keys
memberIds.forEach { groupId ->
// Fetch the group cipher and other necessary details using the groupId and journey.key_id
val (distributionMessage, groupCipher) = getGroupCipherByKeyId(
spaceId,
userId,
journey.key_id,
groupKeysDoc
) ?: run {
Timber.e("Failed to get group cipher for group $groupId in space $spaceId")
return@forEach
}

val encryptedJourney =
journey.toEncryptedLocationJourney(groupCipher, distributionMessage.distributionId)
try {
encryptedJourney?.let {
spaceMemberJourneyRef(spaceId, userId)
.document(journey.id)
.set(it)
.await()
val encryptedJourney =
journey.toEncryptedLocationJourney(
groupCipher,
distributionMessage.distributionId
)
try {
// Update the encrypted journey for each group in the space
if (encryptedJourney != null) {
spaceMemberJourneyRef(spaceId, userId)
.document(journey.id)
.set(encryptedJourney)
.await()
}
Timber.d("Updated journey for group $groupId in space $spaceId")
} catch (e: Exception) {
Timber.e(e, "Error updating journey for group $groupId in space $spaceId")
}
} catch (e: Exception) {
Timber.e(e, "Error updating journey")
}
}
}
Expand Down

0 comments on commit 77c1250

Please sign in to comment.