Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix part of #5025: App and OS Deprecation Milestone 2 - Add protos and the DeprecationController #4999

Merged
merged 20 commits into from
Jul 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
698647d
feat: Add protos for the deprecation feature as well as the deprecati…
kkmurerwa May 29, 2023
10e1e50
fix: Add comments on the DeprecationController to fix kdocs issues
kkmurerwa May 29, 2023
d88c458
chore: Update comments on the deprecation.proto file to better explai…
kkmurerwa Jun 1, 2023
dd0d378
Merge branch 'develop' into app-and-os-deprecation-milestone-2
kkmurerwa Jun 1, 2023
29a4835
fix: Fix failing tests in the DeprecationControllerTest.
kkmurerwa Jun 1, 2023
974ad10
Merge branch 'develop' into app-and-os-deprecation-milestone-2
kkmurerwa Jun 2, 2023
384fec2
fix: Fix failing kdoc regex check
kkmurerwa Jun 2, 2023
409a26c
Merge branch 'develop' into app-and-os-deprecation-milestone-2
kkmurerwa Jun 22, 2023
65c0cd0
Merge branch 'develop' into app-and-os-deprecation-milestone-2
kkmurerwa Jul 3, 2023
700a14a
chore: Fix a few nits and minor code improvements
Jul 3, 2023
6dabebc
Merge branch 'app-and-os-deprecation-milestone-2' of github.com:kkmur…
Jul 3, 2023
1ad6387
chore: Fix linting errors
Jul 3, 2023
20135a1
chore: Fix bazel build file linting issues
Jul 3, 2023
10109b1
chore: Update code comments and fix a few linting issues
Jul 4, 2023
ea10834
Merge branch 'develop' into app-and-os-deprecation-milestone-2
kkmurerwa Jul 4, 2023
2c10b92
Merge branch 'develop' into app-and-os-deprecation-milestone-2
kkmurerwa Jul 10, 2023
15a6a3d
Merge branch 'develop' into app-and-os-deprecation-milestone-2
kkmurerwa Jul 11, 2023
ed972f4
chore: Remove unused DeprecationResponseActionStatus options
Jul 11, 2023
1eef054
Merge branch 'develop' into app-and-os-deprecation-milestone-2
kkmurerwa Jul 12, 2023
27a997e
Merge branch 'develop' into app-and-os-deprecation-milestone-2
adhiamboperes Jul 12, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions domain/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ TEST_DEPS = [
"//domain/src/main/java/org/oppia/android/domain/classify/rules/textinput:text_input_rule_module",
"//domain/src/main/java/org/oppia/android/domain/feedbackreporting:prod_module",
"//domain/src/main/java/org/oppia/android/domain/feedbackreporting:report_schema_version",
"//domain/src/main/java/org/oppia/android/domain/onboarding:deprecation_controller",
"//domain/src/main/java/org/oppia/android/domain/onboarding:retriever_prod_module",
"//domain/src/main/java/org/oppia/android/domain/onboarding:state_controller",
"//domain/src/main/java/org/oppia/android/domain/oppialogger:prod_module",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,17 @@ kt_android_library(
name = "state_controller",
srcs = [
"AppStartupStateController.kt",
"DeprecationController.kt",
adhiamboperes marked this conversation as resolved.
Show resolved Hide resolved
],
visibility = ["//:oppia_api_visibility"],
deps = [
":exploration_meta_data_retriever",
"//data/src/main/java/org/oppia/android/data/persistence:cache_store",
"//domain/src/main/java/org/oppia/android/domain/oppialogger:oppia_logger",
"//model/src/main/proto:deprecation_java_proto_lite",
"//model/src/main/proto:onboarding_java_proto_lite",
"//third_party:javax_inject_javax_inject",
"//utility",
"//utility/src/main/java/org/oppia/android/util/data:data_provider",
"//utility/src/main/java/org/oppia/android/util/data:data_providers",
"//utility/src/main/java/org/oppia/android/util/extensions:bundle_extensions",
Expand Down Expand Up @@ -55,4 +58,24 @@ kt_android_library(
],
)

kt_android_library(
name = "deprecation_controller",
srcs = [
"DeprecationController.kt",
],
visibility = ["//:oppia_api_visibility"],
deps = [
":exploration_meta_data_retriever",
"//data/src/main/java/org/oppia/android/data/persistence:cache_store",
"//domain/src/main/java/org/oppia/android/domain/oppialogger:oppia_logger",
"//model/src/main/proto:deprecation_java_proto_lite",
"//model/src/main/proto:onboarding_java_proto_lite",
"//third_party:javax_inject_javax_inject",
"//utility",
"//utility/src/main/java/org/oppia/android/util/data:data_provider",
"//utility/src/main/java/org/oppia/android/util/data:data_providers",
"//utility/src/main/java/org/oppia/android/util/extensions:bundle_extensions",
],
)

dagger_rules()
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package org.oppia.android.domain.onboarding

import kotlinx.coroutines.Deferred
import org.oppia.android.app.model.DeprecationNoticeType
import org.oppia.android.app.model.DeprecationResponse
import org.oppia.android.app.model.DeprecationResponseDatabase
import org.oppia.android.data.persistence.PersistentCacheStore
import org.oppia.android.domain.oppialogger.OppiaLogger
import org.oppia.android.util.data.AsyncResult
import org.oppia.android.util.data.DataProvider
import org.oppia.android.util.data.DataProviders
import org.oppia.android.util.data.DataProviders.Companion.transform
import javax.inject.Inject
import javax.inject.Singleton

private const val GET_DEPRECATION_RESPONSE_PROVIDER_ID = "get_deprecation_response_provider_id"
private const val ADD_DEPRECATION_RESPONSE_PROVIDER_ID = "add_deprecation_response_provider_id"

/**
* Controller for persisting and retrieving the user's deprecation responses. This will be used to
* handle deprecations once the user opens the app.
*/
@Singleton
class DeprecationController @Inject constructor(
cacheStoreFactory: PersistentCacheStore.Factory,
private val oppiaLogger: OppiaLogger,
private val dataProviders: DataProviders
) {
/** Create an instance of [PersistentCacheStore] that contains a [DeprecationResponseDatabase]. */
private val deprecationStore by lazy {
cacheStoreFactory.create(
"deprecation_store",
DeprecationResponseDatabase.getDefaultInstance()
)
}

/** Enum states for the possible outcomes of a deprecation action. */
private enum class DeprecationResponseActionStatus {
/** Indicates that the deprecation response read/write operation succeeded. */
SUCCESS
}

init {
// Prime the cache ahead of time so that the deprecation response can be retrieved
// synchronously.
deprecationStore.primeInMemoryAndDiskCacheAsync(
updateMode = PersistentCacheStore.UpdateMode.UPDATE_ALWAYS,
publishMode = PersistentCacheStore.PublishMode.PUBLISH_TO_IN_MEMORY_CACHE
).invokeOnCompletion { primeFailure ->
primeFailure?.let {
oppiaLogger.e(
"DeprecationController",
"Failed to prime cache ahead of data retrieval for DeprecationController.",
primeFailure
)
}
}
}

private val deprecationDataProvider by lazy { fetchDeprecationProvider() }

private fun fetchDeprecationProvider(): DataProvider<DeprecationResponseDatabase> {
return deprecationStore.transform(
GET_DEPRECATION_RESPONSE_PROVIDER_ID
) { deprecationResponsesDatabase ->
DeprecationResponseDatabase.newBuilder().apply {
appDeprecationResponse = deprecationResponsesDatabase.appDeprecationResponse
osDeprecationResponse = deprecationResponsesDatabase.osDeprecationResponse
}.build()
}
}

/**
* Returns a [DataProvider] containing the the [DeprecationResponseDatabase], which in turn
* affects what initial app flow the user is directed to.
*/
fun getDeprecationDatabase(): DataProvider<DeprecationResponseDatabase> = deprecationDataProvider

/**
* Stores a new [DeprecationResponse] to the cache.
*
* @param deprecationResponse the deprecation response to be stored
* @return [AsyncResult] of the deprecation action
*/
fun saveDeprecationResponse(deprecationResponse: DeprecationResponse): DataProvider<Any?> {
val deferred = deprecationStore.storeDataWithCustomChannelAsync(
updateInMemoryCache = true
) { deprecationResponseDb ->
val deprecationBuilder = deprecationResponseDb.toBuilder().apply {
if (deprecationResponse.deprecationNoticeType == DeprecationNoticeType.APP_DEPRECATION)
appDeprecationResponse = deprecationResponse
else
osDeprecationResponse = deprecationResponse
}
.build()
Pair(deprecationBuilder, DeprecationResponseActionStatus.SUCCESS)
}

return dataProviders.createInMemoryDataProviderAsync(ADD_DEPRECATION_RESPONSE_PROVIDER_ID) {
return@createInMemoryDataProviderAsync getDeferredResult(deferred)
}
}

/**
* Retrieves the [DeprecationResponse] from the cache.
*
* @param deferred a deferred instance of the [DeprecationResponseActionStatus]
* @return [AsyncResult]
*/
private suspend fun getDeferredResult(
deferred: Deferred<DeprecationResponseActionStatus>
): AsyncResult<Any?> {
return when (deferred.await()) {
DeprecationResponseActionStatus.SUCCESS -> AsyncResult.Success(null)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,35 @@ oppia_android_test(
],
)

oppia_android_test(
name = "DeprecationControllerTest",
srcs = ["DeprecationControllerTest.kt"],
custom_package = "org.oppia.android.domain.onboarding",
test_class = "org.oppia.android.domain.onboarding.DeprecationControllerTest",
test_manifest = "//domain:test_manifest",
deps = [
":dagger",
"//domain",
"//domain/src/main/java/org/oppia/android/domain/onboarding:deprecation_controller",
"//domain/src/main/java/org/oppia/android/domain/onboarding:retriever_prod_module",
"//domain/src/main/java/org/oppia/android/domain/oppialogger:prod_module",
"//domain/src/main/java/org/oppia/android/domain/oppialogger/analytics:prod_module",
"//testing",
"//testing/src/main/java/org/oppia/android/testing/data:data_provider_test_monitor",
"//testing/src/main/java/org/oppia/android/testing/junit:oppia_parameterized_test_runner",
"//testing/src/main/java/org/oppia/android/testing/junit:parameterized_robolectric_test_runner",
"//testing/src/main/java/org/oppia/android/testing/robolectric:test_module",
"//testing/src/main/java/org/oppia/android/testing/threading:test_module",
"//third_party:com_google_truth_truth",
"//third_party:junit_junit",
"//third_party:org_mockito_mockito-core",
"//third_party:org_robolectric_robolectric",
"//third_party:robolectric_android-all",
"//utility/src/main/java/org/oppia/android/util/locale:prod_module",
"//utility/src/main/java/org/oppia/android/util/logging:prod_module",
"//utility/src/main/java/org/oppia/android/util/networking:debug_module",
"//utility/src/main/java/org/oppia/android/util/system:prod_module",
],
)

dagger_rules()
Loading