Skip to content

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
gino-m authored May 28, 2024
2 parents 6f75d7a + f81e3e6 commit 1ef7dea
Show file tree
Hide file tree
Showing 73 changed files with 394 additions and 459 deletions.
21 changes: 10 additions & 11 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
[*]
charset=utf-8
end_of_line=lf
insert_final_newline=false
indent_style=space
indent_size=4
charset = utf-8
end_of_line = lf
insert_final_newline = false
indent_style = space
indent_size = 4

[{*.jhm,*.rng,*.wsdl,*.fxml,*.xslt,*.jrxml,*.ant,*.xul,*.xsl,*.xsd,*.tld,*.jnlp,*.xml}]
indent_size=2
indent_size = 2

[*.json]
indent_size=2
indent_size = 2

[*.java]
indent_size=2
continuation_indent_size = 4
indent_size = 2

[*.yaml]
indent_size=2
indent_size = 2

[*.kt]
indent_size=2
indent_size = 2
18 changes: 9 additions & 9 deletions ground/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -194,21 +194,21 @@ dependencies {

// UI widgets.
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'com.google.android.material:material:1.11.0'
implementation 'com.google.android.material:material:1.12.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'

// Jetpack Compose
implementation 'androidx.compose.ui:ui:1.6.4'
implementation 'androidx.compose.compiler:compiler:1.5.11'
implementation 'androidx.compose.ui:ui:1.6.7'
implementation 'androidx.compose.compiler:compiler:1.5.14'
implementation 'androidx.compose.material3:material3-android:1.2.1'
implementation 'androidx.compose.ui:ui-tooling-preview-android:1.6.4'
implementation 'androidx.compose.ui:ui-tooling-preview-android:1.6.7'
// Test rules and transitive dependencies:
testImplementation('androidx.compose.ui:ui-test-junit4:1.6.4')
testImplementation('androidx.compose.ui:ui-test-junit4:1.6.7')
// Needed for createComposeRule(), but not for createAndroidComposeRule<YourActivity>():
debugImplementation('androidx.compose.ui:ui-test-manifest:1.6.4')
debugImplementation 'androidx.compose.ui:ui-tooling:1.6.6'
stagingImplementation('androidx.compose.ui:ui-test-manifest:1.6.4')
implementation 'androidx.compose.runtime:runtime-livedata:1.6.5'
debugImplementation('androidx.compose.ui:ui-test-manifest:1.6.7')
debugImplementation 'androidx.compose.ui:ui-tooling:1.6.7'
stagingImplementation('androidx.compose.ui:ui-test-manifest:1.6.7')
implementation 'androidx.compose.runtime:runtime-livedata:1.6.7'

// Google Play Services.
implementation 'com.google.android.gms:play-services-auth:21.0.0'
Expand Down
4 changes: 2 additions & 2 deletions ground/src/main/java/com/google/android/ground/Config.kt
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ object Config {

// TODO(#1730): Make sub-paths configurable and stop hardcoding here.
const val DEFAULT_MOG_TILE_LOCATION = "/offline-imagery/default"
const val DEFAULT_MOG_MIN_ZOOM = 8
const val DEFAULT_MOG_MAX_ZOOM = 14
private const val DEFAULT_MOG_MIN_ZOOM = 8
private const val DEFAULT_MOG_MAX_ZOOM = 14

fun getMogSources(path: String) =
listOf(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ import com.google.android.ground.ui.common.NavigateTo
import com.google.android.ground.ui.common.NavigateUp
import com.google.android.ground.ui.common.NavigationRequest
import com.google.android.ground.ui.common.Navigator
import com.google.android.ground.ui.common.ProgressDialogs.modalSpinner
import com.google.android.ground.ui.common.ViewModelFactory
import com.google.android.ground.ui.common.modalSpinner
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject
import kotlinx.coroutines.launch
Expand Down Expand Up @@ -80,7 +80,7 @@ class MainActivity : AbstractActivity() {
navHostFragment =
supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment

viewModel = viewModelFactory.get(this, MainViewModel::class.java)
viewModel = viewModelFactory[this, MainViewModel::class.java]
viewModel.signInProgressDialogVisibility.observe(this) { visible: Boolean ->
onSignInProgress(visible)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@ enum class Role {
VIEWER;

companion object {
fun valueStrings() = values().map(Role::toString)
fun valueStrings() = entries.map(Role::toString)
}
}
3 changes: 1 addition & 2 deletions ground/src/main/java/com/google/android/ground/model/User.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@
package com.google.android.ground.model

/** Represents a single application user. */
data class User
constructor(
data class User(
val id: String,
val email: String,
val displayName: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@
*/
package com.google.android.ground.model.job

data class Style constructor(val color: String)
data class Style(val color: String)
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ package com.google.android.ground.model.submission
import com.google.android.ground.model.geometry.Polygon

/** User-provided response to a "draw an area" data collection [Task]. */
data class DrawAreaTaskData constructor(val area: Polygon) : GeometryTaskData(area) {
data class DrawAreaTaskData(val area: Polygon) : GeometryTaskData(area) {
override fun isEmpty(): Boolean = area.isEmpty()
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ package com.google.android.ground.model.submission
import com.google.android.ground.model.geometry.LineString

/** User-provided "ongoing" response to a "draw an area" data collection [Task]. */
data class DrawAreaTaskIncompleteData constructor(val lineString: LineString) :
GeometryTaskData(lineString) {
data class DrawAreaTaskIncompleteData(val lineString: LineString) : GeometryTaskData(lineString) {
override fun isEmpty(): Boolean = lineString.isEmpty()
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import java.math.RoundingMode
import java.text.DecimalFormat

/** User-provided response to a "drop a pin" data collection [Task]. */
data class DropPinTaskData constructor(val location: Point) : GeometryTaskData(location) {
data class DropPinTaskData(val location: Point) : GeometryTaskData(location) {
override fun getDetailsText(): String {
// TODO(#752): Move to strings.xml for i18n
val df = DecimalFormat("#.##")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import kotlinx.serialization.Serializable

/** A user provided response to a number question task. */
@Serializable
data class NumberTaskData constructor(private val number: String) : TaskData {
data class NumberTaskData(private val number: String) : TaskData {
val value: Double
get() = number.toDouble()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@ package com.google.android.ground.persistence.local
import android.content.Context
import android.content.SharedPreferences
import com.google.android.ground.Config
import com.google.android.ground.persistence.local.room.dao.*
import com.google.android.ground.persistence.local.room.stores.*
import com.google.android.ground.persistence.local.stores.*
import com.google.android.ground.util.allowThreadDiskReads
import dagger.Module
import dagger.Provides
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ enum class EntityState(private val intValue: Int) : IntEnum {
companion object {
@JvmStatic @TypeConverter fun toInt(value: EntityState?) = toInt(value, UNKNOWN)

@JvmStatic @TypeConverter fun fromInt(intValue: Int) = fromInt(values(), intValue, UNKNOWN)
@JvmStatic
@TypeConverter
fun fromInt(intValue: Int) = fromInt(entries.toTypedArray(), intValue, UNKNOWN)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ enum class ExpressionEntityType(private val intValue: Int) : IntEnum {

@JvmStatic
@TypeConverter
fun fromInt(intValue: Int): ExpressionEntityType = IntEnum.fromInt(values(), intValue, UNKNOWN)
fun fromInt(intValue: Int): ExpressionEntityType =
IntEnum.fromInt(entries.toTypedArray(), intValue, UNKNOWN)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ enum class MatchEntityType(private val intValue: Int) : IntEnum {

@JvmStatic
@TypeConverter
fun fromInt(intValue: Int): MatchEntityType = IntEnum.fromInt(values(), intValue, UNKNOWN)
fun fromInt(intValue: Int): MatchEntityType =
IntEnum.fromInt(entries.toTypedArray(), intValue, UNKNOWN)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ enum class MultipleChoiceEntityType(private val intValue: Int) : IntEnum {

@JvmStatic @TypeConverter fun toInt(value: MultipleChoiceEntityType?) = toInt(value, UNKNOWN)

@JvmStatic @TypeConverter fun fromInt(intValue: Int) = fromInt(values(), intValue, UNKNOWN)
@JvmStatic
@TypeConverter
fun fromInt(intValue: Int) = fromInt(entries.toTypedArray(), intValue, UNKNOWN)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,12 @@ enum class MutationEntitySyncStatus(private val intValue: Int, private val enumV

companion object {
fun fromMutationSyncStatus(syncStatus: SyncStatus) =
values().firstOrNull { s: MutationEntitySyncStatus -> s.enumValue === syncStatus } ?: UNKNOWN
entries.firstOrNull { s: MutationEntitySyncStatus -> s.enumValue === syncStatus } ?: UNKNOWN

@JvmStatic @TypeConverter fun toInt(value: MutationEntitySyncStatus?) = toInt(value, UNKNOWN)

@JvmStatic @TypeConverter fun fromInt(intValue: Int) = fromInt(values(), intValue, UNKNOWN)
@JvmStatic
@TypeConverter
fun fromInt(intValue: Int) = fromInt(entries.toTypedArray(), intValue, UNKNOWN)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ enum class MutationEntityType(private val intValue: Int) : IntEnum {

@JvmStatic @TypeConverter fun toInt(value: MutationEntityType?) = toInt(value, UNKNOWN)

@JvmStatic @TypeConverter fun fromInt(intValue: Int) = fromInt(values(), intValue, UNKNOWN)
@JvmStatic
@TypeConverter
fun fromInt(intValue: Int) = fromInt(entries.toTypedArray(), intValue, UNKNOWN)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ enum class TaskEntityType(private val intValue: Int) : IntEnum {

@JvmStatic
@TypeConverter
fun fromInt(intValue: Int): TaskEntityType = IntEnum.fromInt(values(), intValue, UNKNOWN)
fun fromInt(intValue: Int): TaskEntityType =
IntEnum.fromInt(entries.toTypedArray(), intValue, UNKNOWN)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ object CaptureLocationResultConverter {
mapOf(
ACCURACY_KEY to result.accuracy!!,
ALTITUDE_KEY to result.altitude!!,
GEOMETRY_KEY to GeometryConverter.toFirestoreMap(result.geometry!!).getOrThrow(),
GEOMETRY_KEY to GeometryConverter.toFirestoreMap(result.geometry).getOrThrow(),
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ import com.google.android.ground.model.task.Task
import com.google.android.ground.persistence.remote.DataStoreException
import com.google.firebase.Timestamp
import com.google.firebase.firestore.DocumentSnapshot
import java.util.Objects
import kotlinx.collections.immutable.toPersistentMap
import timber.log.Timber

Expand All @@ -50,16 +49,16 @@ internal object SubmissionConverter {
throw DataStoreException("Submission doc featureId doesn't match specified loiId")
}
// Degrade gracefully when audit info missing in remote db.
val created = Objects.requireNonNullElse(doc.created, AuditInfoNestedObject.FALLBACK_VALUE)
val lastModified = Objects.requireNonNullElse(doc.lastModified, created)
val created = doc.created ?: AuditInfoNestedObject.FALLBACK_VALUE
val lastModified = doc.lastModified ?: created
val job = loi.job
return Submission(
snapshot.id,
loi.surveyId,
loi,
job,
AuditInfoConverter.toAuditInfo(created!!),
AuditInfoConverter.toAuditInfo(lastModified!!),
AuditInfoConverter.toAuditInfo(created),
AuditInfoConverter.toAuditInfo(lastModified),
// TODO(#2058): Remove reference to `responses` once dev dbs updated or reset.
toSubmissionData(snapshot.id, job, doc.data ?: doc.responses),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,12 @@ internal object SubmissionMutationConverter {
is DateTaskData -> {
taskData.date
}
is GeometryTaskData -> {
GeometryConverter.toFirestoreMap(taskData.geometry).getOrThrow()
}
is CaptureLocationTaskData -> {
CaptureLocationResultConverter.toFirestoreMap(taskData).getOrThrow()
}
is GeometryTaskData -> {
GeometryConverter.toFirestoreMap(taskData.geometry).getOrThrow()
}
else -> {
Timber.e("Unknown value type: %s", taskData?.javaClass?.name)
null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ package com.google.android.ground.persistence.remote.firebase.schema

import com.google.firebase.firestore.IgnoreExtraProperties

@IgnoreExtraProperties data class TermsOfServiceDocument constructor(val text: String? = null)
@IgnoreExtraProperties data class TermsOfServiceDocument(val text: String? = null)
Original file line number Diff line number Diff line change
Expand Up @@ -29,31 +29,25 @@ import kotlinx.coroutines.tasks.await

/** Thin wrapper around [FusedLocationProviderClient] exposing key LOIs as reactive streams. */
class FusedLocationProviderClient @Inject constructor(@ApplicationContext context: Context) {
private val fusedLocationProviderClient: FusedLocationProviderClient

init {
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(context)
}
private val client = LocationServices.getFusedLocationProviderClient(context)

/**
* Returns the most recent historical location currently available. Will return null if no
* historical location is available. The historical location may be of an arbitrary age, so
* clients should check how old the location is to see if it suits their purposes.
*/
@SuppressLint("MissingPermission")
suspend fun getLastLocation(): Location? = fusedLocationProviderClient.lastLocation.await()
suspend fun getLastLocation(): Location? = client.lastLocation.await()

@SuppressLint("MissingPermission")
suspend fun requestLocationUpdates(
locationRequest: LocationRequest,
locationCallback: LocationSharedFlowCallback,
) {
fusedLocationProviderClient
.requestLocationUpdates(locationRequest, locationCallback, Looper.myLooper())
.await()
client.requestLocationUpdates(locationRequest, locationCallback, Looper.myLooper()).await()
}

suspend fun removeLocationUpdates(locationCallback: LocationSharedFlowCallback) {
fusedLocationProviderClient.removeLocationUpdates(locationCallback).await()
client.removeLocationUpdates(locationCallback).await()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,8 @@ import kotlinx.coroutines.tasks.await

/** Thin wrapper around [SettingsClient] exposing key features as reactive streams. */
class SettingsClient @Inject constructor(@ApplicationContext context: Context) {
private val settingsClient: SettingsClient

init {
settingsClient = LocationServices.getSettingsClient(context)
}
private val client = LocationServices.getSettingsClient(context)

suspend fun checkLocationSettings(request: LocationSettingsRequest): LocationSettingsResponse =
settingsClient.checkLocationSettings(request).await()
client.checkLocationSettings(request).await()
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,14 @@ constructor(
@ApplicationScope private val externalScope: CoroutineScope,
) : BaseAuthenticationManager() {

private val googleSignInOptions: GoogleSignInOptions
private val googleSignInOptions: GoogleSignInOptions =
GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(resources.getString(R.string.default_web_client_id))
.requestEmail()
.requestProfile()
.build()

init {
googleSignInOptions =
GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(resources.getString(R.string.default_web_client_id))
.requestEmail()
.requestProfile()
.build()

externalScope.launch {
activityStreams.getActivityResults(signInRequestCode).collect { onActivityResult(it) }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import com.google.android.ground.AbstractActivity
import com.google.android.ground.R
import com.google.android.ground.ui.common.ProgressDialogs.modalSpinner
import com.google.android.ground.ui.util.ViewUtil
import com.google.android.ground.util.Debug
import javax.inject.Inject
Expand All @@ -45,7 +44,7 @@ abstract class AbstractFragment : Fragment() {
private var progressDialog: AlertDialog? = null

protected fun <T : ViewModel> getViewModel(modelClass: Class<T>): T =
viewModelFactory.get(this, modelClass)
viewModelFactory[this, modelClass]

override fun onAttach(context: Context) {
Debug.logLifecycleEvent(this)
Expand Down
Loading

0 comments on commit 1ef7dea

Please sign in to comment.