Skip to content

Commit

Permalink
added journey into cache with spaceId
Browse files Browse the repository at this point in the history
  • Loading branch information
cp-sneh-s committed Jan 21, 2025
1 parent 77c1250 commit a9f2710
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 107 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ 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 @@ -38,9 +37,6 @@ 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 @@ -56,7 +52,7 @@ class LocationUpdateReceiver : BroadcastReceiver() {
extractedLocation.longitude,
System.currentTimeMillis()
)
journeyRepository.saveLocationJourney(extractedLocation, userId, userPreferences)
journeyRepository.saveLocationJourney(extractedLocation, userId)
}
} catch (e: Exception) {
Timber.e(e, "Error while saving location")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,6 @@ fun getJourney(
// 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,
updated_at = System.currentTimeMillis()
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,43 +12,41 @@ import javax.inject.Singleton
@Singleton
class JourneyRepository @Inject constructor(
private val journeyService: ApiJourneyService,
private val locationCache: LocationCache
private val locationCache: LocationCache,
private val userPreferences: UserPreferences
) {
suspend fun saveLocationJourney(
extractedLocation: Location,
userId: String,
userPreferences: UserPreferences
userId: String
) {
try {
cacheLocations(extractedLocation, userId)
val userPreferences = userPreferences.currentUser?.space_ids ?: emptyList()
userPreferences.forEach { spaceId ->
cacheLocations(extractedLocation, userId)
val lastKnownJourney = getLastKnownLocation(userId, spaceId)

val lastKnownJourney = getLastKnownLocation(userId)

val spaceIds = userPreferences.currentUser?.space_ids ?: emptyList()
spaceIds.forEach { spaceId ->
val result = getJourney(
userId = userId,
newLocation = extractedLocation,
lastKnownJourney = lastKnownJourney,
lastLocations = locationCache.getLastFiveLocations(userId) ?: emptyList()
lastLocations = locationCache.getLastFiveLocations(userId, spaceId)
?: emptyList()
)

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

result?.newJourney?.let { journey ->
val currentJourney = journeyService.addJourney(
userId = userId,
newJourney = journey,
spaceId = spaceId
newJourney = journey
)
locationCache.putLastJourney(currentJourney, userId)
locationCache.putLastJourney(currentJourney, userId, spaceId)
}
}
} catch (e: Exception) {
Expand All @@ -63,26 +61,34 @@ class JourneyRepository @Inject constructor(
* with steady state in cache as well as remote database
* */
private suspend fun getLastKnownLocation(
userid: String
userid: String,
spaceId: String
): LocationJourney? {
// Return last location journey if available from cache
return locationCache.getLastJourney(userid) ?: run {
return locationCache.getLastJourney(userid, spaceId) ?: run {
// Here, means no location journey available in cache
// Fetch last location journey from remote database and save it to cache
val lastJourney = journeyService.getLastJourneyLocation(userid)
val lastJourney = journeyService.getLastJourneyLocation(userid, spaceId)
if (lastJourney != null) {
Timber.tag("XXX").e("lastJourney for $spaceId is ${lastJourney.id} ")
}
return lastJourney?.let {
locationCache.putLastJourney(it, userid)
locationCache.putLastJourney(it, userid, spaceId)
lastJourney
}
}
}

private fun cacheLocations(extractedLocation: Location, userId: String) {
val lastFiveLocations = (locationCache.getLastFiveLocations(userId) ?: emptyList()).toMutableList()
if (lastFiveLocations.size >= 5) {
lastFiveLocations.removeAt(0)
userPreferences.currentUser?.space_ids?.forEach { spaceId ->
val lastFiveLocations =
(locationCache.getLastFiveLocations(userId, spaceId) ?: emptyList()).toMutableList()
Timber.tag("xxx").e("LastFiveLocations :- $lastFiveLocations for spaceId $spaceId")
if (lastFiveLocations.size >= 5) {
lastFiveLocations.removeAt(0)
}
lastFiveLocations.add(extractedLocation)
locationCache.putLastFiveLocations(lastFiveLocations, userId, spaceId)
}
lastFiveLocations.add(extractedLocation)
locationCache.putLastFiveLocations(lastFiveLocations, userId)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -144,98 +144,79 @@ class ApiJourneyService @Inject constructor(
*/
suspend fun addJourney(
userId: String,
newJourney: LocationJourney,
spaceId: String
newJourney: LocationJourney
): LocationJourney {
var journey: LocationJourney = newJourney

// 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")
userPreferences.currentUser?.space_ids?.forEach { spaceId ->
Timber.tag("xxx").d("started adding journey for space :- $spaceId")
val groupKeysDoc = getGroupKeyDoc(spaceId) ?: return@forEach

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

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

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

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

// Save the encrypted journey to the document
encryptedJourney?.let { docRef.set(it).await() }
Timber.d("xxx Added journey to group $memberId in space $spaceId")
}
encryptedJourney?.let { docRef.set(it).await() }
Timber.tag("xxx").d("successfully added journey for 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, 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")
suspend fun updateJourney(userId: String, journey: LocationJourney) {
userPreferences.currentUser?.space_ids?.forEach { spaceId ->
Timber.tag("XXX").e("started updating journey for space $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")
return@forEach
}

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")
val encryptedJourney =
journey.toEncryptedLocationJourney(groupCipher, distributionMessage.distributionId)
try {
encryptedJourney?.let {
spaceMemberJourneyRef(spaceId, userId)
.document(journey.id)
.set(it)
.await()
}
Timber.tag("XXX").e("successfully updated journey for space $spaceId")
} catch (e: Exception) {
Timber.e(e, "Error updating journey")
}
}
}


/**
* Fetches the most recent [LocationJourney] for [userId] in the current space.
*/
suspend fun getLastJourneyLocation(userId: String): LocationJourney? {
val encryptedJourney = spaceMemberJourneyRef(currentSpaceId, userId)
suspend fun getLastJourneyLocation(userId: String, spaceId: String): LocationJourney? {
val encryptedJourney = spaceMemberJourneyRef(spaceId, userId)
.orderBy("created_at", Query.Direction.DESCENDING)
.limit(1)
.get()
Expand All @@ -245,11 +226,11 @@ class ApiJourneyService @Inject constructor(
?.toObject<EncryptedLocationJourney>()
?: return null

val groupKeysDoc = getGroupKeyDoc(currentSpaceId) ?: return null
val groupKeysDoc = getGroupKeyDoc(spaceId) ?: return null

// Decrypt
return runWithGroupCipher(
spaceId = currentSpaceId,
spaceId = spaceId,
userId = userId,
groupKeysDoc = groupKeysDoc,
keyId = encryptedJourney.key_id,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,20 @@ class LocationCache @Inject constructor() {
private val lastFiveLocationsCache = LruCache<String, List<Location>>(25)
private val lastJourneyUpdatedTime = LruCache<String, Long>(25)

fun putLastJourney(journey: LocationJourney, userId: String) {
lastJourneyCache.put(userId, journey)
fun putLastJourney(journey: LocationJourney, userId: String, spaceId: String) {
lastJourneyCache.put("${userId}_${spaceId}", journey)
}

fun getLastJourney(userId: String): LocationJourney? {
return lastJourneyCache.get(userId) ?: null
fun getLastJourney(userId: String, spaceId: String): LocationJourney? {
return lastJourneyCache.get("${userId}_${spaceId}") ?: null
}

fun putLastFiveLocations(locations: List<Location>, userId: String) {
lastFiveLocationsCache.put(userId, locations)
fun putLastFiveLocations(locations: List<Location>, userId: String, spaceId: String) {
lastFiveLocationsCache.put("${userId}_${spaceId}", locations)
}

fun getLastFiveLocations(userId: String): List<Location>? {
return lastFiveLocationsCache.get(userId) ?: null
fun getLastFiveLocations(userId: String, spaceId: String): List<Location>? {
return lastFiveLocationsCache.get("${userId}_${spaceId}") ?: null
}

fun putLastJourneyUpdatedTime(time: Long, userId: String) {
Expand Down

0 comments on commit a9f2710

Please sign in to comment.