and ordered lists leading margin span. */
+class ListItemLeadingMarginSpanTestActivity : InjectableAppCompatActivity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ (activityComponent as ActivityComponentImpl).inject(this)
+ setContentView(R.layout.test_list_item_leading_margin_activity)
+ }
+}
diff --git a/app/src/main/java/org/oppia/android/app/testing/PoliciesFragmentTestActivity.kt b/app/src/main/java/org/oppia/android/app/testing/PoliciesFragmentTestActivity.kt
new file mode 100644
index 00000000000..e85b14b61f6
--- /dev/null
+++ b/app/src/main/java/org/oppia/android/app/testing/PoliciesFragmentTestActivity.kt
@@ -0,0 +1,49 @@
+package org.oppia.android.app.testing
+
+import android.content.Context
+import android.content.Intent
+import android.os.Bundle
+import org.oppia.android.app.activity.ActivityComponentImpl
+import org.oppia.android.app.activity.InjectableAppCompatActivity
+import org.oppia.android.app.model.PoliciesActivityParams
+import org.oppia.android.app.model.PolicyPage
+import org.oppia.android.util.extensions.getProtoExtra
+import org.oppia.android.util.extensions.putProtoExtra
+import javax.inject.Inject
+
+/** Test Activity used for testing [PoliciesFragment] */
+class PoliciesFragmentTestActivity : InjectableAppCompatActivity() {
+
+ @Inject
+ lateinit var policiesFragmentTestActivityPresenter: PoliciesFragmentTestActivityPresenter
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ (activityComponent as ActivityComponentImpl).inject(this)
+
+ policiesFragmentTestActivityPresenter.handleOnCreate(
+ intent.getProtoExtra(
+ POLICIES_FRAGMENT_TEST_POLICY_PAGE_PARAMS_PROTO,
+ PoliciesActivityParams.getDefaultInstance()
+ )
+ )
+ }
+
+ companion object {
+ /** Argument key for policy page in [PoliciesFragmentTestActivity]. */
+ const val POLICIES_FRAGMENT_TEST_POLICY_PAGE_PARAMS_PROTO =
+ "PoliciesFragmentTestActivity.policy_page"
+
+ /** Returns the [Intent] for opening [PoliciesFragmentTestActivity] for the specified [policyPage]. */
+ fun createPoliciesFragmentTestActivity(context: Context, policyPage: PolicyPage): Intent {
+ val policiesActivityParams =
+ PoliciesActivityParams
+ .newBuilder()
+ .setPolicyPage(policyPage)
+ .build()
+ return Intent(context, PoliciesFragmentTestActivity::class.java).also {
+ it.putProtoExtra(POLICIES_FRAGMENT_TEST_POLICY_PAGE_PARAMS_PROTO, policiesActivityParams)
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/org/oppia/android/app/testing/PoliciesFragmentTestActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/testing/PoliciesFragmentTestActivityPresenter.kt
new file mode 100644
index 00000000000..acacdf432c0
--- /dev/null
+++ b/app/src/main/java/org/oppia/android/app/testing/PoliciesFragmentTestActivityPresenter.kt
@@ -0,0 +1,44 @@
+package org.oppia.android.app.testing
+
+import androidx.appcompat.app.AppCompatActivity
+import org.oppia.android.R
+import org.oppia.android.app.activity.ActivityScope
+import org.oppia.android.app.model.PoliciesActivityParams
+import org.oppia.android.app.model.PoliciesFragmentArguments
+import org.oppia.android.app.policies.PoliciesFragment
+import javax.inject.Inject
+
+/** The presenter for [PoliciesFragmentTestActivity] */
+@ActivityScope
+class PoliciesFragmentTestActivityPresenter @Inject constructor(
+ private val activity: AppCompatActivity
+) {
+
+ /** Handles onCreate() method of the [PoliciesFragmentTestActivity]. */
+ fun handleOnCreate(policiesActivityParams: PoliciesActivityParams) {
+ activity.setContentView(R.layout.policies_fragment_test_activity)
+ if (getPoliciesFragment() == null) {
+ val policiesFragmentArguments =
+ PoliciesFragmentArguments
+ .newBuilder()
+ .setPolicyPage(policiesActivityParams.policyPage)
+ .build()
+ val policiesFragment: PoliciesFragment =
+ PoliciesFragment.newInstance(policiesFragmentArguments)
+
+ activity
+ .supportFragmentManager
+ .beginTransaction()
+ .add(
+ R.id.policies_fragment_placeholder,
+ policiesFragment
+ ).commitNow()
+ }
+ }
+
+ private fun getPoliciesFragment(): PoliciesFragment? {
+ return activity
+ .supportFragmentManager
+ .findFragmentById(R.id.policies_fragment_placeholder) as PoliciesFragment?
+ }
+}
diff --git a/app/src/main/java/org/oppia/android/app/topic/conceptcard/ConceptCardFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/topic/conceptcard/ConceptCardFragmentPresenter.kt
index 28c8d1b8415..4b731ea971f 100644
--- a/app/src/main/java/org/oppia/android/app/topic/conceptcard/ConceptCardFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/conceptcard/ConceptCardFragmentPresenter.kt
@@ -7,6 +7,7 @@ import androidx.fragment.app.Fragment
import org.oppia.android.R
import org.oppia.android.app.fragment.FragmentScope
import org.oppia.android.app.model.ProfileId
+import org.oppia.android.app.translation.AppLanguageResourceHandler
import org.oppia.android.app.viewmodel.ViewModelProvider
import org.oppia.android.databinding.ConceptCardFragmentBinding
import org.oppia.android.domain.oppialogger.OppiaLogger
@@ -25,7 +26,8 @@ class ConceptCardFragmentPresenter @Inject constructor(
@ConceptCardHtmlParserEntityType private val entityType: String,
@DefaultResourceBucketName private val resourceBucketName: String,
private val viewModelProvider: ViewModelProvider,
- private val translationController: TranslationController
+ private val translationController: TranslationController,
+ private val appLanguageResourceHandler: AppLanguageResourceHandler
) {
/**
* Sets up data binding and toolbar.
@@ -70,8 +72,16 @@ class ConceptCardFragmentPresenter @Inject constructor(
ephemeralConceptCard.writtenTranslationContext
)
view.text = htmlParserFactory
- .create(resourceBucketName, entityType, skillId, imageCenterAlign = true)
- .parseOppiaHtml(explanationHtml, view)
+ .create(
+ resourceBucketName,
+ entityType,
+ skillId,
+ imageCenterAlign = true,
+ displayLocale = appLanguageResourceHandler.getDisplayLocale()
+ )
+ .parseOppiaHtml(
+ explanationHtml, view
+ )
}
)
diff --git a/app/src/main/java/org/oppia/android/app/topic/info/TopicInfoFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/topic/info/TopicInfoFragmentPresenter.kt
index 9195ce8ebb5..b7c0cda88cf 100644
--- a/app/src/main/java/org/oppia/android/app/topic/info/TopicInfoFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/info/TopicInfoFragmentPresenter.kt
@@ -34,15 +34,6 @@ class TopicInfoFragmentPresenter @Inject constructor(
private val topicInfoViewModel = getTopicInfoViewModel()
private var internalProfileId: Int = -1
private lateinit var topicId: String
- private val htmlParser: HtmlParser by lazy {
- htmlParserFactory
- .create(
- resourceBucketName,
- /* entityType= */ "topic",
- topicId,
- /* imageCenterAlign= */ true
- )
- }
fun handleCreateView(
inflater: LayoutInflater,
diff --git a/app/src/main/java/org/oppia/android/app/topic/revisioncard/RevisionCardFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/topic/revisioncard/RevisionCardFragmentPresenter.kt
index f83db2ce970..35d2c496e22 100755
--- a/app/src/main/java/org/oppia/android/app/topic/revisioncard/RevisionCardFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/topic/revisioncard/RevisionCardFragmentPresenter.kt
@@ -8,6 +8,7 @@ import org.oppia.android.app.fragment.FragmentScope
import org.oppia.android.app.model.ProfileId
import org.oppia.android.app.topic.conceptcard.ConceptCardFragment
import org.oppia.android.app.topic.conceptcard.ConceptCardFragment.Companion.CONCEPT_CARD_DIALOG_FRAGMENT_TAG
+import org.oppia.android.app.translation.AppLanguageResourceHandler
import org.oppia.android.app.viewmodel.ViewModelProvider
import org.oppia.android.databinding.RevisionCardFragmentBinding
import org.oppia.android.domain.oppialogger.OppiaLogger
@@ -26,7 +27,8 @@ class RevisionCardFragmentPresenter @Inject constructor(
@DefaultResourceBucketName private val resourceBucketName: String,
@TopicHtmlParserEntityType private val entityType: String,
private val viewModelProvider: ViewModelProvider,
- private val translationController: TranslationController
+ private val translationController: TranslationController,
+ private val appLanguageResourceHandler: AppLanguageResourceHandler
) : HtmlParser.CustomOppiaTagActionListener {
private lateinit var profileId: ProfileId
@@ -66,7 +68,8 @@ class RevisionCardFragmentPresenter @Inject constructor(
)
view.text = htmlParserFactory.create(
resourceBucketName, entityType, topicId, imageCenterAlign = true,
- customOppiaTagActionListener = this
+ customOppiaTagActionListener = this,
+ displayLocale = appLanguageResourceHandler.getDisplayLocale()
).parseOppiaHtml(
pageContentsHtml, view, supportsLinks = true, supportsConceptCards = true
)
diff --git a/app/src/main/java/org/oppia/android/app/translation/AppLanguageResourceHandler.kt b/app/src/main/java/org/oppia/android/app/translation/AppLanguageResourceHandler.kt
index 4887f41175a..dc31fe5ccd2 100644
--- a/app/src/main/java/org/oppia/android/app/translation/AppLanguageResourceHandler.kt
+++ b/app/src/main/java/org/oppia/android/app/translation/AppLanguageResourceHandler.kt
@@ -132,6 +132,7 @@ class AppLanguageResourceHandler @Inject constructor(
/** See [OppiaLocale.DisplayLocale.getLayoutDirection]. */
fun getLayoutDirection(): Int = getDisplayLocale().getLayoutDirection()
- private fun getDisplayLocale(): OppiaLocale.DisplayLocale =
+ /** Returns the current [OppiaLocale.DisplayLocale] used for resource processing. */
+ fun getDisplayLocale(): OppiaLocale.DisplayLocale =
appLanguageLocaleHandler.getDisplayLocale()
}
diff --git a/app/src/main/res/layout-land/onboarding_slide_final.xml b/app/src/main/res/layout-land/onboarding_slide_final.xml
index 02e4afdb540..365ca188dc6 100644
--- a/app/src/main/res/layout-land/onboarding_slide_final.xml
+++ b/app/src/main/res/layout-land/onboarding_slide_final.xml
@@ -80,6 +80,21 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/slide_image_view"
app:layout_constraintTop_toBottomOf="@id/slide_description_text_view" />
+
+
+
diff --git a/app/src/main/res/layout-sw600dp-land/onboarding_slide_final.xml b/app/src/main/res/layout-sw600dp-land/onboarding_slide_final.xml
index df1ed7a87b6..2e7a4b532a8 100644
--- a/app/src/main/res/layout-sw600dp-land/onboarding_slide_final.xml
+++ b/app/src/main/res/layout-sw600dp-land/onboarding_slide_final.xml
@@ -75,6 +75,16 @@
app:layout_constraintStart_toStartOf="@+id/slide_title_text_view"
app:layout_constraintTop_toBottomOf="@id/slide_description_text_view" />
+
+
+
+
+
diff --git a/app/src/main/res/layout/onboarding_slide_final.xml b/app/src/main/res/layout/onboarding_slide_final.xml
index 04b32e15546..a4dc71c819d 100644
--- a/app/src/main/res/layout/onboarding_slide_final.xml
+++ b/app/src/main/res/layout/onboarding_slide_final.xml
@@ -83,6 +83,20 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/slide_description_text_view" />
+
+
+
diff --git a/app/src/main/res/layout/policies_activity.xml b/app/src/main/res/layout/policies_activity.xml
new file mode 100644
index 00000000000..49f40041965
--- /dev/null
+++ b/app/src/main/res/layout/policies_activity.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/policies_fragment.xml b/app/src/main/res/layout/policies_fragment.xml
new file mode 100644
index 00000000000..4fe60b6af41
--- /dev/null
+++ b/app/src/main/res/layout/policies_fragment.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/policies_fragment_test_activity.xml b/app/src/main/res/layout/policies_fragment_test_activity.xml
new file mode 100644
index 00000000000..4a50b06e26e
--- /dev/null
+++ b/app/src/main/res/layout/policies_fragment_test_activity.xml
@@ -0,0 +1,7 @@
+
+
diff --git a/app/src/main/res/layout/test_list_item_leading_margin_activity.xml b/app/src/main/res/layout/test_list_item_leading_margin_activity.xml
new file mode 100644
index 00000000000..07dc89231ee
--- /dev/null
+++ b/app/src/main/res/layout/test_list_item_leading_margin_activity.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
diff --git a/app/src/main/res/layout/view_event_logs_event_log_item_view.xml b/app/src/main/res/layout/view_event_logs_event_log_item_view.xml
index 47849bce089..82af9772cc6 100644
--- a/app/src/main/res/layout/view_event_logs_event_log_item_view.xml
+++ b/app/src/main/res/layout/view_event_logs_event_log_item_view.xml
@@ -42,7 +42,7 @@
36dp
60dp60dp
+
+
+ 24dp
+ 22dp
+ 28dp
+ 60dp
+ 80dp
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index 55dbf12bbd3..7e1c6fc8d9f 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -442,6 +442,13 @@
60dp80dp
+
+ 24dp
+ 22dp
+ 28dp
+ 60dp
+ 80dp
+
80dp60dp
diff --git a/app/src/main/res/values/privacy_policy.xml b/app/src/main/res/values/privacy_policy.xml
new file mode 100644
index 00000000000..68a03b643e0
--- /dev/null
+++ b/app/src/main/res/values/privacy_policy.xml
@@ -0,0 +1,401 @@
+
+
+
+ Oppia\'s mission is to make it easy for users to learn anything they
+ want to in an effective and enjoyable way. As part of achieving that
+ mission, Oppia (also "we" or "us") collects some information from its
+ users to deliver an interactive and engaging experience. This Privacy
+ Policy describes the types of information we collect from users of the
+ Oppia website (https://www.oppia.org)
+ (the "Site") and how Oppia collects, uses, discloses, and protects that
+ information. By using the Site or providing Personal Information (as
+ defined below) to us, you agree to this Privacy Policy.
+
+
+
+ Please note that the Oppia codebase (i.e., our software code, but not
+ any Personal Information we have collected from our users) may be
+ downloaded and hosted independently by third parties. This Privacy
+ Policy covers only our Site and not third-party sites or services using
+ the Oppia codebase. If you are using such a third-party site or service,
+ we encourage you to review the third party\'s privacy policy for that
+ site or service.
+
+
+
What information do we collect and how do we use it?
+
+
Personal Information
+
+
+ The Site is designed to be open and free, which means that you do not
+ have to register, create an account or sign in to use the Site. If you
+ do choose to register with the Site, we collect certain information that
+ identifies you as an individual or relates to you as an identifiable
+ person ("Personal Information"), including:
+
+
your email address;
+
your user name;
+
your photo (if you choose to upload one); and
+
+ any other Personal Information you submit to us during your profile
+ registration process ("Profile Information") or on any forms or
+ other input fields on the Site.
+
+
+
+
+
+ If you disclose any Personal Information relating to other people to us
+ in connection with the Site, you represent that you have the authority
+ to do so and to permit us to use and disclose the information in
+ accordance with this Privacy Policy.
+
+
+
+ We may use Personal Information:
+
+
+ to respond to your inquiries and fulfill your requests, such as to
+ send you updates regarding the Site;
+
+
+ to send administrative information to you, such as information
+ regarding the Site and changes to our terms, conditions, and
+ policies;
+
+
to send you information about the Site and other offerings;
+
to provide you with technical support and customer service;
+
+ to personalize your experience on the Site by suggesting new
+ educational activities, including but not limited to the
+ Explorations, Collections and Questions accessible on the Site (the
+ "Lessons"), for you to try and by helping you to track your
+ progress;
+
+
+ to allow you to provide feedback to and receive feedback from
+ other users on Lessons;
+
+
+ to allow you to participate in contests and similar promotions and
+ to administer these activities, some of which may have additional
+ rules about how we use and disclose your Personal Information. We
+ suggest that you read any such rules carefully;
+
+
to facilitate social sharing functionality; and
+
+ for our business purposes, such as data analysis, audits, fraud
+ monitoring and prevention, developing new products, providing
+ technical fixes, enhancing, improving or modifying our products or
+ services, identifying usage trends, determining the effectiveness
+ of our promotional campaigns and operating and expanding our
+ business activities.
+
+
+
+
+
Other Information
+
+
+ "Other Information" is information that does not reveal your specific
+ identity or does not relate to you as an identifiable person, including:
+
+
+ "Usage Data", such as:
+
+
your answers to Lessons;
+
when you begin and end a Lesson;
+
when you visit the site;
+
what pages you visit while using the Site;
+
+ the page from which you navigated to the Site and the page to
+ which you navigate when you leave the Site;
+
+
+ any playthrough-specific customizations to a Lesson (such as
+ randomly generated parameters);
+
+
+ any contributions you make to the Site (such as feedback on
+ Lessons, edits to Lessons, and Lessons created);
+
+
+
+
+
+ browser and device information, such as:
+
+
the IP address of the computer used to access the Site;
+
what browser or device you are using to visit the Site;
+
what operating system you are using;
+
+
+
+
+ information collected through cookies, pixel tags and other
+ technologies;
+
+
+ demographic information and other information disclosed by you; and
+
+
aggregated information
+
+
+
+
+ Usage Data:
+ We collect information when a user, whether or not the user is signed
+ in, visits the Site. We use Usage Data to guide the learning experience,
+ to evaluate the effectiveness of contributions, to improve our
+ understanding of the learning process and to otherwise improve the
+ effectiveness of our offerings. We do not correlate Usage Data with
+ Personal Information unless the user has created an account and signed
+ in, in which case only Usage Data collected or generated by the user
+ related to Lessons is correlated with the user\'s account.
+
+
+
+ Browser and device information:
+ Certain information is collected by most browsers or automatically
+ through your device, such as your Media Access Control (MAC) address,
+ computer type (Windows or Macintosh), screen resolution, operating
+ system name and version, device manufacturer and model, language and
+ Internet browser type and version. We use this information to ensure
+ that the Site functions properly and to better understand our users.
+
+
+
+ Cookies:
+ We may collect Other Information through the use of cookies. Cookies
+ are small text files with a string of alphanumeric characters that keep
+ track of user activities, stored directly on the computer you are using.
+ Cookies allow us to collect information such as browser type, time
+ spent on the Site, pages visited, language preferences, and other
+ traffic data.
+
+
+
+ If, during your visit to our Site, you do not want information
+ collected through the use of cookies, you may change the settings on
+ your browser to automatically decline cookies, to give you the choice
+ of declining or accepting the cookies from a particular site on a
+ case-by-case basis, or, in some instances, to automatically delete
+ cookies upon exiting the browser. You may also wish to refer to
+ http://www.allaboutcookies.org/manage-cookies/index.html.
+ If you choose not to accept cookies from our Site, you may
+ experience some reduced functionality or other inconvenience while
+ accessing the Site.
+
+
+
We do not respond to browser do-not-track signals at this time.
+
+
+ Using pixel tags and other similar technologies:
+ Pixel tags (also known as web beacons and clear GIFs) may be used in
+ connection with the Site to, among other things, track the actions of
+ users, measure the success of our marketing campaigns and compile
+ statistics about use of the Site.
+
+
+
+ Google Services:
+ Our Site is built on Google App Engine, which uses cookies and performs
+ default request logging. We also use Google Analytics to better
+ understand how our users use our Site. Google Analytics uses cookies
+ and other technologies to collect this information. For further
+ information about the collection and use of data through Google
+ Analytics, please refer to: https://www.google.com/policies/privacy/partners/.
+
+
+
+ Google offers the ability to opt out from tracking through Google
+ Analytics cookies; for more information, visit:
+ https://tools.google.com/dlpage/gaoptout.
+
+
+
+ IP Address:
+ Your IP address is a number that is automatically assigned to the
+ computer that you are using by your Internet Service Provider. An IP
+ address may be identified and logged automatically in our server log
+ files whenever a user accesses the Site, along with the time of the
+ visit and the pages visited. Collecting IP addresses is standard
+ practice and is done automatically by many websites, applications and
+ other services. We use IP addresses for purposes such as calculating
+ usage levels, diagnosing server problems and administering the Site.
+
+
+
+ From you:
+ Information such as your preferred means of communication is collected
+ when you voluntarily disclose it.
+
+
+
+ By aggregating information:
+ Aggregated Personal Information does not personally identify you or any
+ other user of the Site.
+
+
+
+ We may use and disclose Other Information for any purpose, except where
+ we are required to do otherwise under applicable law. If we combine
+ Other Information with Personal Information, we will treat the combined
+ information as Personal Information as long as it is combined. If we
+ are required to treat Other Information as Personal Information under
+ applicable law, then we may use it for the purposes for which we use
+ and disclose Personal Information as detailed in this Privacy Policy.
+
+
+
How is your information shared or disclosed?
+
+
+ Your Personal Information may be disclosed:
+
+
+ to our service providers (including Google) who provide services
+ such as website hosting, data analysis, information technology and
+ related infrastructure provision, customer service, email delivery,
+ auditing and other services;
+
+
to third-party sponsors of contests and similar promotions;
+
+ to identify you to anyone to whom you send messages or feedback
+ through the Site;
+
+
+ by you, on or through your profile page (including your Profile
+ Information), and your messages, edits and contributions to the
+ Site and feedback to us or other users. Please note that any
+ information you choose to post or disclose will become public and
+ may be available to other users and the general public. We urge you
+ to be thoughtful when deciding to disclose any information on the
+ Site.
+
+
+ to your friends associated with your social media account
+ (including, but not limited to, your Google Plus account), to other
+ Site users and to your social media account provider, in connection
+ with your social sharing activity. By connecting your Site account
+ and your social media account, you authorize us to share
+ information with your social media account provider, and you
+ understand that the use of the information we share will be
+ governed by the social media site\'s privacy policy.
+
+
+
+
+
+ We also reserve the right to disclose Personal Information or other
+ information: (a) to comply with applicable legal requirements (for
+ example, responding to subpoenas); (b) to respond to requests from
+ public and government authorities; (c) to enforce our Terms of Use;
+ (d) to protect our, your, and/or third parties\' rights, privacy, safety
+ or property; (e) to allow us to pursue available remedies or limit the
+ damages that we may sustain; and (f) in connection with a
+ reorganization, merger, sale, joint venture, assignment, transfer, or
+ other disposition of all or any portion of our business, assets or
+ stock (including in connection with any bankruptcy or similar
+ proceedings).
+
+
+
How do we protect Personal Information?
+
+ Oppia is committed to protecting your information. We seek to use
+ reasonable organizational, technical and administrative measures to
+ protect Personal Information that we maintain within our organization.
+ We also seek to use third-party service providers capable of protecting
+ the information they maintain or process for us. Unfortunately, no
+ data transmission or storage system can be guaranteed to be 100%
+ secure. If you have reason to believe that your data has been
+ compromised or your use of the Site is no longer secure, please
+ immediately notify us of the problem by contacting us at the following
+ email address: admin@oppia.org.
+
+
+
Choices and access
+
+ If you register and provide Oppia with Personal Information, you may
+ update or delete your Personal Information at any time by reviewing
+ your Profile Information and preferences on your account settings page
+ or by contacting us at admin@oppia.org. The only exception is that we
+ cannot allow users to change their email address or username.
+
+
+
+ If you no longer want to receive marketing-related emails from us on a
+ going-forward basis, you may opt out by following the instructions
+ contained in each such email. We will try to comply with your request
+ as soon as reasonably practicable. Please note that if you opt out, we
+ may still send you important administrative messages, from which you
+ cannot opt out.
+
+
+
+ If you are a resident of California, under 18, and a registered user of
+ the Site, you may ask us to remove content or information that you have
+ posted to the Site by writing to admin@oppia.org. Please note that your
+ request does not ensure complete or comprehensive removal of the
+ content or information, as, for example, some of your content may have
+ been reposted by another user.
+
+
+
Use by children
+
+ The Site is not directed to individuals under the age of thirteen (13).
+ If you are under 13, we do not want your Personal Information and you
+ should not provide it to us. If you are a legal guardian and believe
+ that your child who is under 13 has provided us with Personal
+ Information, please contact us at admin@oppia.org to have your child\'s
+ information removed.
+
+
+
Jurisdictional issues
+
+ The Site is controlled and operated by us from the United States, and
+ is not intended to subject us to the laws or jurisdiction of any state,
+ country or territory other than that of the United States. Your
+ Personal Information may be stored and processed in any country where
+ we or our service providers have facilities, and by using the Site you
+ consent to the transfer of information to countries outside of your
+ country of residence, including the United States, which may have
+ different data protection rules than those of your country. In certain
+ circumstances, courts, law enforcement agencies, regulatory agencies or
+ security authorities in those other countries may be entitled to access
+ your Personal Information.
+
+
+
Links to third-party sites
+
+ Our Site and content may feature links to third party websites that
+ offer goods, services or information. When you click on one of these
+ links, you will be leaving our Site and will no longer be subject to
+ this Privacy Policy. We are not responsible for the information or other
+ practices of the other sites that you visit and urge you to review
+ their privacy policies before you provide them with any personally
+ identifiable information. Third party sites or services may collect and
+ use information about you in a way that is different from this Privacy
+ Policy.
+
+
+
Changes and updates to this Privacy Policy
+
+ Oppia will continue to evolve and we may update our Privacy Policy from
+ time to time to reflect our practices. The "Last updated" legend at the
+ bottom of this Privacy Policy indicates when this Privacy Policy was
+ last revised, and any changes will become effective immediately upon
+ posting of the Privacy Policy on the Site. Your continued use of the
+ Site following these changes constitutes your agreement to the revised
+ Privacy Policy.
+
+
+
Contacting Us
+
+ If you have questions about this Privacy Policy or would like to
+ provide feedback, please send an e-mail to admin@oppia.org.
+
+
+ Last updated: 24 May 2018
+]]>
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 8851ba79912..dbb8d131dbb 100755
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -526,6 +526,14 @@
Good morning,Good afternoon,Good evening,
+
+ Policy Page
+ Privacy Policy
+ this page for the latest version of this privacy policy.]]>
+
+ Terms of Service
+ Terms of Service and Privacy Policy.]]>
+ this page for the latest version of these terms.]]>How can I create a new profile?How can I delete a profile?
@@ -536,14 +544,14 @@
Why is my audio not playing?How do I download a Topic?I can\'t find my question here. What now?
- If it is your first time creating a profile and not have a PIN:
1. From the Profile Chooser, tap on Set up Multiple Profiles.
2. Create a PIN and Save.
3. Fill in all fields for the profile.
(Optional) Upload a photo.
Enter a name.
(Optional) Assign a 3-digit PIN.
4. Tap Create. This profile is added to your Profile Chooser!
If you have created a profile before and have a PIN:
1. From the Profile Chooser, tap on Add Profile.
2. Enter your PIN and tap Submit.
3. Fill in all fields for the profile.
(Optional) Upload a photo.
Enter a name.
(Optional) Assign a 3-digit PIN.
4. Tap Create. This profile is added to your Profile Chooser!
Note: Only the Administrator is able to manage profiles.
]]>
- Once a profile is deleted:
The profile cannot be recovered.
Profile information such as name, photos, and progress will be permanently deleted.
To delete a profile (excluding the Administrator\'s):
1. From the Administrator\'s Home Page, tap on the menu button on the top left.
2. Tap on Administrator Controls.
3. Tap on Edit Profiles.
4. Tap on the Profile you would like to delete.
5. At the bottom of the screen, tap Profile Deletion.
6. Tap Delete to confirm deletion.
Note: Only the Administrator is able to manage profiles.
]]>
- To change your email/phone number:
1. From the Administrator\'s Home Page, tap on the menu button on the top left.
2. Tap on Administrator Controls.
3. Tap on Edit Account.
If you want to change your email:
4. Enter your new email and tap Save.
5. A confirmation link is sent to confirm your new email. The link will expire after 24 hours and must be clicked on to be associated with your account.
If changing your phone number:
4. Enter your new phone number and tap Verify.
5. A code is sent to confirm your new number. The code will expire after 5 minutes and must be entered in the new screen to be associated with your account.
]]>
+ If it is your first time creating a profile and not have a PIN:
From the Profile Chooser, tap on Set up Multiple Profiles.
Create a PIN and Save.
Fill in all fields for the profile.
(Optional) Upload a photo.
Enter a name.
(Optional) Assign a 3-digit PIN.
Tap Create. This profile is added to your Profile Chooser!
If you have created a profile before and have a PIN:
From the Profile Chooser, tap on Add Profile.
Enter your PIN and tap Submit.
Fill in all fields for the profile.
(Optional) Upload a photo.
Enter a name.
(Optional) Assign a 3-digit PIN.
Tap Create. This profile is added to your Profile Chooser!
Note: Only the Administrator is able to manage profiles.
]]>
+ Once a profile is deleted:
The profile cannot be recovered.
Profile information such as name, photos, and progress will be permanently deleted.
To delete a profile (excluding the Administrator\'s):
From the Administrator\'s Home Page, tap on the menu button on the top left.
Tap on Administrator Controls.
Tap on Edit Profiles.
Tap on the Profile you would like to delete.
At the bottom of the screen, tap Profile Deletion.
Tap Delete to confirm deletion.
Note: Only the Administrator is able to manage profiles.
]]>
+ To change your email/phone number:
From the Administrator\'s Home Page, tap on the menu button on the top left.
Tap on Administrator Controls.
Tap on Edit Account.
If you want to change your email:
Enter your new email and tap Save.
A confirmation link is sent to confirm your new email. The link will expire after 24 hours and must be clicked on to be associated with your account.
If changing your phone number:
Enter your new phone number and tap Verify.
A code is sent to confirm your new number. The code will expire after 5 minutes and must be entered in the new screen to be associated with your account.
]]>%1$s \"O-pee-yah\" (Finnish) - \"to learn\"
%1$s\'s mission is to help anyone learn anything they want in an effective and enjoyable way.
By creating a set of free, high-quality, demonstrably effective lessons with the help of educators from around the world, %1$s aims to provide students with quality education — regardless of where they are or what traditional resources they have access to.
As a student, you can begin your learning adventure by browsing the topics listed on the Home Page!
]]>An Administrator is the main user that manages profiles and settings for every profile on their account. They are most likely your parent, teacher, or guardian that created this profile for you.
Administrators have the ability to manage profiles, assign PINs, and change other settings under their account. Depending on your profile, Administrator permissions may be required for certain features such as downloading Topics, changing your PIN, and more.
To see who your Administrator is, go to the Profile Chooser. The first profile listed and has \"Administrator\" written under their name is the Administrator.
]]>
- If the Exploration Player is not loading
Check to see if the app is up to date:
Go to the Play Store and make sure the app is updated to its latest version
Check your internet connection:
If your internet connection is slow, try re-connecting to your Wi-Fi network or connecting to a different network.
Ask the Administrator to check their device and internet connection:
Get the Administrator to troubleshoot using the steps above
Let us know if you still have issues with loading:
Report a problem by contacting us at admin@oppia.org.
]]>
- If your audio is not playing
Check to see if the app is up to date:
Go to the Play Store and make sure the app is updated to its latest version
Check your internet connection:
If your internet connection is slow, try re-connecting to your Wi-Fi network or connecting to a different network. Slow internet may cause the audio to load irregularly, making it difficult to play.
Ask the Administrator to check their device and internet connection:
Get the Administrator to troubleshoot using the steps above
Let us know if you still have issues with loading:
Report a problem by contacting us at admin@oppia.org.
]]>
- To download an Exploration:
1. From the Home Page, tap on a Topic or Exploration.
2. From that Topic Page, tap on the Info tab.
3. Tap on Download Topic.
4. Depending on your app settings, you may need Administrator approval or stable Wifi connection to complete your download. If needed, once these requirements are satisfied, the Topic has been downloaded onto the device and can be used offline by all profiles.
]]>
+ If the Exploration Player is not loading
Check to see if the app is up to date:
Go to the Play Store and make sure the app is updated to its latest version
Check your internet connection:
If your internet connection is slow, try re-connecting to your Wi-Fi network or connecting to a different network.
Ask the Administrator to check their device and internet connection:
Get the Administrator to troubleshoot using the steps above
Let us know if you still have issues with loading:
Report a problem by contacting us at admin@oppia.org.
]]>
+ If your audio is not playing
Check to see if the app is up to date:
Go to the Play Store and make sure the app is updated to its latest version
Check your internet connection:
If your internet connection is slow, try re-connecting to your Wi-Fi network or connecting to a different network. Slow internet may cause the audio to load irregularly, making it difficult to play.
Ask the Administrator to check their device and internet connection:
Get the Administrator to troubleshoot using the steps above
Let us know if you still have issues with loading:
Report a problem by contacting us at admin@oppia.org.
]]>
+ To download an Exploration:
From the Home Page, tap on a Topic or Exploration.
From that Topic Page, tap on the Info tab.
Tap on Download Topic.
Depending on your app settings, you may need Administrator approval or stable Wifi connection to complete your download. If needed, once these requirements are satisfied, the Topic has been downloaded onto the device and can be used offline by all profiles.
]]>
If you cannot find your question or would like to report a bug, contact us at admin@oppia.org.]]>Profile Edit Fragment Test ActivityAdministrator Controls Fragment Test Activity
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index d7237b66bd2..68d1bd223a4 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -256,6 +256,10 @@
@color/component_color_shared_text_view_heading_text_color
+
+
@@ -311,10 +315,14 @@
viewStart
-
+
+
diff --git a/app/src/main/res/values/component_colors.xml b/app/src/main/res/values/component_colors.xml
index 47385886ac9..a6683108bbd 100644
--- a/app/src/main/res/values/component_colors.xml
+++ b/app/src/main/res/values/component_colors.xml
@@ -214,4 +214,12 @@
@color/color_palette_dark_text_color@color/color_palette_dark_background_color
+
+ @color/color_palette_container_background_color
+ @color/color_palette_dark_text_color
+
+ @color/color_palette_dark_text_color
+
+ @color/color_palette_dark_text_color
+
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
index eec60bb6ce4..b599f82a52f 100644
--- a/app/src/main/res/values/themes.xml
+++ b/app/src/main/res/values/themes.xml
@@ -28,6 +28,8 @@
diff --git a/app/src/main/res/values/color_defs.xml b/app/src/main/res/values/color_defs.xml
index d0ab46278b6..8604a4de10a 100644
--- a/app/src/main/res/values/color_defs.xml
+++ b/app/src/main/res/values/color_defs.xml
@@ -71,4 +71,7 @@
#00C7B6#E5E5E5#008577
+ #777777
+ #F7F7F7
+ #DCDCDC
diff --git a/app/src/main/res/values/color_palette.xml b/app/src/main/res/values/color_palette.xml
index 38d1acfe686..24ea7e5c2df 100644
--- a/app/src/main/res/values/color_palette.xml
+++ b/app/src/main/res/values/color_palette.xml
@@ -72,4 +72,20 @@
@color/color_def_dark_silver@color/color_def_oppia_grey_background@color/color_def_white
+ @color/color_def_spanish_grey
+ @color/color_def_error_text
+ @color/color_def_white
+ @color/color_def_black
+ @color/color_def_oppia_dark_blue
+ @color/color_def_mid_grey
+ @color/color_def_mid_grey
+ @color/color_def_accessible_light_grey_2
+ @color/color_def_oppia_dark_blue
+ @color/color_def_white
+ @color/color_def_accessible_grey
+ @color/color_def_drag_drop_single_item_gradient_end
+ @color/color_def_drag_drop_single_item_gradient_center
+ @color/color_def_white
+ @color/color_def_stroke_silver
+ @color/color_def_oppia_dark_blue
diff --git a/app/src/main/res/values/component_colors.xml b/app/src/main/res/values/component_colors.xml
index a6683108bbd..c0f7bc573a6 100644
--- a/app/src/main/res/values/component_colors.xml
+++ b/app/src/main/res/values/component_colors.xml
@@ -1,20 +1,38 @@
- @color/color_palette_primary_text_color
+ @color/color_palette_cursor_color@color/color_palette_toolbar_color@color/color_palette_highlighted_text_color@color/color_palette_highlighted_text_color@color/color_palette_exploration_background_color@color/color_palette_highlighted_text_color@color/color_palette_highlighted_text_color
+ @color/color_palette_highlighted_text_color
+ @color/color_palette_input_error_color
+ @color/color_palette_submitted_answer_item_solid_color
+ @color/color_palette_submitted_answer_item_stroke_color
+ @color/color_palette_highlighted_text_color
+ @color/color_palette_hint_text_input_interaction_color
+ @color/color_palette_input_interaction_edit_text_border_color
+ @color/color_palette_input_interaction_edit_text_not_selected_border_color
+ @color/color_palette_arrow_down_grey_color
+ @color/color_palette_arrow_right_grey_color@color/color_palette_rounded_rect_background_color
+ @color/color_palette_drag_drop_background_color
+ @color/color_palette_oppia_submitted_answer_text_color
+ @color/color_palette_drag_drop_single_item_stroke_color
+ @color/color_palette_drag_drop_single_item_gradient_start_color
+ @color/color_palette_drag_drop_single_item_gradient_center_color
+ @color/color_palette_drag_drop_single_item_gradient_end_color@color/color_palette_multiple_choice_color@color/color_palette_multiple_choice_text_color@color/color_palette_multiple_choice_selected_color@color/color_palette_multiple_choice_selected_text_color
+ @color/color_palette_primary_text_color@color/color_palette_item_selection_color@color/color_palette_item_selection_text_color@color/color_palette_back_arrow_button_color
+ @color/color_palette_forward_arrow_button_color@color/color_palette_replay_button_color@color/color_palette_progress_bar_solid_color@color/color_palette_progress_bar_stroke_color
@@ -40,7 +58,7 @@
@color/color_palette_primary_text_color@color/color_palette_primary_text_color@color/color_palette_primary_text_color
- @color/color_palette_text_input_background_color
+ @color/color_palette_text_input_background_color@color/color_palette_error_color@color/color_palette_container_background_color@color/color_palette_dark_background_color
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index 68d1bd223a4..ab1b29ed346 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -164,7 +164,7 @@
From 64c5b0cfe37d6211ac2398f2f4a049eba7a43086 Mon Sep 17 00:00:00 2001
From: Sarthak Agarwal
Date: Fri, 2 Sep 2022 12:02:37 +0530
Subject: [PATCH 28/57] Fixes #4334: Log report creation support for
performance metrics collection (#4388)
* qualifiers and constants for metric record and upload times
* comments
* dagger provides for flags
* rename to enablePerformanceMetricCollection
* initial proto
* nit fixes
* nit fixes
* comments.
* nits
* nit
* updates.
* updates.
* nits.
* metric log inclusion.
* base setup.
* name correction.
* nits.
* nits.
* storage comment
* pss comment
* network usage comment.
* network usage comment - part 2.
* metric addition in proto definitions.
* metricLog --> loggableMetric
* proto definitions in oppiaLogger
* wording update for transmission
* dependency/api updates.
* nits.
* metric controller and oppiaLogger
* nits
* logger-controller pattern, single utils
* nits
* comments
* performance metric event logger nits.
* nits.
* deleting unused interfaces.
* log generator to metric log scheduler
* nits
* worker functions to schedule logging, renaming
* nits.
* clearing up build errors.
* nits.
* removal of dependency from oppiaLogger and basing the entire implementation on Logger-Controller
* performanceMetricController tests + fakeLogger
* fakeLogger tests
* nits
* tests for the new logger.
* tests for the worker + renaming of package to logScheduler
* tests for work manager initializer
* initial base setup for utils test
* nits
* nits
* performanceMetricsUtils tests
* nits
* renamed logUpload to logReport + nits
* nits
* review updates.
* nit
* review updates - 2
* isAppInForeground revamp
* isAppInForeground revamp
* nits
* domain tests repair
* app tests repair
* nits.
* nits.
* nits.
* nits.
* nit
* test update.
* test update.
* nit
* todo issue number update -- static check
* comments.
* nits.
* utils test + nits
* utils test + nits
* nits
* test rearrangement
* nits
* test fixes.
* nits
* memory and storage tier updates
* memory and storage tier updates
* updates.
* nits
* test file exemptions refactor due to file renaming.
* additional tests, nit fixes.
* activity manager shadow and assessor test
* nit
* nit
* shadow traffic stats + assessor test fix.
* custom shadow tests
* module deps
* tests
* nits
* metricLogScheduler refactor and test
* exemption removal
* nits
* updates.
* variable nits + parameterized test exemption
* app component dependencies.
* nits
* logging module bazel build, config module creation
* testing robolectric bazel module update
* domain bazel build fixes
* working oppia bazel build
* nits.
* nits.
* nit for bazel building
* addition of test file for module
* bazel tests fixes
* more fixes.
* reformatting
* nits
* nits
* dep fix
* deps fix
* deps fix
* nit
* nits
* nits
* test fixes -- renaming.
* deps addition
* previous merge correction
* nits
* updates.
* nits
* bazel update.
* nit
* nits.
---
.../oppia/android/app/application/BUILD.bazel | 4 +
.../alpha/AlphaApplicationComponent.kt | 12 +-
.../AlphaKenyaApplicationComponent.kt | 12 +-
.../dev/DeveloperApplicationComponent.kt | 12 +-
.../AdministratorControlsActivityTest.kt | 7 +-
.../AdministratorControlsFragmentTest.kt | 7 +-
.../AppVersionActivityTest.kt | 7 +-
.../ProfileAndDeviceIdActivityTest.kt | 7 +-
.../ProfileAndDeviceIdFragmentTest.kt | 7 +-
.../CompletedStoryListActivityTest.kt | 7 +-
.../LessonThumbnailImageViewTest.kt | 7 +-
.../MathExpressionInteractionsViewTest.kt | 7 +-
.../DrawableBindingAdaptersTest.kt | 7 +-
.../ImageViewBindingAdaptersTest.kt | 8 +-
.../databinding/MarginBindingAdaptersTest.kt | 8 +-
...StateAssemblerMarginBindingAdaptersTest.kt | 8 +-
...tateAssemblerPaddingBindingAdaptersTest.kt | 8 +-
.../TextViewBindingAdaptersTest.kt | 7 +-
.../databinding/ViewBindingAdaptersTest.kt | 8 +-
.../DeveloperOptionsActivityTest.kt | 7 +-
.../DeveloperOptionsFragmentTest.kt | 7 +-
.../MarkChaptersCompletedActivityTest.kt | 7 +-
.../MarkChaptersCompletedFragmentTest.kt | 7 +-
.../MarkStoriesCompletedActivityTest.kt | 7 +-
.../MarkStoriesCompletedFragmentTest.kt | 7 +-
.../MarkTopicsCompletedActivityTest.kt | 7 +-
.../MarkTopicsCompletedFragmentTest.kt | 7 +-
.../devoptions/ViewEventLogsActivityTest.kt | 10 +-
.../devoptions/ViewEventLogsFragmentTest.kt | 12 +-
.../ForceNetworkTypeActivityTest.kt | 8 +-
.../ForceNetworkTypeFragmentTest.kt | 8 +-
.../MathExpressionParserActivityTest.kt | 7 +-
.../MathExpressionParserFragmentTest.kt | 7 +-
.../android/app/faq/FAQListFragmentTest.kt | 7 +-
.../android/app/faq/FAQSingleActivityTest.kt | 7 +-
.../android/app/faq/FaqListActivityTest.kt | 7 +-
.../android/app/help/HelpActivityTest.kt | 7 +-
.../android/app/help/HelpFragmentTest.kt | 7 +-
.../android/app/home/HomeActivityTest.kt | 7 +-
.../app/home/RecentlyPlayedFragmentTest.kt | 7 +-
.../app/home/TopicSummaryViewModelTest.kt | 7 +-
.../android/app/home/WelcomeViewModelTest.kt | 7 +-
.../PromotedStoryListViewModelTest.kt | 7 +-
.../PromotedStoryViewModelTest.kt | 7 +-
.../mydownloads/MyDownloadsActivityTest.kt | 7 +-
.../mydownloads/MyDownloadsFragmentTest.kt | 7 +-
.../app/onboarding/OnboardingActivityTest.kt | 7 +-
.../app/onboarding/OnboardingFragmentTest.kt | 7 +-
.../OngoingTopicListActivityTest.kt | 7 +-
.../app/options/AppLanguageActivityTest.kt | 7 +-
.../app/options/AppLanguageFragmentTest.kt | 7 +-
.../app/options/AudioLanguageActivityTest.kt | 7 +-
.../app/options/AudioLanguageFragmentTest.kt | 7 +-
.../app/options/OptionsActivityTest.kt | 7 +-
.../app/options/OptionsFragmentTest.kt | 7 +-
.../options/ReadingTextSizeActivityTest.kt | 7 +-
.../options/ReadingTextSizeFragmentTest.kt | 7 +-
.../android/app/parser/HtmlParserTest.kt | 7 +-
.../parser/ListItemLeadingMarginSpanTest.kt | 7 +-
.../app/player/audio/AudioFragmentTest.kt | 7 +-
.../exploration/ExplorationActivityTest.kt | 8 +-
.../app/player/state/StateFragmentTest.kt | 7 +-
.../app/policies/PoliciesActivityTest.kt | 7 +-
.../app/policies/PoliciesFragmentTest.kt | 7 +-
.../app/profile/AddProfileActivityTest.kt | 7 +-
.../app/profile/AdminAuthActivityTest.kt | 7 +-
.../app/profile/AdminPinActivityTest.kt | 7 +-
.../app/profile/PinPasswordActivityTest.kt | 7 +-
.../app/profile/ProfileChooserFragmentTest.kt | 7 +-
.../ProfilePictureActivityTest.kt | 7 +-
.../ProfileProgressActivityTest.kt | 7 +-
.../ProfileProgressFragmentTest.kt | 7 +-
.../app/recyclerview/BindableAdapterTest.kt | 7 +-
.../resumelesson/ResumeLessonActivityTest.kt | 7 +-
.../resumelesson/ResumeLessonFragmentTest.kt | 7 +-
.../profile/ProfileEditActivityTest.kt | 7 +-
.../profile/ProfileEditFragmentTest.kt | 7 +-
.../profile/ProfileListActivityTest.kt | 7 +-
.../profile/ProfileListFragmentTest.kt | 7 +-
.../profile/ProfileRenameActivityTest.kt | 7 +-
.../profile/ProfileRenameFragmentTest.kt | 7 +-
.../profile/ProfileResetPinActivityTest.kt | 7 +-
.../profile/ProfileResetPinFragmentTest.kt | 7 +-
.../android/app/splash/SplashActivityTest.kt | 7 +-
.../android/app/story/StoryActivityTest.kt | 7 +-
.../android/app/story/StoryFragmentTest.kt | 7 +-
.../app/testing/DragDropTestActivityTest.kt | 7 +-
...ImageRegionSelectionInteractionViewTest.kt | 7 +-
.../InputInteractionViewTestActivityTest.kt | 7 +-
.../NavigationDrawerActivityDebugTest.kt | 7 +-
.../NavigationDrawerActivityProdTest.kt | 7 +-
...tFontScaleConfigurationUtilActivityTest.kt | 7 +-
.../testing/TopicTestActivityForStoryTest.kt | 7 +-
.../app/thirdparty/LicenseListActivityTest.kt | 8 +-
.../app/thirdparty/LicenseListFragmentTest.kt | 8 +-
.../LicenseTextViewerActivityTest.kt | 8 +-
.../LicenseTextViewerFragmentTest.kt | 8 +-
.../ThirdPartyDependencyListActivityTest.kt | 8 +-
.../ThirdPartyDependencyListFragmentTest.kt | 8 +-
.../android/app/topic/TopicActivityTest.kt | 7 +-
.../android/app/topic/TopicFragmentTest.kt | 7 +-
.../conceptcard/ConceptCardFragmentTest.kt | 7 +-
.../app/topic/info/TopicInfoFragmentTest.kt | 7 +-
.../topic/lessons/TopicLessonsFragmentTest.kt | 7 +-
.../practice/TopicPracticeFragmentTest.kt | 7 +-
.../QuestionPlayerActivityTest.kt | 7 +-
.../revision/TopicRevisionFragmentTest.kt | 7 +-
.../revisioncard/RevisionCardActivityTest.kt | 7 +-
.../revisioncard/RevisionCardFragmentTest.kt | 7 +-
.../app/utility/RatioExtensionsTest.kt | 7 +-
.../walkthrough/WalkthroughActivityTest.kt | 7 +-
.../WalkthroughFinalFragmentTest.kt | 7 +-
.../WalkthroughTopicListFragmentTest.kt | 7 +-
.../WalkthroughWelcomeFragmentTest.kt | 7 +-
.../activity/ActivityIntentFactoriesTest.kt | 7 +-
.../android/app/home/HomeActivityLocalTest.kt | 7 +-
.../app/parser/FractionParsingUiErrorTest.kt | 7 +-
.../app/parser/StringToRatioParserTest.kt | 7 +-
.../ExplorationActivityLocalTest.kt | 7 +-
.../player/state/StateFragmentLocalTest.kt | 7 +-
.../ProfileChooserFragmentLocalTest.kt | 7 +-
.../app/story/StoryActivityLocalTest.kt | 7 +-
.../app/testing/CompletedStoryListSpanTest.kt | 7 +-
.../oppia/android/app/testing/HomeSpanTest.kt | 7 +-
.../app/testing/OngoingTopicListSpanTest.kt | 7 +-
.../PlatformParameterIntegrationTest.kt | 7 +-
.../app/testing/ProfileChooserSpanTest.kt | 7 +-
.../testing/ProfileProgressSpanCountTest.kt | 7 +-
.../app/testing/RecentlyPlayedSpanTest.kt | 7 +-
.../app/testing/TopicRevisionSpanTest.kt | 7 +-
.../app/testing/activity/TestActivityTest.kt | 7 +-
.../AdministratorControlsFragmentTest.kt | 7 +-
.../testing/options/OptionsFragmentTest.kt | 7 +-
.../player/split/PlayerSplitScreenTest.kt | 7 +-
.../state/StateFragmentAccessibilityTest.kt | 7 +-
.../topic/info/TopicInfoFragmentLocalTest.kt | 7 +-
.../lessons/TopicLessonsFragmentLocalTest.kt | 7 +-
.../QuestionPlayerActivityLocalTest.kt | 7 +-
.../RevisionCardActivityLocalTest.kt | 7 +-
.../AppLanguageResourceHandlerTest.kt | 7 +-
.../AppLanguageWatcherMixinTest.kt | 7 +-
.../MathExpressionAccessibilityUtilTest.kt | 7 +-
domain/BUILD.bazel | 6 +
.../domain/oppialogger/LogStorageModule.kt | 13 +
.../analytics/ApplicationLifecycleObserver.kt | 3 +
.../domain/oppialogger/analytics/BUILD.bazel | 52 ++
.../analytics/PerformanceMetricsController.kt | 193 ++++++
.../analytics/PerformanceMetricsLogger.kt | 305 ++++++++++
.../PerformanceMetricsLoggerModule.kt | 16 +
.../oppialogger/analytics/testing/BUILD.bazel | 22 +
.../analytics/testing/FakeLogScheduler.kt | 58 ++
.../oppialogger/logscheduler/BUILD.bazel | 61 ++
.../logscheduler/MetricLogSchedulerModule.kt | 14 +
.../logscheduler/MetricLogSchedulingWorker.kt | 125 ++++
.../MetricLogSchedulingWorkerFactory.kt | 22 +
.../PerformanceMetricsLogScheduler.kt | 50 ++
.../oppialogger/loguploader/BUILD.bazel | 6 +-
.../LogReportWorkManagerInitializer.kt | 195 ++++++
...rkerModule.kt => LogReportWorkerModule.kt} | 6 +-
.../LogUploadWorkManagerInitializer.kt | 74 ---
.../WorkManagerConfigurationModule.kt | 5 +-
.../ApplicationLifecycleObserverTest.kt | 17 +
.../PerformanceMetricsControllerTest.kt | 555 ++++++++++++++++++
.../PerformanceMetricsLoggerModuleTest.kt | 106 ++++
.../analytics/PerformanceMetricsLoggerTest.kt | 315 ++++++++++
.../analytics/testing/FakeLogSchedulerTest.kt | 182 ++++++
.../MetricLogSchedulerModuleTest.kt | 79 +++
.../MetricLogSchedulingWorkerTest.kt | 292 +++++++++
.../PerformanceMetricsLogSchedulerTest.kt | 205 +++++++
...=> LogReportWorkManagerInitializerTest.kt} | 111 +++-
.../loguploader/LogUploadWorkerTest.kt | 2 +-
.../application/TestApplicationComponent.kt | 12 +-
model/src/main/proto/BUILD.bazel | 11 +
.../src/main/proto/performance_metrics.proto | 12 +-
.../file_content_validation_checks.textproto | 2 +
scripts/assets/test_file_exemptions.textproto | 6 +-
testing/BUILD.bazel | 6 +
.../testing/FakePerformanceMetricAssessor.kt | 67 +++
.../FakePerformanceMetricsEventLogger.kt | 41 ++
.../android/testing/TestLogReportingModule.kt | 12 +
.../android/testing/robolectric/BUILD.bazel | 24 +
.../robolectric/OppiaShadowActivityManager.kt | 54 ++
.../robolectric/OppiaShadowTrafficStats.kt | 57 ++
.../FakePerformanceMetricAssessorTest.kt | 174 ++++++
.../FakePerformanceMetricsEventLoggerTest.kt | 324 ++++++++++
...alizeDefaultLocaleRuleCustomContextTest.kt | 7 +-
...InitializeDefaultLocaleRuleOmissionTest.kt | 7 +-
.../junit/InitializeDefaultLocaleRuleTest.kt | 7 +-
.../OppiaShadowActivityManagerTest.kt | 160 +++++
.../OppiaShadowTrafficStatsTest.kt | 111 ++++
utility/BUILD.bazel | 8 +
.../oppia/android/util/logging/BUILD.bazel | 12 +
.../util/logging/MetricLogScheduler.kt | 31 +
.../android/util/logging/firebase/BUILD.bazel | 2 +
.../firebase/DebugLogReportingModule.kt | 8 +
.../logging/firebase/FirebaseEventLogger.kt | 23 +-
.../logging/firebase/LogReportingModule.kt | 8 +
.../logging/performancemetrics/BUILD.bazel | 71 +++
.../PerformanceMetricsAssessor.kt | 38 ++
.../PerformanceMetricsAssessorImpl.kt | 73 +++
.../PerformanceMetricsAssessorModule.kt | 14 +
.../PerformanceMetricsConfigurationsModule.kt | 51 ++
.../PerformanceMetricsEventLogger.kt | 13 +
.../PerformanceMetricsAssessorImplTest.kt | 343 +++++++++++
.../PerformanceMetricsAssessorModuleTest.kt | 91 +++
...formanceMetricsConfigurationsModuleTest.kt | 121 ++++
206 files changed, 5579 insertions(+), 540 deletions(-)
create mode 100644 domain/src/main/java/org/oppia/android/domain/oppialogger/analytics/PerformanceMetricsController.kt
create mode 100644 domain/src/main/java/org/oppia/android/domain/oppialogger/analytics/PerformanceMetricsLogger.kt
create mode 100644 domain/src/main/java/org/oppia/android/domain/oppialogger/analytics/PerformanceMetricsLoggerModule.kt
create mode 100644 domain/src/main/java/org/oppia/android/domain/oppialogger/analytics/testing/BUILD.bazel
create mode 100644 domain/src/main/java/org/oppia/android/domain/oppialogger/analytics/testing/FakeLogScheduler.kt
create mode 100644 domain/src/main/java/org/oppia/android/domain/oppialogger/logscheduler/BUILD.bazel
create mode 100644 domain/src/main/java/org/oppia/android/domain/oppialogger/logscheduler/MetricLogSchedulerModule.kt
create mode 100644 domain/src/main/java/org/oppia/android/domain/oppialogger/logscheduler/MetricLogSchedulingWorker.kt
create mode 100644 domain/src/main/java/org/oppia/android/domain/oppialogger/logscheduler/MetricLogSchedulingWorkerFactory.kt
create mode 100644 domain/src/main/java/org/oppia/android/domain/oppialogger/logscheduler/PerformanceMetricsLogScheduler.kt
create mode 100644 domain/src/main/java/org/oppia/android/domain/oppialogger/loguploader/LogReportWorkManagerInitializer.kt
rename domain/src/main/java/org/oppia/android/domain/oppialogger/loguploader/{LogUploadWorkerModule.kt => LogReportWorkerModule.kt} (71%)
delete mode 100644 domain/src/main/java/org/oppia/android/domain/oppialogger/loguploader/LogUploadWorkManagerInitializer.kt
create mode 100644 domain/src/test/java/org/oppia/android/domain/oppialogger/analytics/PerformanceMetricsControllerTest.kt
create mode 100644 domain/src/test/java/org/oppia/android/domain/oppialogger/analytics/PerformanceMetricsLoggerModuleTest.kt
create mode 100644 domain/src/test/java/org/oppia/android/domain/oppialogger/analytics/PerformanceMetricsLoggerTest.kt
create mode 100644 domain/src/test/java/org/oppia/android/domain/oppialogger/analytics/testing/FakeLogSchedulerTest.kt
create mode 100644 domain/src/test/java/org/oppia/android/domain/oppialogger/logscheduler/MetricLogSchedulerModuleTest.kt
create mode 100644 domain/src/test/java/org/oppia/android/domain/oppialogger/logscheduler/MetricLogSchedulingWorkerTest.kt
create mode 100644 domain/src/test/java/org/oppia/android/domain/oppialogger/logscheduler/PerformanceMetricsLogSchedulerTest.kt
rename domain/src/test/java/org/oppia/android/domain/oppialogger/loguploader/{LogUploadWorkManagerInitializerTest.kt => LogReportWorkManagerInitializerTest.kt} (59%)
create mode 100644 testing/src/main/java/org/oppia/android/testing/FakePerformanceMetricAssessor.kt
create mode 100644 testing/src/main/java/org/oppia/android/testing/FakePerformanceMetricsEventLogger.kt
create mode 100644 testing/src/main/java/org/oppia/android/testing/robolectric/OppiaShadowActivityManager.kt
create mode 100644 testing/src/main/java/org/oppia/android/testing/robolectric/OppiaShadowTrafficStats.kt
create mode 100644 testing/src/test/java/org/oppia/android/testing/FakePerformanceMetricAssessorTest.kt
create mode 100644 testing/src/test/java/org/oppia/android/testing/FakePerformanceMetricsEventLoggerTest.kt
create mode 100644 testing/src/test/java/org/oppia/android/testing/robolectric/OppiaShadowActivityManagerTest.kt
create mode 100644 testing/src/test/java/org/oppia/android/testing/robolectric/OppiaShadowTrafficStatsTest.kt
create mode 100644 utility/src/main/java/org/oppia/android/util/logging/MetricLogScheduler.kt
create mode 100644 utility/src/main/java/org/oppia/android/util/logging/performancemetrics/BUILD.bazel
create mode 100644 utility/src/main/java/org/oppia/android/util/logging/performancemetrics/PerformanceMetricsAssessor.kt
create mode 100644 utility/src/main/java/org/oppia/android/util/logging/performancemetrics/PerformanceMetricsAssessorImpl.kt
create mode 100644 utility/src/main/java/org/oppia/android/util/logging/performancemetrics/PerformanceMetricsAssessorModule.kt
create mode 100644 utility/src/main/java/org/oppia/android/util/logging/performancemetrics/PerformanceMetricsConfigurationsModule.kt
create mode 100644 utility/src/main/java/org/oppia/android/util/logging/performancemetrics/PerformanceMetricsEventLogger.kt
create mode 100644 utility/src/test/java/org/oppia/android/util/logging/performancemetrics/PerformanceMetricsAssessorImplTest.kt
create mode 100644 utility/src/test/java/org/oppia/android/util/logging/performancemetrics/PerformanceMetricsAssessorModuleTest.kt
create mode 100644 utility/src/test/java/org/oppia/android/util/logging/performancemetrics/PerformanceMetricsConfigurationsModuleTest.kt
diff --git a/app/src/main/java/org/oppia/android/app/application/BUILD.bazel b/app/src/main/java/org/oppia/android/app/application/BUILD.bazel
index 9b2927ff303..593be4f261a 100644
--- a/app/src/main/java/org/oppia/android/app/application/BUILD.bazel
+++ b/app/src/main/java/org/oppia/android/app/application/BUILD.bazel
@@ -115,8 +115,10 @@ android_library(
"//domain/src/main/java/org/oppia/android/domain/classify/rules/ratioinput:ratio_input_module",
"//domain/src/main/java/org/oppia/android/domain/classify/rules/textinput:text_input_rule_module",
"//domain/src/main/java/org/oppia/android/domain/onboarding:retriever_prod_module",
+ "//domain/src/main/java/org/oppia/android/domain/oppialogger/analytics:performance_metrics_logger_module",
"//domain/src/main/java/org/oppia/android/domain/oppialogger/analytics:prod_module",
"//domain/src/main/java/org/oppia/android/domain/oppialogger/exceptions:logger_module",
+ "//domain/src/main/java/org/oppia/android/domain/oppialogger/logscheduler:metric_log_scheduler_module",
"//domain/src/main/java/org/oppia/android/domain/oppialogger/loguploader:worker_module",
"//utility/src/main/java/org/oppia/android/util/accessibility:prod_module",
"//utility/src/main/java/org/oppia/android/util/caching:asset_prod_module",
@@ -124,6 +126,8 @@ android_library(
"//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/logging/firebase:prod_module",
+ "//utility/src/main/java/org/oppia/android/util/logging/performancemetrics:performance_metrics_assessor_module",
+ "//utility/src/main/java/org/oppia/android/util/logging/performancemetrics:performance_metrics_configurations_module",
"//utility/src/main/java/org/oppia/android/util/networking:debug_util_module",
"//utility/src/main/java/org/oppia/android/util/parser/html:html_parser_entity_type_module",
"//utility/src/main/java/org/oppia/android/util/parser/image:glide_image_loader_module",
diff --git a/app/src/main/java/org/oppia/android/app/application/alpha/AlphaApplicationComponent.kt b/app/src/main/java/org/oppia/android/app/application/alpha/AlphaApplicationComponent.kt
index 8aa2c20f6bd..997ff520abf 100644
--- a/app/src/main/java/org/oppia/android/app/application/alpha/AlphaApplicationComponent.kt
+++ b/app/src/main/java/org/oppia/android/app/application/alpha/AlphaApplicationComponent.kt
@@ -33,8 +33,10 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
+import org.oppia.android.domain.oppialogger.analytics.PerformanceMetricsLoggerModule
import org.oppia.android.domain.oppialogger.exceptions.UncaughtExceptionLoggerModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.platformparameter.syncup.PlatformParameterSyncUpWorkerModule
@@ -50,6 +52,8 @@ import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
import org.oppia.android.util.logging.firebase.LogReportingModule
+import org.oppia.android.util.logging.performancemetrics.PerformanceMetricsAssessorModule
+import org.oppia.android.util.logging.performancemetrics.PerformanceMetricsConfigurationsModule
import org.oppia.android.util.networking.NetworkConnectionDebugUtilModule
import org.oppia.android.util.networking.NetworkConnectionUtilProdModule
import org.oppia.android.util.parser.html.HtmlParserEntityTypeModule
@@ -77,7 +81,7 @@ import javax.inject.Singleton
LogStorageModule::class, IntentFactoryShimModule::class, ViewBindingShimModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
RatioInputModule::class, UncaughtExceptionLoggerModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
WorkManagerConfigurationModule::class, HintsAndSolutionConfigModule::class,
FirebaseLogUploaderModule::class, NetworkModule::class, PracticeTabModule::class,
PlatformParameterModule::class, PlatformParameterSingletonModule::class,
@@ -89,7 +93,9 @@ import javax.inject.Singleton
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
NetworkConnectionDebugUtilModule::class, LoggingIdentifierModule::class,
SyncStatusModule::class, LogReportingModule::class, NetworkConnectionUtilProdModule::class,
- HintsAndSolutionProdModule::class
+ HintsAndSolutionProdModule::class, MetricLogSchedulerModule::class,
+ PerformanceMetricsLoggerModule::class, PerformanceMetricsAssessorModule::class,
+ PerformanceMetricsConfigurationsModule::class
]
)
interface AlphaApplicationComponent : ApplicationComponent {
diff --git a/app/src/main/java/org/oppia/android/app/application/alphakenya/AlphaKenyaApplicationComponent.kt b/app/src/main/java/org/oppia/android/app/application/alphakenya/AlphaKenyaApplicationComponent.kt
index 5a31d7f8f4d..2d20f037a76 100644
--- a/app/src/main/java/org/oppia/android/app/application/alphakenya/AlphaKenyaApplicationComponent.kt
+++ b/app/src/main/java/org/oppia/android/app/application/alphakenya/AlphaKenyaApplicationComponent.kt
@@ -33,8 +33,10 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
+import org.oppia.android.domain.oppialogger.analytics.PerformanceMetricsLoggerModule
import org.oppia.android.domain.oppialogger.exceptions.UncaughtExceptionLoggerModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterAlphaKenyaModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.platformparameter.syncup.PlatformParameterSyncUpWorkerModule
@@ -50,6 +52,8 @@ import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
import org.oppia.android.util.logging.firebase.LogReportingModule
+import org.oppia.android.util.logging.performancemetrics.PerformanceMetricsAssessorModule
+import org.oppia.android.util.logging.performancemetrics.PerformanceMetricsConfigurationsModule
import org.oppia.android.util.networking.NetworkConnectionDebugUtilModule
import org.oppia.android.util.networking.NetworkConnectionUtilProdModule
import org.oppia.android.util.parser.html.HtmlParserEntityTypeModule
@@ -77,7 +81,7 @@ import javax.inject.Singleton
LogStorageModule::class, IntentFactoryShimModule::class, ViewBindingShimModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
RatioInputModule::class, UncaughtExceptionLoggerModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
WorkManagerConfigurationModule::class, HintsAndSolutionConfigAlphaKenyaModule::class,
FirebaseLogUploaderModule::class, NetworkModule::class, PracticeTabModule::class,
PlatformParameterAlphaKenyaModule::class, PlatformParameterSingletonModule::class,
@@ -89,7 +93,9 @@ import javax.inject.Singleton
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
NetworkConnectionDebugUtilModule::class, LoggingIdentifierModule::class,
SyncStatusModule::class, LogReportingModule::class, NetworkConnectionUtilProdModule::class,
- HintsAndSolutionProdModule::class
+ HintsAndSolutionProdModule::class, MetricLogSchedulerModule::class,
+ PerformanceMetricsLoggerModule::class, PerformanceMetricsAssessorModule::class,
+ PerformanceMetricsConfigurationsModule::class
]
)
interface AlphaKenyaApplicationComponent : ApplicationComponent {
diff --git a/app/src/main/java/org/oppia/android/app/application/dev/DeveloperApplicationComponent.kt b/app/src/main/java/org/oppia/android/app/application/dev/DeveloperApplicationComponent.kt
index aee630025d2..9d2bd782568 100644
--- a/app/src/main/java/org/oppia/android/app/application/dev/DeveloperApplicationComponent.kt
+++ b/app/src/main/java/org/oppia/android/app/application/dev/DeveloperApplicationComponent.kt
@@ -34,8 +34,10 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
+import org.oppia.android.domain.oppialogger.analytics.PerformanceMetricsLoggerModule
import org.oppia.android.domain.oppialogger.exceptions.UncaughtExceptionLoggerModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.platformparameter.syncup.PlatformParameterSyncUpWorkerModule
@@ -51,6 +53,8 @@ import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.DebugLogReportingModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
+import org.oppia.android.util.logging.performancemetrics.PerformanceMetricsAssessorModule
+import org.oppia.android.util.logging.performancemetrics.PerformanceMetricsConfigurationsModule
import org.oppia.android.util.networking.NetworkConnectionDebugUtilModule
import org.oppia.android.util.networking.NetworkConnectionUtilDebugModule
import org.oppia.android.util.parser.html.HtmlParserEntityTypeModule
@@ -79,7 +83,7 @@ import javax.inject.Singleton
ViewBindingShimModule::class, PrimeTopicAssetsControllerModule::class,
ExpirationMetaDataRetrieverModule::class, RatioInputModule::class,
UncaughtExceptionLoggerModule::class, ApplicationStartupListenerModule::class,
- LogUploadWorkerModule::class, WorkManagerConfigurationModule::class,
+ LogReportWorkerModule::class, WorkManagerConfigurationModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionDebugModule::class,
FirebaseLogUploaderModule::class, NetworkModule::class, PracticeTabModule::class,
PlatformParameterModule::class, PlatformParameterSingletonModule::class,
@@ -90,7 +94,9 @@ import javax.inject.Singleton
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- NetworkConnectionDebugUtilModule::class, LoggingIdentifierModule::class, SyncStatusModule::class
+ NetworkConnectionDebugUtilModule::class, LoggingIdentifierModule::class,
+ SyncStatusModule::class, MetricLogSchedulerModule::class, PerformanceMetricsLoggerModule::class,
+ PerformanceMetricsAssessorModule::class, PerformanceMetricsConfigurationsModule::class
]
)
interface DeveloperApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/AdministratorControlsActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/AdministratorControlsActivityTest.kt
index 1b46cb78cb4..5918ad0614f 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/AdministratorControlsActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/AdministratorControlsActivityTest.kt
@@ -89,7 +89,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
import org.oppia.android.domain.topic.PrimeTopicAssetsControllerModule
@@ -824,7 +825,7 @@ class AdministratorControlsActivityTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -834,7 +835,7 @@ class AdministratorControlsActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/AdministratorControlsFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/AdministratorControlsFragmentTest.kt
index 2f737fe499b..ae58e53a313 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/AdministratorControlsFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/AdministratorControlsFragmentTest.kt
@@ -80,7 +80,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
import org.oppia.android.domain.topic.PrimeTopicAssetsControllerModule
@@ -602,7 +603,7 @@ class AdministratorControlsFragmentTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -612,7 +613,7 @@ class AdministratorControlsFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/AppVersionActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/AppVersionActivityTest.kt
index 894b70c8199..4d3875e7a30 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/AppVersionActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/AppVersionActivityTest.kt
@@ -69,7 +69,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -280,7 +281,7 @@ class AppVersionActivityTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -290,7 +291,7 @@ class AppVersionActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/learneranalytics/ProfileAndDeviceIdActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/learneranalytics/ProfileAndDeviceIdActivityTest.kt
index beb69438acf..e0b44a0a5fa 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/learneranalytics/ProfileAndDeviceIdActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/learneranalytics/ProfileAndDeviceIdActivityTest.kt
@@ -58,8 +58,9 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.ApplicationIdSeed
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.OppiaLogger
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerFactory
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -189,7 +190,7 @@ class ProfileAndDeviceIdActivityTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -198,7 +199,7 @@ class ProfileAndDeviceIdActivityTest {
AssetModule::class, LocaleProdModule::class, ActivityRecreatorTestModule::class,
SyncStatusModule::class, SplitScreenInteractionModule::class,
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
- MathEquationInputModule::class
+ MathEquationInputModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/learneranalytics/ProfileAndDeviceIdFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/learneranalytics/ProfileAndDeviceIdFragmentTest.kt
index affe4a867b5..1c99c20e542 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/learneranalytics/ProfileAndDeviceIdFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/learneranalytics/ProfileAndDeviceIdFragmentTest.kt
@@ -76,9 +76,10 @@ import org.oppia.android.domain.oppialogger.ApplicationIdSeed
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.OppiaLogger
import org.oppia.android.domain.oppialogger.analytics.LearnerAnalyticsLogger
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorker
import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerFactory
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
import org.oppia.android.domain.topic.PrimeTopicAssetsControllerModule
@@ -615,7 +616,7 @@ class ProfileAndDeviceIdFragmentTest {
LogStorageModule::class, CachingTestModule::class, PrimeTopicAssetsControllerModule::class,
ExpirationMetaDataRetrieverModule::class, ViewBindingShimModule::class,
RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -624,7 +625,7 @@ class ProfileAndDeviceIdFragmentTest {
AssetModule::class, LocaleProdModule::class, ActivityRecreatorTestModule::class,
SyncStatusModule::class, SplitScreenInteractionModule::class,
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
- MathEquationInputModule::class
+ MathEquationInputModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/completedstorylist/CompletedStoryListActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/completedstorylist/CompletedStoryListActivityTest.kt
index df59509cf92..dc1c7fd5a82 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/completedstorylist/CompletedStoryListActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/completedstorylist/CompletedStoryListActivityTest.kt
@@ -70,7 +70,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -503,7 +504,7 @@ class CompletedStoryListActivityTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -513,7 +514,7 @@ class CompletedStoryListActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/customview/LessonThumbnailImageViewTest.kt b/app/src/sharedTest/java/org/oppia/android/app/customview/LessonThumbnailImageViewTest.kt
index e45061db40d..e9fd803c1e3 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/customview/LessonThumbnailImageViewTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/customview/LessonThumbnailImageViewTest.kt
@@ -53,7 +53,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -161,7 +162,7 @@ class LessonThumbnailImageViewTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -171,7 +172,7 @@ class LessonThumbnailImageViewTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/customview/interaction/MathExpressionInteractionsViewTest.kt b/app/src/sharedTest/java/org/oppia/android/app/customview/interaction/MathExpressionInteractionsViewTest.kt
index 453409d3d18..100c5a437f8 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/customview/interaction/MathExpressionInteractionsViewTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/customview/interaction/MathExpressionInteractionsViewTest.kt
@@ -68,7 +68,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -1763,7 +1764,7 @@ class MathExpressionInteractionsViewTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -1773,7 +1774,7 @@ class MathExpressionInteractionsViewTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/databinding/DrawableBindingAdaptersTest.kt b/app/src/sharedTest/java/org/oppia/android/app/databinding/DrawableBindingAdaptersTest.kt
index 0a9961aaa12..1bee02bb647 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/databinding/DrawableBindingAdaptersTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/databinding/DrawableBindingAdaptersTest.kt
@@ -59,7 +59,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -172,7 +173,7 @@ class DrawableBindingAdaptersTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -182,7 +183,7 @@ class DrawableBindingAdaptersTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/databinding/ImageViewBindingAdaptersTest.kt b/app/src/sharedTest/java/org/oppia/android/app/databinding/ImageViewBindingAdaptersTest.kt
index 6b36d3068dd..6559b4e211b 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/databinding/ImageViewBindingAdaptersTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/databinding/ImageViewBindingAdaptersTest.kt
@@ -63,7 +63,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -214,7 +215,7 @@ class ImageViewBindingAdaptersTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -223,7 +224,8 @@ class ImageViewBindingAdaptersTest {
AssetModule::class, LocaleProdModule::class, ActivityRecreatorTestModule::class,
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
- LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class
+ LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class,
+ MetricLogSchedulerModule::class
]
)
/** Create a TestApplicationComponent. */
diff --git a/app/src/sharedTest/java/org/oppia/android/app/databinding/MarginBindingAdaptersTest.kt b/app/src/sharedTest/java/org/oppia/android/app/databinding/MarginBindingAdaptersTest.kt
index 1153bd7ef6f..51af7e5e519 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/databinding/MarginBindingAdaptersTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/databinding/MarginBindingAdaptersTest.kt
@@ -64,7 +64,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -302,7 +303,7 @@ class MarginBindingAdaptersTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -311,7 +312,8 @@ class MarginBindingAdaptersTest {
AssetModule::class, LocaleProdModule::class, ActivityRecreatorTestModule::class,
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
- LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class
+ LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class,
+ MetricLogSchedulerModule::class
]
)
/** Create a TestApplicationComponent. */
diff --git a/app/src/sharedTest/java/org/oppia/android/app/databinding/StateAssemblerMarginBindingAdaptersTest.kt b/app/src/sharedTest/java/org/oppia/android/app/databinding/StateAssemblerMarginBindingAdaptersTest.kt
index e297c8cf07f..8f24ad52f76 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/databinding/StateAssemblerMarginBindingAdaptersTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/databinding/StateAssemblerMarginBindingAdaptersTest.kt
@@ -66,7 +66,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -490,7 +491,7 @@ class StateAssemblerMarginBindingAdaptersTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -499,7 +500,8 @@ class StateAssemblerMarginBindingAdaptersTest {
AssetModule::class, LocaleProdModule::class, ActivityRecreatorTestModule::class,
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
- LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class
+ LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class,
+ MetricLogSchedulerModule::class
]
)
/** Create a TestApplicationComponent. */
diff --git a/app/src/sharedTest/java/org/oppia/android/app/databinding/StateAssemblerPaddingBindingAdaptersTest.kt b/app/src/sharedTest/java/org/oppia/android/app/databinding/StateAssemblerPaddingBindingAdaptersTest.kt
index 1bf0b3191c5..d4c2448a4db 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/databinding/StateAssemblerPaddingBindingAdaptersTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/databinding/StateAssemblerPaddingBindingAdaptersTest.kt
@@ -64,7 +64,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -488,7 +489,7 @@ class StateAssemblerPaddingBindingAdaptersTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -497,7 +498,8 @@ class StateAssemblerPaddingBindingAdaptersTest {
AssetModule::class, LocaleProdModule::class, ActivityRecreatorTestModule::class,
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
- LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class
+ LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class,
+ MetricLogSchedulerModule::class
]
)
diff --git a/app/src/sharedTest/java/org/oppia/android/app/databinding/TextViewBindingAdaptersTest.kt b/app/src/sharedTest/java/org/oppia/android/app/databinding/TextViewBindingAdaptersTest.kt
index c20b2af3164..ebd73e65eda 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/databinding/TextViewBindingAdaptersTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/databinding/TextViewBindingAdaptersTest.kt
@@ -57,7 +57,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -321,7 +322,7 @@ class TextViewBindingAdaptersTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -331,7 +332,7 @@ class TextViewBindingAdaptersTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/databinding/ViewBindingAdaptersTest.kt b/app/src/sharedTest/java/org/oppia/android/app/databinding/ViewBindingAdaptersTest.kt
index c1735ce7351..5127d9aec73 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/databinding/ViewBindingAdaptersTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/databinding/ViewBindingAdaptersTest.kt
@@ -61,7 +61,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -222,7 +223,7 @@ class ViewBindingAdaptersTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -231,7 +232,8 @@ class ViewBindingAdaptersTest {
AssetModule::class, LocaleProdModule::class, ActivityRecreatorTestModule::class,
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
- LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class
+ LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class,
+ MetricLogSchedulerModule::class
]
)
/** Create a TestApplicationComponent. */
diff --git a/app/src/sharedTest/java/org/oppia/android/app/devoptions/DeveloperOptionsActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/devoptions/DeveloperOptionsActivityTest.kt
index e5022299560..f5be1badb63 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/devoptions/DeveloperOptionsActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/devoptions/DeveloperOptionsActivityTest.kt
@@ -79,7 +79,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -313,7 +314,7 @@ class DeveloperOptionsActivityTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -324,7 +325,7 @@ class DeveloperOptionsActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/devoptions/DeveloperOptionsFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/devoptions/DeveloperOptionsFragmentTest.kt
index 3c039beadf5..98130794bda 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/devoptions/DeveloperOptionsFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/devoptions/DeveloperOptionsFragmentTest.kt
@@ -75,7 +75,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -644,7 +645,7 @@ class DeveloperOptionsFragmentTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -655,7 +656,7 @@ class DeveloperOptionsFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkChaptersCompletedActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkChaptersCompletedActivityTest.kt
index 1244ee96e90..1f3326161e7 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkChaptersCompletedActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkChaptersCompletedActivityTest.kt
@@ -56,7 +56,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -175,7 +176,7 @@ class MarkChaptersCompletedActivityTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -186,7 +187,7 @@ class MarkChaptersCompletedActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkChaptersCompletedFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkChaptersCompletedFragmentTest.kt
index 928e30a086a..62272000673 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkChaptersCompletedFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkChaptersCompletedFragmentTest.kt
@@ -65,7 +65,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -903,7 +904,7 @@ class MarkChaptersCompletedFragmentTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -914,7 +915,7 @@ class MarkChaptersCompletedFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkStoriesCompletedActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkStoriesCompletedActivityTest.kt
index 0deb989b06d..b4b998b9f7c 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkStoriesCompletedActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkStoriesCompletedActivityTest.kt
@@ -56,7 +56,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -175,7 +176,7 @@ class MarkStoriesCompletedActivityTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -186,7 +187,7 @@ class MarkStoriesCompletedActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkStoriesCompletedFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkStoriesCompletedFragmentTest.kt
index 5e8c2c5dc4f..9613d6d6729 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkStoriesCompletedFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkStoriesCompletedFragmentTest.kt
@@ -65,7 +65,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -580,7 +581,7 @@ class MarkStoriesCompletedFragmentTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -591,7 +592,7 @@ class MarkStoriesCompletedFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkTopicsCompletedActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkTopicsCompletedActivityTest.kt
index 0aedf6d8d4e..5107bd10697 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkTopicsCompletedActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkTopicsCompletedActivityTest.kt
@@ -56,7 +56,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -175,7 +176,7 @@ class MarkTopicsCompletedActivityTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -186,7 +187,7 @@ class MarkTopicsCompletedActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkTopicsCompletedFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkTopicsCompletedFragmentTest.kt
index 9f677943e57..7ddd3a668ac 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkTopicsCompletedFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkTopicsCompletedFragmentTest.kt
@@ -65,7 +65,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -550,7 +551,7 @@ class MarkTopicsCompletedFragmentTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -561,7 +562,7 @@ class MarkTopicsCompletedFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/devoptions/ViewEventLogsActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/devoptions/ViewEventLogsActivityTest.kt
index 109e70e701c..2104922adec 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/devoptions/ViewEventLogsActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/devoptions/ViewEventLogsActivityTest.kt
@@ -57,7 +57,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -77,6 +78,8 @@ import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.DebugLogReportingModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
+import org.oppia.android.util.logging.performancemetrics.PerformanceMetricsAssessorModule
+import org.oppia.android.util.logging.performancemetrics.PerformanceMetricsConfigurationsModule
import org.oppia.android.util.networking.NetworkConnectionDebugUtilModule
import org.oppia.android.util.networking.NetworkConnectionUtilDebugModule
import org.oppia.android.util.parser.html.HtmlParserEntityTypeModule
@@ -163,7 +166,7 @@ class ViewEventLogsActivityTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -174,7 +177,8 @@ class ViewEventLogsActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class,
+ PerformanceMetricsAssessorModule::class, PerformanceMetricsConfigurationsModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/devoptions/ViewEventLogsFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/devoptions/ViewEventLogsFragmentTest.kt
index 8d6e26325a3..e10ba410943 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/devoptions/ViewEventLogsFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/devoptions/ViewEventLogsFragmentTest.kt
@@ -17,7 +17,6 @@ import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.google.firebase.FirebaseApp
import dagger.Component
-import org.hamcrest.Matchers.not
import org.junit.After
import org.junit.Before
import org.junit.Rule
@@ -63,7 +62,8 @@ import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.OppiaLogger
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -85,6 +85,8 @@ import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.DebugLogReportingModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
+import org.oppia.android.util.logging.performancemetrics.PerformanceMetricsAssessorModule
+import org.oppia.android.util.logging.performancemetrics.PerformanceMetricsConfigurationsModule
import org.oppia.android.util.networking.NetworkConnectionDebugUtilModule
import org.oppia.android.util.networking.NetworkConnectionUtilDebugModule
import org.oppia.android.util.parser.html.HtmlParserEntityTypeModule
@@ -564,7 +566,7 @@ class ViewEventLogsFragmentTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -574,7 +576,9 @@ class ViewEventLogsFragmentTest {
PlatformParameterSingletonModule::class,
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
- LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class
+ LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class,
+ MetricLogSchedulerModule::class, PerformanceMetricsAssessorModule::class,
+ PerformanceMetricsConfigurationsModule::class
]
)
diff --git a/app/src/sharedTest/java/org/oppia/android/app/devoptions/forcenetworktype/ForceNetworkTypeActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/devoptions/forcenetworktype/ForceNetworkTypeActivityTest.kt
index dd0cdd29398..1647b6b5dee 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/devoptions/forcenetworktype/ForceNetworkTypeActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/devoptions/forcenetworktype/ForceNetworkTypeActivityTest.kt
@@ -57,7 +57,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -167,7 +168,7 @@ class ForceNetworkTypeActivityTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, NetworkConfigProdModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
WorkManagerConfigurationModule::class, HintsAndSolutionConfigModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -177,7 +178,8 @@ class ForceNetworkTypeActivityTest {
PlatformParameterSingletonModule::class,
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
- LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class
+ LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class,
+ MetricLogSchedulerModule::class
]
)
/** [ApplicationComponent] for [ForceNetworkTypeActivityTest]. */
diff --git a/app/src/sharedTest/java/org/oppia/android/app/devoptions/forcenetworktype/ForceNetworkTypeFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/devoptions/forcenetworktype/ForceNetworkTypeFragmentTest.kt
index defd8e3d336..d6c30067abe 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/devoptions/forcenetworktype/ForceNetworkTypeFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/devoptions/forcenetworktype/ForceNetworkTypeFragmentTest.kt
@@ -62,7 +62,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -383,7 +384,7 @@ class ForceNetworkTypeFragmentTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, NetworkConfigProdModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
WorkManagerConfigurationModule::class, HintsAndSolutionConfigModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -393,7 +394,8 @@ class ForceNetworkTypeFragmentTest {
PlatformParameterSingletonModule::class,
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
- LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class
+ LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class,
+ MetricLogSchedulerModule::class
]
)
/** [ApplicationComponent] for [ForceNetworkTypeFragmentTest]. */
diff --git a/app/src/sharedTest/java/org/oppia/android/app/devoptions/mathexpressionparser/MathExpressionParserActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/devoptions/mathexpressionparser/MathExpressionParserActivityTest.kt
index 149e44b36d2..e9a86da55ae 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/devoptions/mathexpressionparser/MathExpressionParserActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/devoptions/mathexpressionparser/MathExpressionParserActivityTest.kt
@@ -54,7 +54,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -152,7 +153,7 @@ class MathExpressionParserActivityTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -162,7 +163,7 @@ class MathExpressionParserActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/devoptions/mathexpressionparser/MathExpressionParserFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/devoptions/mathexpressionparser/MathExpressionParserFragmentTest.kt
index 39a65aa5273..6bf88c29bf3 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/devoptions/mathexpressionparser/MathExpressionParserFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/devoptions/mathexpressionparser/MathExpressionParserFragmentTest.kt
@@ -64,7 +64,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -1402,7 +1403,7 @@ class MathExpressionParserFragmentTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -1412,7 +1413,7 @@ class MathExpressionParserFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/faq/FAQListFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/faq/FAQListFragmentTest.kt
index f5401ca0893..e6f86c7cbbf 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/faq/FAQListFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/faq/FAQListFragmentTest.kt
@@ -68,7 +68,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -236,7 +237,7 @@ class FAQListFragmentTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -246,7 +247,7 @@ class FAQListFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/faq/FAQSingleActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/faq/FAQSingleActivityTest.kt
index e557fd60a10..79c2ab467fb 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/faq/FAQSingleActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/faq/FAQSingleActivityTest.kt
@@ -63,7 +63,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -214,7 +215,7 @@ class FAQSingleActivityTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -224,7 +225,7 @@ class FAQSingleActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/faq/FaqListActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/faq/FaqListActivityTest.kt
index baad49bd787..66b90ab902a 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/faq/FaqListActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/faq/FaqListActivityTest.kt
@@ -51,7 +51,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -141,7 +142,7 @@ class FaqListActivityTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -151,7 +152,7 @@ class FaqListActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/help/HelpActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/help/HelpActivityTest.kt
index 7a284ed0d26..659279b6035 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/help/HelpActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/help/HelpActivityTest.kt
@@ -50,7 +50,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -143,7 +144,7 @@ class HelpActivityTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -153,7 +154,7 @@ class HelpActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/help/HelpFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/help/HelpFragmentTest.kt
index 931f0a2d0e2..085d91bda44 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/help/HelpFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/help/HelpFragmentTest.kt
@@ -81,7 +81,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -1431,7 +1432,7 @@ class HelpFragmentTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -1441,7 +1442,7 @@ class HelpFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt
index 8d0fa6bc777..99e47450a8a 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt
@@ -97,7 +97,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -1800,7 +1801,7 @@ class HomeActivityTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -1810,7 +1811,7 @@ class HomeActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/home/RecentlyPlayedFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/home/RecentlyPlayedFragmentTest.kt
index 157e4032e81..672069768fd 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/home/RecentlyPlayedFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/home/RecentlyPlayedFragmentTest.kt
@@ -84,7 +84,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -1495,7 +1496,7 @@ class RecentlyPlayedFragmentTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -1505,7 +1506,7 @@ class RecentlyPlayedFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/home/TopicSummaryViewModelTest.kt b/app/src/sharedTest/java/org/oppia/android/app/home/TopicSummaryViewModelTest.kt
index 4b6b1351d10..7e6cedb6445 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/home/TopicSummaryViewModelTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/home/TopicSummaryViewModelTest.kt
@@ -52,7 +52,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -361,7 +362,7 @@ class TopicSummaryViewModelTest {
ImageClickInputModule::class, LogStorageModule::class, IntentFactoryShimModule::class,
ViewBindingShimModule::class, CachingTestModule::class, RatioInputModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
WorkManagerConfigurationModule::class, HintsAndSolutionConfigModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -372,7 +373,7 @@ class TopicSummaryViewModelTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/home/WelcomeViewModelTest.kt b/app/src/sharedTest/java/org/oppia/android/app/home/WelcomeViewModelTest.kt
index b041e1e92d1..7505e4d774c 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/home/WelcomeViewModelTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/home/WelcomeViewModelTest.kt
@@ -52,7 +52,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -345,7 +346,7 @@ class WelcomeViewModelTest {
ImageClickInputModule::class, LogStorageModule::class, IntentFactoryShimModule::class,
ViewBindingShimModule::class, CachingTestModule::class, RatioInputModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
WorkManagerConfigurationModule::class, HintsAndSolutionConfigModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -356,7 +357,7 @@ class WelcomeViewModelTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/home/promotedlist/PromotedStoryListViewModelTest.kt b/app/src/sharedTest/java/org/oppia/android/app/home/promotedlist/PromotedStoryListViewModelTest.kt
index 94ea2653fc9..aee3ce36441 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/home/promotedlist/PromotedStoryListViewModelTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/home/promotedlist/PromotedStoryListViewModelTest.kt
@@ -53,7 +53,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -357,7 +358,7 @@ class PromotedStoryListViewModelTest {
ImageClickInputModule::class, LogStorageModule::class, IntentFactoryShimModule::class,
ViewBindingShimModule::class, CachingTestModule::class, RatioInputModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
WorkManagerConfigurationModule::class, HintsAndSolutionConfigModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -368,7 +369,7 @@ class PromotedStoryListViewModelTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/home/promotedlist/PromotedStoryViewModelTest.kt b/app/src/sharedTest/java/org/oppia/android/app/home/promotedlist/PromotedStoryViewModelTest.kt
index 58f9a657ff1..6208ea3fbec 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/home/promotedlist/PromotedStoryViewModelTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/home/promotedlist/PromotedStoryViewModelTest.kt
@@ -51,7 +51,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -367,7 +368,7 @@ class PromotedStoryViewModelTest {
ImageClickInputModule::class, LogStorageModule::class, IntentFactoryShimModule::class,
ViewBindingShimModule::class, CachingTestModule::class, RatioInputModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
WorkManagerConfigurationModule::class, HintsAndSolutionConfigModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -378,7 +379,7 @@ class PromotedStoryViewModelTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/mydownloads/MyDownloadsActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/mydownloads/MyDownloadsActivityTest.kt
index 7c074f3ac7e..a9b9c815a49 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/mydownloads/MyDownloadsActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/mydownloads/MyDownloadsActivityTest.kt
@@ -49,7 +49,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -131,7 +132,7 @@ class MyDownloadsActivityTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -141,7 +142,7 @@ class MyDownloadsActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/mydownloads/MyDownloadsFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/mydownloads/MyDownloadsFragmentTest.kt
index e00a159ed6a..a1aa44be743 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/mydownloads/MyDownloadsFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/mydownloads/MyDownloadsFragmentTest.kt
@@ -60,7 +60,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -222,7 +223,7 @@ class MyDownloadsFragmentTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -232,7 +233,7 @@ class MyDownloadsFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingActivityTest.kt
index 4a75018850e..412a7674a49 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingActivityTest.kt
@@ -50,7 +50,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -140,7 +141,7 @@ class OnboardingActivityTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -150,7 +151,7 @@ class OnboardingActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingFragmentTest.kt
index cbeb01d1d79..5b3d03d8824 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingFragmentTest.kt
@@ -78,7 +78,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -712,7 +713,7 @@ class OnboardingFragmentTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -722,7 +723,7 @@ class OnboardingFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/ongoingtopiclist/OngoingTopicListActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/ongoingtopiclist/OngoingTopicListActivityTest.kt
index e5caa8c9196..c9d0f8ff1d1 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/ongoingtopiclist/OngoingTopicListActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/ongoingtopiclist/OngoingTopicListActivityTest.kt
@@ -69,7 +69,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -447,7 +448,7 @@ class OngoingTopicListActivityTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -457,7 +458,7 @@ class OngoingTopicListActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/options/AppLanguageActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/options/AppLanguageActivityTest.kt
index 395f1bfa6d0..62965d09a72 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/options/AppLanguageActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/options/AppLanguageActivityTest.kt
@@ -50,7 +50,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -150,7 +151,7 @@ class AppLanguageActivityTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -160,7 +161,7 @@ class AppLanguageActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/options/AppLanguageFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/options/AppLanguageFragmentTest.kt
index 1720dc9ebf2..78966f2e217 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/options/AppLanguageFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/options/AppLanguageFragmentTest.kt
@@ -59,7 +59,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -246,7 +247,7 @@ class AppLanguageFragmentTest {
ViewBindingShimModule::class, ApplicationStartupListenerModule::class,
RatioInputModule::class, HintsAndSolutionConfigModule::class,
WorkManagerConfigurationModule::class, FirebaseLogUploaderModule::class,
- LogUploadWorkerModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
+ LogReportWorkerModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
ExplorationStorageModule::class, NetworkModule::class, HintsAndSolutionProdModule::class,
NetworkConnectionUtilDebugModule::class, NetworkConnectionDebugUtilModule::class,
@@ -255,7 +256,7 @@ class AppLanguageFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/options/AudioLanguageActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/options/AudioLanguageActivityTest.kt
index fa2bed58f8b..eb69586b13c 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/options/AudioLanguageActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/options/AudioLanguageActivityTest.kt
@@ -50,7 +50,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -150,7 +151,7 @@ class AudioLanguageActivityTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -160,7 +161,7 @@ class AudioLanguageActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/options/AudioLanguageFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/options/AudioLanguageFragmentTest.kt
index 4376d4ebeb3..dbb338d76e2 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/options/AudioLanguageFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/options/AudioLanguageFragmentTest.kt
@@ -58,7 +58,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -238,7 +239,7 @@ class AudioLanguageFragmentTest {
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, ApplicationStartupListenerModule::class,
RatioInputModule::class, HintsAndSolutionConfigModule::class,
- WorkManagerConfigurationModule::class, LogUploadWorkerModule::class,
+ WorkManagerConfigurationModule::class, LogReportWorkerModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
ExplorationStorageModule::class, NetworkModule::class, HintsAndSolutionProdModule::class,
@@ -248,7 +249,7 @@ class AudioLanguageFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/options/OptionsActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/options/OptionsActivityTest.kt
index 51ef476ad81..b90e05fd338 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/options/OptionsActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/options/OptionsActivityTest.kt
@@ -50,7 +50,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -142,7 +143,7 @@ class OptionsActivityTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -152,7 +153,7 @@ class OptionsActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/options/OptionsFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/options/OptionsFragmentTest.kt
index 8d8dd411b1b..50701da0b58 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/options/OptionsFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/options/OptionsFragmentTest.kt
@@ -70,7 +70,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
import org.oppia.android.domain.topic.PrimeTopicAssetsControllerModule
@@ -642,7 +643,7 @@ class OptionsFragmentTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -652,7 +653,7 @@ class OptionsFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/options/ReadingTextSizeActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/options/ReadingTextSizeActivityTest.kt
index ae37f1cea24..40fd59f6fb8 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/options/ReadingTextSizeActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/options/ReadingTextSizeActivityTest.kt
@@ -50,7 +50,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -150,7 +151,7 @@ class ReadingTextSizeActivityTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -160,7 +161,7 @@ class ReadingTextSizeActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/options/ReadingTextSizeFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/options/ReadingTextSizeFragmentTest.kt
index 52e4e3e40fe..46284607705 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/options/ReadingTextSizeFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/options/ReadingTextSizeFragmentTest.kt
@@ -65,7 +65,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -305,7 +306,7 @@ class ReadingTextSizeFragmentTest {
ViewBindingShimModule::class, ApplicationStartupListenerModule::class,
RatioInputModule::class, HintsAndSolutionConfigModule::class,
WorkManagerConfigurationModule::class, FirebaseLogUploaderModule::class,
- LogUploadWorkerModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
+ LogReportWorkerModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
ExplorationStorageModule::class, NetworkModule::class, HintsAndSolutionProdModule::class,
NetworkConnectionUtilDebugModule::class, NetworkConnectionDebugUtilModule::class,
@@ -314,7 +315,7 @@ class ReadingTextSizeFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/parser/HtmlParserTest.kt b/app/src/sharedTest/java/org/oppia/android/app/parser/HtmlParserTest.kt
index 189215323b4..6cc3bbcb4a0 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/parser/HtmlParserTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/parser/HtmlParserTest.kt
@@ -90,7 +90,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -896,7 +897,7 @@ class HtmlParserTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -906,7 +907,7 @@ class HtmlParserTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/parser/ListItemLeadingMarginSpanTest.kt b/app/src/sharedTest/java/org/oppia/android/app/parser/ListItemLeadingMarginSpanTest.kt
index ca6620e317e..1ccba698308 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/parser/ListItemLeadingMarginSpanTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/parser/ListItemLeadingMarginSpanTest.kt
@@ -72,7 +72,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -1095,7 +1096,7 @@ class ListItemLeadingMarginSpanTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -1105,7 +1106,7 @@ class ListItemLeadingMarginSpanTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
diff --git a/app/src/sharedTest/java/org/oppia/android/app/player/audio/AudioFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/player/audio/AudioFragmentTest.kt
index 026a0eb3a6a..30186b1cc96 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/player/audio/AudioFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/player/audio/AudioFragmentTest.kt
@@ -74,7 +74,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.profile.ProfileManagementController
@@ -467,7 +468,7 @@ class AudioFragmentTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -477,7 +478,7 @@ class AudioFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt
index 13ea34c89a2..2020e38b87b 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt
@@ -105,7 +105,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -1947,7 +1948,7 @@ class ExplorationActivityTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -1956,7 +1957,8 @@ class ExplorationActivityTest {
AssetModule::class, LocaleProdModule::class, ActivityRecreatorTestModule::class,
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
- LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class
+ LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class,
+ MetricLogSchedulerModule::class
]
)
diff --git a/app/src/sharedTest/java/org/oppia/android/app/player/state/StateFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/player/state/StateFragmentTest.kt
index ecbe1f15c4d..f1898d255d3 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/player/state/StateFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/player/state/StateFragmentTest.kt
@@ -128,7 +128,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -4308,7 +4309,7 @@ class StateFragmentTest {
ExpirationMetaDataRetrieverModule::class, ViewBindingShimModule::class,
RatioInputModule::class, ApplicationStartupListenerModule::class,
HintsAndSolutionConfigFastShowTestModule::class, HintsAndSolutionProdModule::class,
- WorkManagerConfigurationModule::class, LogUploadWorkerModule::class,
+ WorkManagerConfigurationModule::class, LogReportWorkerModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
ExplorationStorageModule::class, NetworkConnectionUtilDebugModule::class,
@@ -4318,7 +4319,7 @@ class StateFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/policies/PoliciesActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/policies/PoliciesActivityTest.kt
index 6e182dbb936..40789301bbd 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/policies/PoliciesActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/policies/PoliciesActivityTest.kt
@@ -51,7 +51,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -173,7 +174,7 @@ class PoliciesActivityTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -183,7 +184,7 @@ class PoliciesActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/policies/PoliciesFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/policies/PoliciesFragmentTest.kt
index 0fde4e38fa8..f2ffe23dd5c 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/policies/PoliciesFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/policies/PoliciesFragmentTest.kt
@@ -74,7 +74,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -326,7 +327,7 @@ class PoliciesFragmentTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -336,7 +337,7 @@ class PoliciesFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/profile/AddProfileActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/profile/AddProfileActivityTest.kt
index 9629aa9a6c1..4cd82b31973 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/profile/AddProfileActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/profile/AddProfileActivityTest.kt
@@ -84,7 +84,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -1721,7 +1722,7 @@ class AddProfileActivityTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -1731,7 +1732,7 @@ class AddProfileActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/profile/AdminAuthActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/profile/AdminAuthActivityTest.kt
index 98236590291..c4934f2611c 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/profile/AdminAuthActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/profile/AdminAuthActivityTest.kt
@@ -70,7 +70,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -660,7 +661,7 @@ class AdminAuthActivityTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -671,7 +672,7 @@ class AdminAuthActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/profile/AdminPinActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/profile/AdminPinActivityTest.kt
index 6159eddba5c..4f66269badb 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/profile/AdminPinActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/profile/AdminPinActivityTest.kt
@@ -79,7 +79,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -1079,7 +1080,7 @@ class AdminPinActivityTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -1089,7 +1090,7 @@ class AdminPinActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/profile/PinPasswordActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/profile/PinPasswordActivityTest.kt
index 76f4a79eb69..f7f5fa8fe29 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/profile/PinPasswordActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/profile/PinPasswordActivityTest.kt
@@ -73,7 +73,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -1140,7 +1141,7 @@ class PinPasswordActivityTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -1151,7 +1152,7 @@ class PinPasswordActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/profile/ProfileChooserFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/profile/ProfileChooserFragmentTest.kt
index d90eee72e20..cdcee36d429 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/profile/ProfileChooserFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/profile/ProfileChooserFragmentTest.kt
@@ -72,7 +72,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.profile.ProfileManagementController
@@ -518,7 +519,7 @@ class ProfileChooserFragmentTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -528,7 +529,7 @@ class ProfileChooserFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/profileprogress/ProfilePictureActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/profileprogress/ProfilePictureActivityTest.kt
index f0c957a2ea4..f1e9541bb3c 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/profileprogress/ProfilePictureActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/profileprogress/ProfilePictureActivityTest.kt
@@ -58,7 +58,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -193,7 +194,7 @@ class ProfilePictureActivityTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -203,7 +204,7 @@ class ProfilePictureActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/profileprogress/ProfileProgressActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/profileprogress/ProfileProgressActivityTest.kt
index 6b05ea0bf15..4716612c00e 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/profileprogress/ProfileProgressActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/profileprogress/ProfileProgressActivityTest.kt
@@ -50,7 +50,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -144,7 +145,7 @@ class ProfileProgressActivityTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -154,7 +155,7 @@ class ProfileProgressActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/profileprogress/ProfileProgressFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/profileprogress/ProfileProgressFragmentTest.kt
index b2955dcb059..3593c3a83b7 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/profileprogress/ProfileProgressFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/profileprogress/ProfileProgressFragmentTest.kt
@@ -90,7 +90,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -845,7 +846,7 @@ class ProfileProgressFragmentTest {
LogStorageModule::class, CachingTestModule::class, PrimeTopicAssetsControllerModule::class,
ExpirationMetaDataRetrieverModule::class, ViewBindingShimModule::class,
RatioInputModule::class, ApplicationStartupListenerModule::class,
- LogUploadWorkerModule::class, WorkManagerConfigurationModule::class,
+ LogReportWorkerModule::class, WorkManagerConfigurationModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -855,7 +856,7 @@ class ProfileProgressFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/recyclerview/BindableAdapterTest.kt b/app/src/sharedTest/java/org/oppia/android/app/recyclerview/BindableAdapterTest.kt
index a0b1d3577a3..e8a168ee1af 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/recyclerview/BindableAdapterTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/recyclerview/BindableAdapterTest.kt
@@ -88,7 +88,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -755,7 +756,7 @@ class BindableAdapterTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -766,7 +767,7 @@ class BindableAdapterTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/resumelesson/ResumeLessonActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/resumelesson/ResumeLessonActivityTest.kt
index 636fe149c84..e76a4ac0ab6 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/resumelesson/ResumeLessonActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/resumelesson/ResumeLessonActivityTest.kt
@@ -65,7 +65,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -214,7 +215,7 @@ class ResumeLessonActivityTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -224,7 +225,7 @@ class ResumeLessonActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/resumelesson/ResumeLessonFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/resumelesson/ResumeLessonFragmentTest.kt
index bb5a9228d51..1bf70dde862 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/resumelesson/ResumeLessonFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/resumelesson/ResumeLessonFragmentTest.kt
@@ -65,7 +65,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -303,7 +304,7 @@ class ResumeLessonFragmentTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -313,7 +314,7 @@ class ResumeLessonFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditActivityTest.kt
index efdbb35eeff..f950c6f152c 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditActivityTest.kt
@@ -66,7 +66,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.profile.ProfileManagementController
@@ -367,7 +368,7 @@ class ProfileEditActivityTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -377,7 +378,7 @@ class ProfileEditActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditFragmentTest.kt
index ddcda48de71..84d523c5200 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditFragmentTest.kt
@@ -66,7 +66,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.profile.ProfileManagementController
@@ -344,7 +345,7 @@ class ProfileEditFragmentTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -354,7 +355,7 @@ class ProfileEditFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
diff --git a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileListActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileListActivityTest.kt
index 4bf44638958..ea0e29aaac2 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileListActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileListActivityTest.kt
@@ -50,7 +50,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -140,7 +141,7 @@ class ProfileListActivityTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -150,7 +151,7 @@ class ProfileListActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileListFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileListFragmentTest.kt
index bbf88cff9dc..6e8ac36d94f 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileListFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileListFragmentTest.kt
@@ -65,7 +65,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -378,7 +379,7 @@ class ProfileListFragmentTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -388,7 +389,7 @@ class ProfileListFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileRenameActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileRenameActivityTest.kt
index a6a0d30c004..55d6e85a511 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileRenameActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileRenameActivityTest.kt
@@ -51,7 +51,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -162,7 +163,7 @@ class ProfileRenameActivityTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -173,7 +174,7 @@ class ProfileRenameActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileRenameFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileRenameFragmentTest.kt
index f88763417df..9744a3daead 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileRenameFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileRenameFragmentTest.kt
@@ -67,7 +67,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -452,7 +453,7 @@ class ProfileRenameFragmentTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -462,7 +463,7 @@ class ProfileRenameFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileResetPinActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileResetPinActivityTest.kt
index 67a3fd83b5d..38c6df5615d 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileResetPinActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileResetPinActivityTest.kt
@@ -52,7 +52,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -173,7 +174,7 @@ class ProfileResetPinActivityTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -184,7 +185,7 @@ class ProfileResetPinActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileResetPinFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileResetPinFragmentTest.kt
index 4a137a97356..dc210acaa36 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileResetPinFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileResetPinFragmentTest.kt
@@ -68,7 +68,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -1015,7 +1016,7 @@ class ProfileResetPinFragmentTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -1026,7 +1027,7 @@ class ProfileResetPinFragmentTest {
AlgebraicExpressionInputModule::class, MathEquationInputModule::class,
SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/splash/SplashActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/splash/SplashActivityTest.kt
index 3fe1604bb31..e554c9df2e1 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/splash/SplashActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/splash/SplashActivityTest.kt
@@ -73,7 +73,8 @@ import org.oppia.android.domain.onboarding.testing.FakeExpirationMetaDataRetriev
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -478,7 +479,7 @@ class SplashActivityTest {
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverTestModule::class,
ViewBindingShimModule::class, RatioInputModule::class, NetworkConfigProdModule::class,
ApplicationStartupListenerModule::class, HintsAndSolutionConfigModule::class,
- LogUploadWorkerModule::class, WorkManagerConfigurationModule::class,
+ LogReportWorkerModule::class, WorkManagerConfigurationModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
ExplorationStorageModule::class, NetworkModule::class, HintsAndSolutionProdModule::class,
@@ -488,7 +489,7 @@ class SplashActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/story/StoryActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/story/StoryActivityTest.kt
index 9cca4e9781e..54df28345a1 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/story/StoryActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/story/StoryActivityTest.kt
@@ -64,7 +64,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -224,7 +225,7 @@ class StoryActivityTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -234,7 +235,7 @@ class StoryActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/story/StoryFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/story/StoryFragmentTest.kt
index f22f9aeab77..74fae89ca56 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/story/StoryFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/story/StoryFragmentTest.kt
@@ -98,7 +98,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -892,7 +893,7 @@ class StoryFragmentTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -902,7 +903,7 @@ class StoryFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/testing/DragDropTestActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/testing/DragDropTestActivityTest.kt
index 0d3c55261f1..fc866ddceb1 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/testing/DragDropTestActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/testing/DragDropTestActivityTest.kt
@@ -61,7 +61,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -217,7 +218,7 @@ class DragDropTestActivityTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -227,7 +228,7 @@ class DragDropTestActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/testing/ImageRegionSelectionInteractionViewTest.kt b/app/src/sharedTest/java/org/oppia/android/app/testing/ImageRegionSelectionInteractionViewTest.kt
index 54c5f4d0c73..20d315e0475 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/testing/ImageRegionSelectionInteractionViewTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/testing/ImageRegionSelectionInteractionViewTest.kt
@@ -72,7 +72,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -404,7 +405,7 @@ class ImageRegionSelectionInteractionViewTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -414,7 +415,7 @@ class ImageRegionSelectionInteractionViewTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/testing/InputInteractionViewTestActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/testing/InputInteractionViewTestActivityTest.kt
index 68404f0feaa..da4d3031acd 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/testing/InputInteractionViewTestActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/testing/InputInteractionViewTestActivityTest.kt
@@ -67,7 +67,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -1115,7 +1116,7 @@ class InputInteractionViewTestActivityTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -1125,7 +1126,7 @@ class InputInteractionViewTestActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/testing/NavigationDrawerActivityDebugTest.kt b/app/src/sharedTest/java/org/oppia/android/app/testing/NavigationDrawerActivityDebugTest.kt
index 017b47e5702..69a7cfcc0ac 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/testing/NavigationDrawerActivityDebugTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/testing/NavigationDrawerActivityDebugTest.kt
@@ -87,7 +87,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -428,7 +429,7 @@ class NavigationDrawerActivityDebugTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -438,7 +439,7 @@ class NavigationDrawerActivityDebugTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/testing/NavigationDrawerActivityProdTest.kt b/app/src/sharedTest/java/org/oppia/android/app/testing/NavigationDrawerActivityProdTest.kt
index 8acb7046c00..c7a0fc12355 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/testing/NavigationDrawerActivityProdTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/testing/NavigationDrawerActivityProdTest.kt
@@ -95,7 +95,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -977,7 +978,7 @@ class NavigationDrawerActivityProdTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsModule::class, ExplorationStorageModule::class, NetworkModule::class,
@@ -987,7 +988,7 @@ class NavigationDrawerActivityProdTest {
AlgebraicExpressionInputModule::class, MathEquationInputModule::class,
SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/testing/TestFontScaleConfigurationUtilActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/testing/TestFontScaleConfigurationUtilActivityTest.kt
index 42d893f3abb..7488560d8d9 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/testing/TestFontScaleConfigurationUtilActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/testing/TestFontScaleConfigurationUtilActivityTest.kt
@@ -56,7 +56,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -195,7 +196,7 @@ class TestFontScaleConfigurationUtilActivityTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -205,7 +206,7 @@ class TestFontScaleConfigurationUtilActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/testing/TopicTestActivityForStoryTest.kt b/app/src/sharedTest/java/org/oppia/android/app/testing/TopicTestActivityForStoryTest.kt
index 6311b17fa9a..5aebaae32fa 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/testing/TopicTestActivityForStoryTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/testing/TopicTestActivityForStoryTest.kt
@@ -62,7 +62,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -192,7 +193,7 @@ class TopicTestActivityForStoryTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -202,7 +203,7 @@ class TopicTestActivityForStoryTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseListActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseListActivityTest.kt
index 9d2caf4de06..efb85e232b1 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseListActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseListActivityTest.kt
@@ -51,7 +51,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -152,7 +153,7 @@ class LicenseListActivityTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -161,7 +162,8 @@ class LicenseListActivityTest {
AssetModule::class, LocaleProdModule::class, ActivityRecreatorTestModule::class,
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
- LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class
+ LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class,
+ MetricLogSchedulerModule::class
]
)
diff --git a/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseListFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseListFragmentTest.kt
index 31d05596c1c..4fd305d3ce0 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseListFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseListFragmentTest.kt
@@ -67,7 +67,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -362,7 +363,7 @@ class LicenseListFragmentTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -371,7 +372,8 @@ class LicenseListFragmentTest {
AssetModule::class, LocaleProdModule::class, ActivityRecreatorTestModule::class,
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
- LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class
+ LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class,
+ MetricLogSchedulerModule::class
]
)
diff --git a/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseTextViewerActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseTextViewerActivityTest.kt
index 8f88e75d8bb..a751f1b52de 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseTextViewerActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseTextViewerActivityTest.kt
@@ -52,7 +52,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -161,7 +162,7 @@ class LicenseTextViewerActivityTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -170,7 +171,8 @@ class LicenseTextViewerActivityTest {
AssetModule::class, LocaleProdModule::class, ActivityRecreatorTestModule::class,
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
- LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class
+ LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class,
+ MetricLogSchedulerModule::class
]
)
diff --git a/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseTextViewerFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseTextViewerFragmentTest.kt
index 62406e2ba8d..bd5f229906f 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseTextViewerFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseTextViewerFragmentTest.kt
@@ -57,7 +57,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -340,7 +341,7 @@ class LicenseTextViewerFragmentTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -349,7 +350,8 @@ class LicenseTextViewerFragmentTest {
AssetModule::class, LocaleProdModule::class, ActivityRecreatorTestModule::class,
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
- LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class
+ LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class,
+ MetricLogSchedulerModule::class
]
)
diff --git a/app/src/sharedTest/java/org/oppia/android/app/thirdparty/ThirdPartyDependencyListActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/thirdparty/ThirdPartyDependencyListActivityTest.kt
index 6f904e3c2f9..2298212d383 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/thirdparty/ThirdPartyDependencyListActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/thirdparty/ThirdPartyDependencyListActivityTest.kt
@@ -51,7 +51,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -149,7 +150,7 @@ class ThirdPartyDependencyListActivityTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -158,7 +159,8 @@ class ThirdPartyDependencyListActivityTest {
AssetModule::class, LocaleProdModule::class, ActivityRecreatorTestModule::class,
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
- LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class
+ LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class,
+ MetricLogSchedulerModule::class
]
)
diff --git a/app/src/sharedTest/java/org/oppia/android/app/thirdparty/ThirdPartyDependencyListFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/thirdparty/ThirdPartyDependencyListFragmentTest.kt
index 1109f817ac6..f9dd5befd2e 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/thirdparty/ThirdPartyDependencyListFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/thirdparty/ThirdPartyDependencyListFragmentTest.kt
@@ -66,7 +66,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -472,7 +473,7 @@ class ThirdPartyDependencyListFragmentTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -481,7 +482,8 @@ class ThirdPartyDependencyListFragmentTest {
AssetModule::class, LocaleProdModule::class, ActivityRecreatorTestModule::class,
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
- LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class
+ LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class,
+ MetricLogSchedulerModule::class
]
)
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/TopicActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/TopicActivityTest.kt
index 93e663a8a4a..15c80f80eca 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/TopicActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/TopicActivityTest.kt
@@ -63,7 +63,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -198,7 +199,7 @@ class TopicActivityTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -208,7 +209,7 @@ class TopicActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt
index 48700e24d59..87fb560776c 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt
@@ -74,7 +74,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -652,7 +653,7 @@ class TopicFragmentTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -663,7 +664,7 @@ class TopicFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/conceptcard/ConceptCardFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/conceptcard/ConceptCardFragmentTest.kt
index c0898715487..6a3c9d7be97 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/conceptcard/ConceptCardFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/conceptcard/ConceptCardFragmentTest.kt
@@ -72,7 +72,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -423,7 +424,7 @@ class ConceptCardFragmentTest {
AccessibilityTestModule::class, LogStorageModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -434,7 +435,7 @@ class ConceptCardFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/info/TopicInfoFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/info/TopicInfoFragmentTest.kt
index 4c8c0eef8b6..e743d17c05d 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/info/TopicInfoFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/info/TopicInfoFragmentTest.kt
@@ -76,7 +76,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -479,7 +480,7 @@ class TopicInfoFragmentTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -490,7 +491,7 @@ class TopicInfoFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/lessons/TopicLessonsFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/lessons/TopicLessonsFragmentTest.kt
index 32b7a7086c4..2e12f85d07a 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/lessons/TopicLessonsFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/lessons/TopicLessonsFragmentTest.kt
@@ -83,7 +83,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -1008,7 +1009,7 @@ class TopicLessonsFragmentTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -1019,7 +1020,7 @@ class TopicLessonsFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/practice/TopicPracticeFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/practice/TopicPracticeFragmentTest.kt
index 5a15bdcbd35..98ae842aa2d 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/practice/TopicPracticeFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/practice/TopicPracticeFragmentTest.kt
@@ -73,7 +73,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -424,7 +425,7 @@ class TopicPracticeFragmentTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -435,7 +436,7 @@ class TopicPracticeFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/questionplayer/QuestionPlayerActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/questionplayer/QuestionPlayerActivityTest.kt
index 18bedd79642..8fbee49074d 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/questionplayer/QuestionPlayerActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/questionplayer/QuestionPlayerActivityTest.kt
@@ -96,7 +96,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.InternalMasteryMultiplyFactor
@@ -715,7 +716,7 @@ class QuestionPlayerActivityTest {
ViewBindingShimModule::class, ApplicationStartupListenerModule::class,
HintsAndSolutionConfigFastShowTestModule::class, HintsAndSolutionProdModule::class,
WorkManagerConfigurationModule::class, FirebaseLogUploaderModule::class,
- LogUploadWorkerModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
+ LogReportWorkerModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
ExplorationStorageModule::class, NetworkModule::class, NetworkConfigProdModule::class,
NetworkConnectionUtilDebugModule::class, NetworkConnectionDebugUtilModule::class,
@@ -724,7 +725,7 @@ class QuestionPlayerActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/revision/TopicRevisionFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/revision/TopicRevisionFragmentTest.kt
index 726c9e6eb80..86da92fe690 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/revision/TopicRevisionFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/revision/TopicRevisionFragmentTest.kt
@@ -74,7 +74,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -320,7 +321,7 @@ class TopicRevisionFragmentTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -331,7 +332,7 @@ class TopicRevisionFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/revisioncard/RevisionCardActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/revisioncard/RevisionCardActivityTest.kt
index c83c20ddef9..6d8fbf9be40 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/revisioncard/RevisionCardActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/revisioncard/RevisionCardActivityTest.kt
@@ -64,7 +64,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -274,7 +275,7 @@ class RevisionCardActivityTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -285,7 +286,7 @@ class RevisionCardActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/revisioncard/RevisionCardFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/revisioncard/RevisionCardFragmentTest.kt
index e0f30bbef08..84f04139d51 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/revisioncard/RevisionCardFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/revisioncard/RevisionCardFragmentTest.kt
@@ -82,7 +82,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -590,7 +591,7 @@ class RevisionCardFragmentTest {
AccessibilityTestModule::class, LogStorageModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -601,7 +602,7 @@ class RevisionCardFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/utility/RatioExtensionsTest.kt b/app/src/sharedTest/java/org/oppia/android/app/utility/RatioExtensionsTest.kt
index c9dd3e508cc..3596c8533d1 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/utility/RatioExtensionsTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/utility/RatioExtensionsTest.kt
@@ -49,7 +49,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -147,7 +148,7 @@ class RatioExtensionsTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -158,7 +159,7 @@ class RatioExtensionsTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughActivityTest.kt
index 4eca4362df3..cd49b90d400 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughActivityTest.kt
@@ -62,7 +62,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -225,7 +226,7 @@ class WalkthroughActivityTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -236,7 +237,7 @@ class WalkthroughActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughFinalFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughFinalFragmentTest.kt
index 5180aa3350b..7bdea47cd8c 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughFinalFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughFinalFragmentTest.kt
@@ -65,7 +65,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -282,7 +283,7 @@ class WalkthroughFinalFragmentTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -293,7 +294,7 @@ class WalkthroughFinalFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughTopicListFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughTopicListFragmentTest.kt
index 7e51303ff99..f334d5e7080 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughTopicListFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughTopicListFragmentTest.kt
@@ -66,7 +66,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -308,7 +309,7 @@ class WalkthroughTopicListFragmentTest {
AccessibilityTestModule::class, LogStorageModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -319,7 +320,7 @@ class WalkthroughTopicListFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughWelcomeFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughWelcomeFragmentTest.kt
index d124e67a7fb..59b4f9f4ca8 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughWelcomeFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughWelcomeFragmentTest.kt
@@ -61,7 +61,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -205,7 +206,7 @@ class WalkthroughWelcomeFragmentTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -216,7 +217,7 @@ class WalkthroughWelcomeFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/activity/ActivityIntentFactoriesTest.kt b/app/src/test/java/org/oppia/android/app/activity/ActivityIntentFactoriesTest.kt
index 92711443d86..f0491f38b65 100644
--- a/app/src/test/java/org/oppia/android/app/activity/ActivityIntentFactoriesTest.kt
+++ b/app/src/test/java/org/oppia/android/app/activity/ActivityIntentFactoriesTest.kt
@@ -52,7 +52,8 @@ import org.oppia.android.domain.onboarding.testing.ExpirationMetaDataRetrieverTe
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -171,7 +172,7 @@ class ActivityIntentFactoriesTest {
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverTestModule::class,
ViewBindingShimModule::class, RatioInputModule::class, NetworkConfigProdModule::class,
ApplicationStartupListenerModule::class, HintsAndSolutionConfigModule::class,
- LogUploadWorkerModule::class, WorkManagerConfigurationModule::class,
+ LogReportWorkerModule::class, WorkManagerConfigurationModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
ExplorationStorageModule::class, NetworkModule::class, HintsAndSolutionProdModule::class,
@@ -181,7 +182,7 @@ class ActivityIntentFactoriesTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/home/HomeActivityLocalTest.kt b/app/src/test/java/org/oppia/android/app/home/HomeActivityLocalTest.kt
index d62ea81ea88..445649d393b 100644
--- a/app/src/test/java/org/oppia/android/app/home/HomeActivityLocalTest.kt
+++ b/app/src/test/java/org/oppia/android/app/home/HomeActivityLocalTest.kt
@@ -53,7 +53,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -142,7 +143,7 @@ class HomeActivityLocalTest {
ImageClickInputModule::class, LogStorageModule::class, IntentFactoryShimModule::class,
ViewBindingShimModule::class, CachingTestModule::class, RatioInputModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
WorkManagerConfigurationModule::class, HintsAndSolutionConfigModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -153,7 +154,7 @@ class HomeActivityLocalTest {
AlgebraicExpressionInputModule::class, MathEquationInputModule::class,
SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/parser/FractionParsingUiErrorTest.kt b/app/src/test/java/org/oppia/android/app/parser/FractionParsingUiErrorTest.kt
index 1c456d24630..d6cb209d2c1 100644
--- a/app/src/test/java/org/oppia/android/app/parser/FractionParsingUiErrorTest.kt
+++ b/app/src/test/java/org/oppia/android/app/parser/FractionParsingUiErrorTest.kt
@@ -48,7 +48,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -253,7 +254,7 @@ class FractionParsingUiErrorTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -263,7 +264,7 @@ class FractionParsingUiErrorTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/parser/StringToRatioParserTest.kt b/app/src/test/java/org/oppia/android/app/parser/StringToRatioParserTest.kt
index 27063d77e1f..73ab39d434f 100644
--- a/app/src/test/java/org/oppia/android/app/parser/StringToRatioParserTest.kt
+++ b/app/src/test/java/org/oppia/android/app/parser/StringToRatioParserTest.kt
@@ -49,7 +49,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -257,7 +258,7 @@ class StringToRatioParserTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -267,7 +268,7 @@ class StringToRatioParserTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/player/exploration/ExplorationActivityLocalTest.kt b/app/src/test/java/org/oppia/android/app/player/exploration/ExplorationActivityLocalTest.kt
index 360220da811..1c875e82863 100644
--- a/app/src/test/java/org/oppia/android/app/player/exploration/ExplorationActivityLocalTest.kt
+++ b/app/src/test/java/org/oppia/android/app/player/exploration/ExplorationActivityLocalTest.kt
@@ -54,7 +54,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -203,7 +204,7 @@ class ExplorationActivityLocalTest {
ImageClickInputModule::class, LogStorageModule::class, IntentFactoryShimModule::class,
ViewBindingShimModule::class, CachingTestModule::class, RatioInputModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
WorkManagerConfigurationModule::class, HintsAndSolutionConfigModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -214,7 +215,7 @@ class ExplorationActivityLocalTest {
AlgebraicExpressionInputModule::class, MathEquationInputModule::class,
SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/player/state/StateFragmentLocalTest.kt b/app/src/test/java/org/oppia/android/app/player/state/StateFragmentLocalTest.kt
index 5589132a0f7..30849532780 100644
--- a/app/src/test/java/org/oppia/android/app/player/state/StateFragmentLocalTest.kt
+++ b/app/src/test/java/org/oppia/android/app/player/state/StateFragmentLocalTest.kt
@@ -108,7 +108,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -2286,7 +2287,7 @@ class StateFragmentLocalTest {
AccessibilityTestModule::class, LogStorageModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -2296,7 +2297,7 @@ class StateFragmentLocalTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/profile/ProfileChooserFragmentLocalTest.kt b/app/src/test/java/org/oppia/android/app/profile/ProfileChooserFragmentLocalTest.kt
index 9831c6fe66f..df5ab8f58d0 100644
--- a/app/src/test/java/org/oppia/android/app/profile/ProfileChooserFragmentLocalTest.kt
+++ b/app/src/test/java/org/oppia/android/app/profile/ProfileChooserFragmentLocalTest.kt
@@ -50,7 +50,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -133,7 +134,7 @@ class ProfileChooserFragmentLocalTest {
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, NetworkConfigProdModule::class,
ApplicationStartupListenerModule::class, HintsAndSolutionConfigModule::class,
- LogUploadWorkerModule::class, WorkManagerConfigurationModule::class,
+ LogReportWorkerModule::class, WorkManagerConfigurationModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
ExplorationStorageModule::class, NetworkModule::class, HintsAndSolutionProdModule::class,
@@ -142,7 +143,7 @@ class ProfileChooserFragmentLocalTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/story/StoryActivityLocalTest.kt b/app/src/test/java/org/oppia/android/app/story/StoryActivityLocalTest.kt
index ebca8ce96a5..5d9cc5e3e75 100644
--- a/app/src/test/java/org/oppia/android/app/story/StoryActivityLocalTest.kt
+++ b/app/src/test/java/org/oppia/android/app/story/StoryActivityLocalTest.kt
@@ -52,7 +52,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -157,7 +158,7 @@ class StoryActivityLocalTest {
ImageClickInputModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -167,7 +168,7 @@ class StoryActivityLocalTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/testing/CompletedStoryListSpanTest.kt b/app/src/test/java/org/oppia/android/app/testing/CompletedStoryListSpanTest.kt
index 724a72ab179..86a05a175dc 100644
--- a/app/src/test/java/org/oppia/android/app/testing/CompletedStoryListSpanTest.kt
+++ b/app/src/test/java/org/oppia/android/app/testing/CompletedStoryListSpanTest.kt
@@ -54,7 +54,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -165,7 +166,7 @@ class CompletedStoryListSpanTest {
ImageClickInputModule::class, LogStorageModule::class, IntentFactoryShimModule::class,
ViewBindingShimModule::class, CachingTestModule::class, RatioInputModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
WorkManagerConfigurationModule::class, HintsAndSolutionConfigModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -176,7 +177,7 @@ class CompletedStoryListSpanTest {
AlgebraicExpressionInputModule::class, MathEquationInputModule::class,
SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/testing/HomeSpanTest.kt b/app/src/test/java/org/oppia/android/app/testing/HomeSpanTest.kt
index db17bd4e90e..83e920a77bd 100644
--- a/app/src/test/java/org/oppia/android/app/testing/HomeSpanTest.kt
+++ b/app/src/test/java/org/oppia/android/app/testing/HomeSpanTest.kt
@@ -54,7 +54,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -179,7 +180,7 @@ class HomeSpanTest {
ImageClickInputModule::class, LogStorageModule::class, IntentFactoryShimModule::class,
ViewBindingShimModule::class, CachingTestModule::class, RatioInputModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
WorkManagerConfigurationModule::class, HintsAndSolutionConfigModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -190,7 +191,7 @@ class HomeSpanTest {
AlgebraicExpressionInputModule::class, MathEquationInputModule::class,
SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/testing/OngoingTopicListSpanTest.kt b/app/src/test/java/org/oppia/android/app/testing/OngoingTopicListSpanTest.kt
index e1940a4ff1a..fc6c6aff74e 100644
--- a/app/src/test/java/org/oppia/android/app/testing/OngoingTopicListSpanTest.kt
+++ b/app/src/test/java/org/oppia/android/app/testing/OngoingTopicListSpanTest.kt
@@ -55,7 +55,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -176,7 +177,7 @@ class OngoingTopicListSpanTest {
ImageClickInputModule::class, LogStorageModule::class, IntentFactoryShimModule::class,
ViewBindingShimModule::class, CachingTestModule::class, RatioInputModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
WorkManagerConfigurationModule::class, HintsAndSolutionConfigModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -187,7 +188,7 @@ class OngoingTopicListSpanTest {
AlgebraicExpressionInputModule::class, MathEquationInputModule::class,
SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/testing/PlatformParameterIntegrationTest.kt b/app/src/test/java/org/oppia/android/app/testing/PlatformParameterIntegrationTest.kt
index 6a6e051cc77..5d30677deb7 100644
--- a/app/src/test/java/org/oppia/android/app/testing/PlatformParameterIntegrationTest.kt
+++ b/app/src/test/java/org/oppia/android/app/testing/PlatformParameterIntegrationTest.kt
@@ -68,7 +68,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterController
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
@@ -349,7 +350,7 @@ class PlatformParameterIntegrationTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -360,7 +361,7 @@ class PlatformParameterIntegrationTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/testing/ProfileChooserSpanTest.kt b/app/src/test/java/org/oppia/android/app/testing/ProfileChooserSpanTest.kt
index 9b0988a43ed..ac18c7ff49f 100644
--- a/app/src/test/java/org/oppia/android/app/testing/ProfileChooserSpanTest.kt
+++ b/app/src/test/java/org/oppia/android/app/testing/ProfileChooserSpanTest.kt
@@ -53,7 +53,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -378,7 +379,7 @@ class ProfileChooserSpanTest {
ImageClickInputModule::class, LogStorageModule::class, IntentFactoryShimModule::class,
ViewBindingShimModule::class, CachingTestModule::class, RatioInputModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
WorkManagerConfigurationModule::class, HintsAndSolutionConfigModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -389,7 +390,7 @@ class ProfileChooserSpanTest {
AlgebraicExpressionInputModule::class, MathEquationInputModule::class,
SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/testing/ProfileProgressSpanCountTest.kt b/app/src/test/java/org/oppia/android/app/testing/ProfileProgressSpanCountTest.kt
index ddb8bf06ac8..7b515278346 100644
--- a/app/src/test/java/org/oppia/android/app/testing/ProfileProgressSpanCountTest.kt
+++ b/app/src/test/java/org/oppia/android/app/testing/ProfileProgressSpanCountTest.kt
@@ -54,7 +54,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -162,7 +163,7 @@ class ProfileProgressSpanCountTest {
ImageClickInputModule::class, LogStorageModule::class, IntentFactoryShimModule::class,
ViewBindingShimModule::class, CachingTestModule::class, RatioInputModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
WorkManagerConfigurationModule::class, HintsAndSolutionConfigModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -173,7 +174,7 @@ class ProfileProgressSpanCountTest {
AlgebraicExpressionInputModule::class, MathEquationInputModule::class,
SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/testing/RecentlyPlayedSpanTest.kt b/app/src/test/java/org/oppia/android/app/testing/RecentlyPlayedSpanTest.kt
index 493ac5ce52b..4571ab23451 100644
--- a/app/src/test/java/org/oppia/android/app/testing/RecentlyPlayedSpanTest.kt
+++ b/app/src/test/java/org/oppia/android/app/testing/RecentlyPlayedSpanTest.kt
@@ -56,7 +56,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -297,7 +298,7 @@ class RecentlyPlayedSpanTest {
ImageClickInputModule::class, LogStorageModule::class, IntentFactoryShimModule::class,
ViewBindingShimModule::class, CachingTestModule::class, RatioInputModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
WorkManagerConfigurationModule::class, HintsAndSolutionConfigModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -308,7 +309,7 @@ class RecentlyPlayedSpanTest {
AlgebraicExpressionInputModule::class, MathEquationInputModule::class,
SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/testing/TopicRevisionSpanTest.kt b/app/src/test/java/org/oppia/android/app/testing/TopicRevisionSpanTest.kt
index edf710c64b4..9ea7e810383 100644
--- a/app/src/test/java/org/oppia/android/app/testing/TopicRevisionSpanTest.kt
+++ b/app/src/test/java/org/oppia/android/app/testing/TopicRevisionSpanTest.kt
@@ -53,7 +53,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -162,7 +163,7 @@ class TopicRevisionSpanTest {
ImageClickInputModule::class, LogStorageModule::class, IntentFactoryShimModule::class,
ViewBindingShimModule::class, CachingTestModule::class, RatioInputModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
WorkManagerConfigurationModule::class, HintsAndSolutionConfigModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -173,7 +174,7 @@ class TopicRevisionSpanTest {
AlgebraicExpressionInputModule::class, MathEquationInputModule::class,
SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/testing/activity/TestActivityTest.kt b/app/src/test/java/org/oppia/android/app/testing/activity/TestActivityTest.kt
index 1866c48e456..bb510bd60c1 100644
--- a/app/src/test/java/org/oppia/android/app/testing/activity/TestActivityTest.kt
+++ b/app/src/test/java/org/oppia/android/app/testing/activity/TestActivityTest.kt
@@ -50,7 +50,8 @@ import org.oppia.android.domain.onboarding.testing.ExpirationMetaDataRetrieverTe
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -188,7 +189,7 @@ class TestActivityTest {
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverTestModule::class,
ViewBindingShimModule::class, RatioInputModule::class, NetworkConfigProdModule::class,
ApplicationStartupListenerModule::class, HintsAndSolutionConfigModule::class,
- LogUploadWorkerModule::class, WorkManagerConfigurationModule::class,
+ LogReportWorkerModule::class, WorkManagerConfigurationModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
ExplorationStorageModule::class, NetworkModule::class, HintsAndSolutionProdModule::class,
@@ -198,7 +199,7 @@ class TestActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/testing/administratorcontrols/AdministratorControlsFragmentTest.kt b/app/src/test/java/org/oppia/android/app/testing/administratorcontrols/AdministratorControlsFragmentTest.kt
index 14ce543faa6..1f95d05540e 100644
--- a/app/src/test/java/org/oppia/android/app/testing/administratorcontrols/AdministratorControlsFragmentTest.kt
+++ b/app/src/test/java/org/oppia/android/app/testing/administratorcontrols/AdministratorControlsFragmentTest.kt
@@ -60,7 +60,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -187,7 +188,7 @@ class AdministratorControlsFragmentTest {
AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -197,7 +198,7 @@ class AdministratorControlsFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/testing/options/OptionsFragmentTest.kt b/app/src/test/java/org/oppia/android/app/testing/options/OptionsFragmentTest.kt
index 0c9b6968ccd..3ebe6f52678 100644
--- a/app/src/test/java/org/oppia/android/app/testing/options/OptionsFragmentTest.kt
+++ b/app/src/test/java/org/oppia/android/app/testing/options/OptionsFragmentTest.kt
@@ -61,7 +61,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
import org.oppia.android.domain.topic.PrimeTopicAssetsControllerModule
@@ -242,7 +243,7 @@ class OptionsFragmentTest {
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, ApplicationStartupListenerModule::class,
RatioInputModule::class, HintsAndSolutionConfigModule::class, NetworkConfigProdModule::class,
- WorkManagerConfigurationModule::class, LogUploadWorkerModule::class,
+ WorkManagerConfigurationModule::class, LogReportWorkerModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
ExplorationStorageModule::class, NetworkModule::class, HintsAndSolutionProdModule::class,
@@ -251,7 +252,7 @@ class OptionsFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/testing/player/split/PlayerSplitScreenTest.kt b/app/src/test/java/org/oppia/android/app/testing/player/split/PlayerSplitScreenTest.kt
index 5b20e41d31c..a7d14d4a6c2 100644
--- a/app/src/test/java/org/oppia/android/app/testing/player/split/PlayerSplitScreenTest.kt
+++ b/app/src/test/java/org/oppia/android/app/testing/player/split/PlayerSplitScreenTest.kt
@@ -51,7 +51,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -195,7 +196,7 @@ class PlayerSplitScreenTest {
ImageClickInputModule::class, LogStorageModule::class, IntentFactoryShimModule::class,
ViewBindingShimModule::class, CachingTestModule::class, RatioInputModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
WorkManagerConfigurationModule::class, HintsAndSolutionConfigModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -206,7 +207,7 @@ class PlayerSplitScreenTest {
AlgebraicExpressionInputModule::class, MathEquationInputModule::class,
SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/testing/player/state/StateFragmentAccessibilityTest.kt b/app/src/test/java/org/oppia/android/app/testing/player/state/StateFragmentAccessibilityTest.kt
index 8c22af7c2d9..11c88ca340c 100644
--- a/app/src/test/java/org/oppia/android/app/testing/player/state/StateFragmentAccessibilityTest.kt
+++ b/app/src/test/java/org/oppia/android/app/testing/player/state/StateFragmentAccessibilityTest.kt
@@ -57,7 +57,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -202,7 +203,7 @@ class StateFragmentAccessibilityTest {
ImageClickInputModule::class, LogStorageModule::class, IntentFactoryShimModule::class,
ViewBindingShimModule::class, CachingTestModule::class, RatioInputModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
WorkManagerConfigurationModule::class, HintsAndSolutionConfigModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -213,7 +214,7 @@ class StateFragmentAccessibilityTest {
AlgebraicExpressionInputModule::class, MathEquationInputModule::class,
SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/topic/info/TopicInfoFragmentLocalTest.kt b/app/src/test/java/org/oppia/android/app/topic/info/TopicInfoFragmentLocalTest.kt
index fd517ae0c36..68b9da3603a 100644
--- a/app/src/test/java/org/oppia/android/app/topic/info/TopicInfoFragmentLocalTest.kt
+++ b/app/src/test/java/org/oppia/android/app/topic/info/TopicInfoFragmentLocalTest.kt
@@ -50,7 +50,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -145,7 +146,7 @@ class TopicInfoFragmentLocalTest {
ImageClickInputModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -155,7 +156,7 @@ class TopicInfoFragmentLocalTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/topic/lessons/TopicLessonsFragmentLocalTest.kt b/app/src/test/java/org/oppia/android/app/topic/lessons/TopicLessonsFragmentLocalTest.kt
index 919664f7e58..cd09a71eb8b 100644
--- a/app/src/test/java/org/oppia/android/app/topic/lessons/TopicLessonsFragmentLocalTest.kt
+++ b/app/src/test/java/org/oppia/android/app/topic/lessons/TopicLessonsFragmentLocalTest.kt
@@ -49,7 +49,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -148,7 +149,7 @@ class TopicLessonsFragmentLocalTest {
ImageClickInputModule::class, LogStorageModule::class, CachingTestModule::class,
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class,
- ApplicationStartupListenerModule::class, LogUploadWorkerModule::class,
+ ApplicationStartupListenerModule::class, LogReportWorkerModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
@@ -158,7 +159,7 @@ class TopicLessonsFragmentLocalTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/topic/questionplayer/QuestionPlayerActivityLocalTest.kt b/app/src/test/java/org/oppia/android/app/topic/questionplayer/QuestionPlayerActivityLocalTest.kt
index 35862612657..aedeb8e43cc 100644
--- a/app/src/test/java/org/oppia/android/app/topic/questionplayer/QuestionPlayerActivityLocalTest.kt
+++ b/app/src/test/java/org/oppia/android/app/topic/questionplayer/QuestionPlayerActivityLocalTest.kt
@@ -66,7 +66,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.InternalMasteryMultiplyFactor
@@ -497,7 +498,7 @@ class QuestionPlayerActivityLocalTest {
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, ApplicationStartupListenerModule::class,
RatioInputModule::class, HintsAndSolutionConfigModule::class, NetworkConfigProdModule::class,
- LogUploadWorkerModule::class, WorkManagerConfigurationModule::class,
+ LogReportWorkerModule::class, WorkManagerConfigurationModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
ExplorationStorageModule::class, NetworkModule::class, HintsAndSolutionProdModule::class,
@@ -506,7 +507,7 @@ class QuestionPlayerActivityLocalTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/topic/revisioncard/RevisionCardActivityLocalTest.kt b/app/src/test/java/org/oppia/android/app/topic/revisioncard/RevisionCardActivityLocalTest.kt
index fda93fb355e..510f56bd197 100644
--- a/app/src/test/java/org/oppia/android/app/topic/revisioncard/RevisionCardActivityLocalTest.kt
+++ b/app/src/test/java/org/oppia/android/app/topic/revisioncard/RevisionCardActivityLocalTest.kt
@@ -49,7 +49,8 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -138,7 +139,7 @@ class RevisionCardActivityLocalTest {
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class,
ViewBindingShimModule::class, RatioInputModule::class, NetworkConfigProdModule::class,
ApplicationStartupListenerModule::class, HintsAndSolutionConfigModule::class,
- LogUploadWorkerModule::class, WorkManagerConfigurationModule::class,
+ LogReportWorkerModule::class, WorkManagerConfigurationModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
ExplorationStorageModule::class, NetworkModule::class, HintsAndSolutionProdModule::class,
@@ -147,7 +148,7 @@ class RevisionCardActivityLocalTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/translation/AppLanguageResourceHandlerTest.kt b/app/src/test/java/org/oppia/android/app/translation/AppLanguageResourceHandlerTest.kt
index e23173d0f1b..3ef2af12404 100644
--- a/app/src/test/java/org/oppia/android/app/translation/AppLanguageResourceHandlerTest.kt
+++ b/app/src/test/java/org/oppia/android/app/translation/AppLanguageResourceHandlerTest.kt
@@ -55,7 +55,8 @@ import org.oppia.android.domain.onboarding.testing.ExpirationMetaDataRetrieverTe
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -546,7 +547,7 @@ class AppLanguageResourceHandlerTest {
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverTestModule::class,
ViewBindingShimModule::class, RatioInputModule::class, NetworkConfigProdModule::class,
ApplicationStartupListenerModule::class, HintsAndSolutionConfigModule::class,
- LogUploadWorkerModule::class, WorkManagerConfigurationModule::class,
+ LogReportWorkerModule::class, WorkManagerConfigurationModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
ExplorationStorageModule::class, NetworkModule::class, HintsAndSolutionProdModule::class,
@@ -556,7 +557,7 @@ class AppLanguageResourceHandlerTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/translation/AppLanguageWatcherMixinTest.kt b/app/src/test/java/org/oppia/android/app/translation/AppLanguageWatcherMixinTest.kt
index daa9f02e4a6..21ac94faac3 100644
--- a/app/src/test/java/org/oppia/android/app/translation/AppLanguageWatcherMixinTest.kt
+++ b/app/src/test/java/org/oppia/android/app/translation/AppLanguageWatcherMixinTest.kt
@@ -60,7 +60,8 @@ import org.oppia.android.domain.onboarding.testing.ExpirationMetaDataRetrieverTe
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -261,7 +262,7 @@ class AppLanguageWatcherMixinTest {
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverTestModule::class,
ViewBindingShimModule::class, RatioInputModule::class, NetworkConfigProdModule::class,
ApplicationStartupListenerModule::class, HintsAndSolutionConfigModule::class,
- LogUploadWorkerModule::class, WorkManagerConfigurationModule::class,
+ LogReportWorkerModule::class, WorkManagerConfigurationModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
ExplorationStorageModule::class, NetworkModule::class, HintsAndSolutionProdModule::class,
@@ -271,7 +272,7 @@ class AppLanguageWatcherMixinTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/utility/math/MathExpressionAccessibilityUtilTest.kt b/app/src/test/java/org/oppia/android/app/utility/math/MathExpressionAccessibilityUtilTest.kt
index badd403918f..d742b20a586 100644
--- a/app/src/test/java/org/oppia/android/app/utility/math/MathExpressionAccessibilityUtilTest.kt
+++ b/app/src/test/java/org/oppia/android/app/utility/math/MathExpressionAccessibilityUtilTest.kt
@@ -67,7 +67,8 @@ import org.oppia.android.domain.onboarding.testing.ExpirationMetaDataRetrieverTe
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -1320,7 +1321,7 @@ class MathExpressionAccessibilityUtilTest {
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverTestModule::class,
ViewBindingShimModule::class, RatioInputModule::class, NetworkConfigProdModule::class,
ApplicationStartupListenerModule::class, HintsAndSolutionConfigModule::class,
- LogUploadWorkerModule::class, WorkManagerConfigurationModule::class,
+ LogReportWorkerModule::class, WorkManagerConfigurationModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
ExplorationStorageModule::class, NetworkModule::class, HintsAndSolutionProdModule::class,
@@ -1330,7 +1331,7 @@ class MathExpressionAccessibilityUtilTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/domain/BUILD.bazel b/domain/BUILD.bazel
index 3a3d9f37f74..e13cc36c9a6 100755
--- a/domain/BUILD.bazel
+++ b/domain/BUILD.bazel
@@ -107,6 +107,7 @@ kt_android_library(
"//domain/src/main/java/org/oppia/android/domain/oppialogger:oppia_logger",
"//domain/src/main/java/org/oppia/android/domain/oppialogger:startup_listener",
"//domain/src/main/java/org/oppia/android/domain/oppialogger/exceptions:controller",
+ "//domain/src/main/java/org/oppia/android/domain/oppialogger/logscheduler:metric_log_scheduling_worker_factory",
"//domain/src/main/java/org/oppia/android/domain/oppialogger/loguploader:worker_factory",
"//domain/src/main/java/org/oppia/android/domain/profile:profile_management_controller",
"//domain/src/main/java/org/oppia/android/domain/state:state_deck",
@@ -182,8 +183,10 @@ TEST_DEPS = [
"//domain/src/main/java/org/oppia/android/domain/onboarding:state_controller",
"//domain/src/main/java/org/oppia/android/domain/oppialogger:prod_module",
"//domain/src/main/java/org/oppia/android/domain/oppialogger/analytics:prod_module",
+ "//domain/src/main/java/org/oppia/android/domain/oppialogger/analytics/testing:fake_log_scheduler",
"//domain/src/main/java/org/oppia/android/domain/oppialogger/exceptions:logger_module",
"//domain/src/main/java/org/oppia/android/domain/oppialogger/exceptions:startup_listener",
+ "//domain/src/main/java/org/oppia/android/domain/oppialogger/logscheduler:metric_log_scheduler_module",
"//domain/src/main/java/org/oppia/android/domain/oppialogger/loguploader:worker_factory",
"//domain/src/main/java/org/oppia/android/domain/oppialogger/loguploader:worker_module",
"//domain/src/main/java/org/oppia/android/domain/testing/oppialogger/loguploader:fake_log_uploader",
@@ -212,6 +215,9 @@ TEST_DEPS = [
"//utility/src/main/java/org/oppia/android/util/extensions:context_extensions",
"//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/logging/firebase:prod_module",
+ "//utility/src/main/java/org/oppia/android/util/logging/performancemetrics:performance_metrics_assessor_module",
+ "//utility/src/main/java/org/oppia/android/util/logging/performancemetrics:performance_metrics_configurations_module",
"//utility/src/main/java/org/oppia/android/util/networking:debug_module",
"//utility/src/main/java/org/oppia/android/util/networking:debug_util_module",
"//utility/src/main/java/org/oppia/android/util/system:prod_module",
diff --git a/domain/src/main/java/org/oppia/android/domain/oppialogger/LogStorageModule.kt b/domain/src/main/java/org/oppia/android/domain/oppialogger/LogStorageModule.kt
index bea59db840e..73fe03a7a3d 100644
--- a/domain/src/main/java/org/oppia/android/domain/oppialogger/LogStorageModule.kt
+++ b/domain/src/main/java/org/oppia/android/domain/oppialogger/LogStorageModule.kt
@@ -10,6 +10,9 @@ annotation class EventLogStorageCacheSize
@Qualifier
annotation class ExceptionLogStorageCacheSize
+@Qualifier
+annotation class PerformanceMetricsLogStorageCacheSize
+
/** Provider to return any constants required during the storage of log reports. */
@Module
class LogStorageModule {
@@ -33,4 +36,14 @@ class LogStorageModule {
@Provides
@ExceptionLogStorageCacheSize
fun provideExceptionLogStorageCacheSize(): Int = 25
+
+ /**
+ * Provides the maximum number of performance metrics logs that can be cached on disk.
+ *
+ * At a configured cache size of 25k records & estimating 121 bytes per record, it's expected that
+ * no more than 3.02MB will be required for cache disk space.
+ */
+ @Provides
+ @PerformanceMetricsLogStorageCacheSize
+ fun provideMetricLogStorageCacheSize(): Int = 25_000
}
diff --git a/domain/src/main/java/org/oppia/android/domain/oppialogger/analytics/ApplicationLifecycleObserver.kt b/domain/src/main/java/org/oppia/android/domain/oppialogger/analytics/ApplicationLifecycleObserver.kt
index e49bf08b3c4..5a9dd411387 100644
--- a/domain/src/main/java/org/oppia/android/domain/oppialogger/analytics/ApplicationLifecycleObserver.kt
+++ b/domain/src/main/java/org/oppia/android/domain/oppialogger/analytics/ApplicationLifecycleObserver.kt
@@ -24,6 +24,7 @@ class ApplicationLifecycleObserver @Inject constructor(
private val learnerAnalyticsLogger: LearnerAnalyticsLogger,
private val profileManagementController: ProfileManagementController,
private val oppiaLogger: OppiaLogger,
+ private val performanceMetricsController: PerformanceMetricsController,
@LearnerAnalyticsInactivityLimitMillis private val inactivityLimitMillis: Long,
@BackgroundDispatcher private val backgroundDispatcher: CoroutineDispatcher
) : ApplicationStartupListener, LifecycleObserver {
@@ -39,6 +40,7 @@ class ApplicationLifecycleObserver @Inject constructor(
/** Occurs when application comes to foreground. */
@OnLifecycleEvent(Lifecycle.Event.ON_START)
fun onAppInForeground() {
+ performanceMetricsController.setAppInForeground()
val timeDifferenceMs = oppiaClock.getCurrentTimeMs() - firstTimestamp
if (timeDifferenceMs > inactivityLimitMillis) {
loggingIdentifierController.updateSessionId()
@@ -49,6 +51,7 @@ class ApplicationLifecycleObserver @Inject constructor(
/** Occurs when application goes to background. */
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
fun onAppInBackground() {
+ performanceMetricsController.setAppInBackground()
firstTimestamp = oppiaClock.getCurrentTimeMs()
logAppLifecycleEventInBackground(learnerAnalyticsLogger::logAppInBackground)
}
diff --git a/domain/src/main/java/org/oppia/android/domain/oppialogger/analytics/BUILD.bazel b/domain/src/main/java/org/oppia/android/domain/oppialogger/analytics/BUILD.bazel
index 5616ff68418..f1f3915e280 100644
--- a/domain/src/main/java/org/oppia/android/domain/oppialogger/analytics/BUILD.bazel
+++ b/domain/src/main/java/org/oppia/android/domain/oppialogger/analytics/BUILD.bazel
@@ -24,6 +24,26 @@ kt_android_library(
],
)
+kt_android_library(
+ name = "performance_metrics_controller",
+ srcs = [
+ "PerformanceMetricsController.kt",
+ ],
+ visibility = ["//domain/src/main/java/org/oppia/android/domain/oppialogger:__subpackages__"],
+ deps = [
+ ":dagger",
+ "//data/src/main/java/org/oppia/android/data/persistence:cache_store",
+ "//domain/src/main/java/org/oppia/android/domain/oppialogger:prod_module",
+ "//model/src/main/proto:performance_metrics_event_logger_java_proto_lite",
+ "//utility/src/main/java/org/oppia/android/util/data:data_provider",
+ "//utility/src/main/java/org/oppia/android/util/logging:console_logger",
+ "//utility/src/main/java/org/oppia/android/util/logging:exception_logger",
+ "//utility/src/main/java/org/oppia/android/util/logging/performancemetrics:performance_metrics_assessor",
+ "//utility/src/main/java/org/oppia/android/util/logging/performancemetrics:performance_metrics_event_logger",
+ "//utility/src/main/java/org/oppia/android/util/networking:network_connection_util",
+ ],
+)
+
kt_android_library(
name = "learner_analytics_logger",
srcs = [
@@ -39,6 +59,37 @@ kt_android_library(
],
)
+kt_android_library(
+ name = "performance_metrics_logger",
+ srcs = [
+ "PerformanceMetricsLogger.kt",
+ ],
+ visibility = ["//:oppia_api_visibility"],
+ deps = [
+ ":dagger",
+ ":performance_metrics_controller",
+ "//domain/src/main/java/org/oppia/android/domain/oppialogger:logging_identifier_controller",
+ "//domain/src/main/java/org/oppia/android/domain/oppialogger:oppia_logger",
+ "//domain/src/main/java/org/oppia/android/domain/oppialogger:startup_listener",
+ "//model/src/main/proto:performance_metrics_event_logger_java_proto_lite",
+ "//utility/src/main/java/org/oppia/android/util/logging/performancemetrics:performance_metrics_assessor",
+ "//utility/src/main/java/org/oppia/android/util/logging/performancemetrics:performance_metrics_event_logger",
+ ],
+)
+
+kt_android_library(
+ name = "performance_metrics_logger_module",
+ srcs = [
+ "PerformanceMetricsLoggerModule.kt",
+ ],
+ visibility = ["//:oppia_prod_module_visibility"],
+ deps = [
+ ":dagger",
+ ":performance_metrics_logger",
+ "//domain/src/main/java/org/oppia/android/domain/oppialogger:startup_listener",
+ ],
+)
+
kt_android_library(
name = "learner_analytics_inactivity_limit_millis",
srcs = [
@@ -59,6 +110,7 @@ kt_android_library(
deps = [
":dagger",
":learner_analytics_inactivity_limit_millis",
+ ":performance_metrics_controller",
"//domain/src/main/java/org/oppia/android/domain/oppialogger:logging_identifier_controller",
"//domain/src/main/java/org/oppia/android/domain/oppialogger:startup_listener",
"//domain/src/main/java/org/oppia/android/domain/profile:profile_management_controller",
diff --git a/domain/src/main/java/org/oppia/android/domain/oppialogger/analytics/PerformanceMetricsController.kt b/domain/src/main/java/org/oppia/android/domain/oppialogger/analytics/PerformanceMetricsController.kt
new file mode 100644
index 00000000000..ee8cca7b6c5
--- /dev/null
+++ b/domain/src/main/java/org/oppia/android/domain/oppialogger/analytics/PerformanceMetricsController.kt
@@ -0,0 +1,193 @@
+package org.oppia.android.domain.oppialogger.analytics
+
+import org.oppia.android.app.model.OppiaMetricLog
+import org.oppia.android.app.model.OppiaMetricLog.Priority
+import org.oppia.android.app.model.OppiaMetricLogs
+import org.oppia.android.data.persistence.PersistentCacheStore
+import org.oppia.android.domain.oppialogger.PerformanceMetricsLogStorageCacheSize
+import org.oppia.android.util.data.DataProvider
+import org.oppia.android.util.logging.ConsoleLogger
+import org.oppia.android.util.logging.ExceptionLogger
+import org.oppia.android.util.logging.performancemetrics.PerformanceMetricsAssessor
+import org.oppia.android.util.logging.performancemetrics.PerformanceMetricsEventLogger
+import org.oppia.android.util.networking.NetworkConnectionUtil
+import java.lang.IllegalStateException
+import javax.inject.Inject
+import javax.inject.Singleton
+
+/**
+ * Controller for handling performance metrics event logging.
+ *
+ * Callers should not use this class directly; instead, they should use ``PerformanceMetricsLogger``
+ * which provides convenience log methods.
+ */
+@Singleton
+class PerformanceMetricsController @Inject constructor(
+ private val performanceMetricsAssessor: PerformanceMetricsAssessor,
+ private val consoleLogger: ConsoleLogger,
+ private val networkConnectionUtil: NetworkConnectionUtil,
+ private val exceptionLogger: ExceptionLogger,
+ private val performanceMetricsEventLogger: PerformanceMetricsEventLogger,
+ cacheStoreFactory: PersistentCacheStore.Factory,
+ @PerformanceMetricsLogStorageCacheSize private val metricLogStorageCacheSize: Int
+) {
+
+ private var isAppInForeground: Boolean = false
+
+ private val metricLogStore =
+ cacheStoreFactory.create("metric_logs", OppiaMetricLogs.getDefaultInstance())
+
+ /**
+ * Logs a performance metric occurring at [currentScreen] defined by [loggableMetric]
+ * corresponding to a time [timestamp].
+ *
+ * This will schedule a background upload of the event if there's internet connectivity, otherwise
+ * it will cache the event for a later upload.
+ */
+ fun logPerformanceMetricsEvent(
+ timestamp: Long,
+ currentScreen: OppiaMetricLog.CurrentScreen,
+ loggableMetric: OppiaMetricLog.LoggableMetric,
+ priority: Priority
+ ) {
+ uploadOrCacheLog(createMetricLog(timestamp, priority, currentScreen, loggableMetric))
+ }
+
+ /** Either uploads or caches [oppiaMetricLog] depending on current internet connectivity. */
+ private fun uploadOrCacheLog(oppiaMetricLog: OppiaMetricLog) {
+ when (networkConnectionUtil.getCurrentConnectionStatus()) {
+ NetworkConnectionUtil.ProdConnectionStatus.NONE -> cacheMetricLog(oppiaMetricLog)
+ else -> performanceMetricsEventLogger.logPerformanceMetric(oppiaMetricLog)
+ }
+ }
+
+ /**
+ * Adds a metric log to the storage.
+ *
+ * At first, it checks if the size of the store isn't exceeding [metricLogStorageCacheSize]. If
+ * the limit is exceeded then the least recent event is removed from the [metricLogStore]. After
+ * this, the [oppiaMetricLog] is added to the store.
+ */
+ private fun cacheMetricLog(oppiaMetricLog: OppiaMetricLog) {
+ metricLogStore.storeDataAsync(updateInMemoryCache = true) { oppiaMetricLogs ->
+ val storeSize = oppiaMetricLogs.oppiaMetricLogList.size
+ if (storeSize + 1 > metricLogStorageCacheSize) {
+ val eventLogRemovalIndex = getLeastRecentMetricLogIndex(oppiaMetricLogs)
+ if (eventLogRemovalIndex != null) {
+ return@storeDataAsync oppiaMetricLogs.toBuilder()
+ .removeOppiaMetricLog(eventLogRemovalIndex)
+ .addOppiaMetricLog(oppiaMetricLog)
+ .build()
+ } else {
+ // TODO(#1433): Refactoring for logging exceptions to both console and exception loggers.
+ val exception =
+ IllegalStateException(
+ "Least Recent Event index absent -- MetricLogStorageCacheSize is 0"
+ )
+ consoleLogger.e(
+ "PerformanceMetricsController",
+ "Failure while caching metric log.",
+ exception
+ )
+ exceptionLogger.logException(exception)
+ }
+ }
+ return@storeDataAsync oppiaMetricLogs.toBuilder().addOppiaMetricLog(oppiaMetricLog).build()
+ }.invokeOnCompletion {
+ it?.let { consoleLogger.e("PerformanceMetricsController", "Failed to store metric log.", it) }
+ }
+ }
+
+ /** Returns a metric log containing relevant data for metric log reporting. */
+ private fun createMetricLog(
+ timestamp: Long,
+ priority: Priority,
+ currentScreen: OppiaMetricLog.CurrentScreen,
+ loggableMetric: OppiaMetricLog.LoggableMetric
+ ): OppiaMetricLog {
+ return OppiaMetricLog.newBuilder().apply {
+ this.timestampMillis = timestamp
+ this.priority = priority
+ this.currentScreen = currentScreen
+ this.loggableMetric = loggableMetric
+ this.isAppInForeground = this@PerformanceMetricsController.isAppInForeground
+ this.storageTier = performanceMetricsAssessor.getDeviceStorageTier()
+ this.memoryTier = performanceMetricsAssessor.getDeviceMemoryTier()
+ }.build()
+ }
+
+ /**
+ * Returns the index of the least recent event from the existing store on the basis of recency and
+ * priority.
+ *
+ * At first, it checks the index of the least recent event which has LOW priority. If that
+ * returns null, then it checks the index of the least recent event which has MEDIUM priority. If
+ * that returns null, then it checks the index of the least recent event regardless of the
+ * priority is returned.
+ */
+ private fun getLeastRecentMetricLogIndex(oppiaMetricLogs: OppiaMetricLogs): Int? =
+ oppiaMetricLogs.oppiaMetricLogList.withIndex()
+ .filter { it.value.priority == Priority.LOW_PRIORITY }
+ .minByOrNull { it.value.timestampMillis }?.index
+ ?: getLeastRecentMediumPriorityEventIndex(oppiaMetricLogs)
+
+ /**
+ * Returns the index of the least recent event from the existing store on the basis of recency and
+ * priority.
+ *
+ * At first, it checks the index of the least recent event which has MEDIUM priority. If that
+ * returns null, then it checks the index of the least recent event regardless of the
+ * priority is returned.
+ */
+ private fun getLeastRecentMediumPriorityEventIndex(oppiaMetricLogs: OppiaMetricLogs): Int? =
+ oppiaMetricLogs.oppiaMetricLogList.withIndex()
+ .filter { it.value.priority == Priority.MEDIUM_PRIORITY }
+ .minByOrNull { it.value.timestampMillis }?.index
+ ?: getLeastRecentGeneralEventIndex(oppiaMetricLogs)
+
+ /** Returns the index of the least recent event regardless of their priority. */
+ private fun getLeastRecentGeneralEventIndex(oppiaMetricLogs: OppiaMetricLogs): Int? =
+ oppiaMetricLogs.oppiaMetricLogList.withIndex()
+ .minByOrNull { it.value.timestampMillis }?.index
+
+ /** Returns a data provider for log reports that have been recorded for upload. */
+ fun getMetricLogStore(): DataProvider = metricLogStore
+
+ /**
+ * Returns a list of metric log reports that have been recorded for upload.
+ *
+ * As we are using the await call on the deferred output of readDataAsync, the failure case would
+ * be caught and it'll throw an error.
+ */
+ suspend fun getMetricLogStoreList(): List {
+ return metricLogStore.readDataAsync().await().oppiaMetricLogList
+ }
+
+ /** Removes the first metric log report that had been recorded for upload. */
+ fun removeFirstMetricLogFromStore() {
+ metricLogStore.storeDataAsync(updateInMemoryCache = true) { oppiaEventLogs ->
+ return@storeDataAsync oppiaEventLogs.toBuilder().removeOppiaMetricLog(0).build()
+ }.invokeOnCompletion {
+ it?.let {
+ consoleLogger.e(
+ "PerformanceMetricsController",
+ "Failed to remove metric log.",
+ it
+ )
+ }
+ }
+ }
+
+ /** Sets [isAppInForeground] to true when application is in or returns to foreground. */
+ fun setAppInForeground() {
+ this.isAppInForeground = true
+ }
+
+ /** Sets [isAppInForeground] to false when application goes to background. */
+ fun setAppInBackground() {
+ this.isAppInForeground = false
+ }
+
+ /** Returns a boolean value indicating whether the application is currently in foreground or not. */
+ fun getIsAppInForeground() = this.isAppInForeground
+}
diff --git a/domain/src/main/java/org/oppia/android/domain/oppialogger/analytics/PerformanceMetricsLogger.kt b/domain/src/main/java/org/oppia/android/domain/oppialogger/analytics/PerformanceMetricsLogger.kt
new file mode 100644
index 00000000000..48a6bda8ad1
--- /dev/null
+++ b/domain/src/main/java/org/oppia/android/domain/oppialogger/analytics/PerformanceMetricsLogger.kt
@@ -0,0 +1,305 @@
+package org.oppia.android.domain.oppialogger.analytics
+
+import org.oppia.android.app.model.OppiaMetricLog
+import org.oppia.android.domain.oppialogger.ApplicationStartupListener
+import org.oppia.android.util.logging.performancemetrics.PerformanceMetricsAssessor
+import org.oppia.android.util.system.OppiaClock
+import javax.inject.Inject
+import javax.inject.Singleton
+
+/**
+ * Convenience logger for performance metrics related analytics events.
+ *
+ * This logger is meant primarily to be used directly in places where a certain performance metric
+ * has to be logged.
+ */
+@Singleton
+class PerformanceMetricsLogger @Inject constructor(
+ private val performanceMetricsController: PerformanceMetricsController,
+ private val performanceMetricsAssessor: PerformanceMetricsAssessor,
+ private val oppiaClock: OppiaClock
+) : ApplicationStartupListener {
+
+ /**
+ * Timestamp indicating the time of application start-up. It will be used to calculate the
+ * cold-startup latency of the application.
+ *
+ * We're using a large Long value such that the time difference based on any timestamp will be
+ * negative and thus ignored until the app records initial time during [onCreate].
+ */
+ private var firstTimestamp: Long = Long.MAX_VALUE
+
+ override fun onCreate() {
+ firstTimestamp = oppiaClock.getCurrentTimeMs()
+ }
+
+ /**
+ * Logs the apk size of the application as a performance metric for the current state of the app.
+ * It must be noted that the value of this metric won't change across calls during the same
+ * application instance.
+ *
+ * @param currentScreen denotes the application screen at which this metric has been logged
+ */
+ fun logApkSize(currentScreen: OppiaMetricLog.CurrentScreen) {
+ performanceMetricsController.logLowPriorityMetricEvent(
+ oppiaClock.getCurrentTimeMs(),
+ currentScreen,
+ createApkSizeLoggableMetric(performanceMetricsAssessor.getApkSize())
+ )
+ }
+
+ /**
+ * Logs the storage usage of the application as a performance metric for the current state of the
+ * app. It must be noted that the value of this metric will change across calls during the same
+ * application instance.
+ *
+ * @param currentScreen denotes the application screen at which this metric has been logged
+ */
+ fun logStorageUsage(currentScreen: OppiaMetricLog.CurrentScreen) {
+ performanceMetricsController.logLowPriorityMetricEvent(
+ oppiaClock.getCurrentTimeMs(),
+ currentScreen,
+ createStorageUsageLoggableMetric(performanceMetricsAssessor.getUsedStorage())
+ )
+ }
+
+ /**
+ * Logs the startup latency of the application as a performance metric for the current state of
+ * the app. This metric should only be logged when the application starts.
+ *
+ * @param currentScreen denotes the application screen at which this metric has been logged
+ */
+ fun logStartupLatency(currentScreen: OppiaMetricLog.CurrentScreen) {
+ val startupLatency = oppiaClock.getCurrentTimeMs() - firstTimestamp
+ if (startupLatency >= 0) {
+ performanceMetricsController.logLowPriorityMetricEvent(
+ oppiaClock.getCurrentTimeMs(),
+ currentScreen,
+ createStartupLatencyLoggableMetric(startupLatency)
+ )
+ }
+ }
+
+ /**
+ * Logs the memory usage of the application as a performance metric for the current state of the
+ * app. It must be noted that the value of this metric will change across calls during the same
+ * application instance.
+ *
+ * @param currentScreen denotes the application screen at which this metric has been logged
+ */
+ fun logMemoryUsage(currentScreen: OppiaMetricLog.CurrentScreen) {
+ performanceMetricsController.logMediumPriorityMetricEvent(
+ oppiaClock.getCurrentTimeMs(),
+ currentScreen,
+ createMemoryUsageLoggableMetric(performanceMetricsAssessor.getTotalPssUsed())
+ )
+ }
+
+ /**
+ * Logs the network usage of the application as a performance metric for the current state of the
+ * app. It must be noted that the value of this metric will change across calls during the same
+ * application instance.
+ *
+ * @param currentScreen denotes the application screen at which this metric has been logged
+ */
+ fun logNetworkUsage(currentScreen: OppiaMetricLog.CurrentScreen) {
+ performanceMetricsController.logHighPriorityMetricEvent(
+ oppiaClock.getCurrentTimeMs(),
+ currentScreen,
+ createNetworkUsageLoggableMetric(
+ performanceMetricsAssessor.getTotalReceivedBytes(),
+ performanceMetricsAssessor.getTotalSentBytes()
+ )
+ )
+ }
+
+ /**
+ * Logs the cpu usage of the application as a performance metric for the current state of the
+ * app. It must be noted that the value of this metric will change across calls during the same
+ * application instance.
+ *
+ * @param currentScreen denotes the application screen at which this metric has been logged
+ * @param cpuUsage denotes the current cpu usage of the application
+ */
+ fun logCpuUsage(cpuUsage: Long, currentScreen: OppiaMetricLog.CurrentScreen) {
+ performanceMetricsController.logHighPriorityMetricEvent(
+ oppiaClock.getCurrentTimeMs(),
+ currentScreen,
+ createCpuUsageLoggableMetric(cpuUsage)
+ )
+ }
+
+ internal companion object {
+ /**
+ * Logs a high priority performance metric occurring at [currentScreen] defined by [loggableMetric].
+ *
+ * This will schedule a background upload of the event if there's internet connectivity, otherwise
+ * it will cache the event for a later upload.
+ *
+ * This method should only be used for logging periodic metrics like network and cpu usage of the
+ * application. These metrics are important to log and should be prioritized over metrics logged
+ * via [logMediumPriorityMetricEvent] and [logLowPriorityMetricEvent].
+ */
+ private fun PerformanceMetricsController.logHighPriorityMetricEvent(
+ timestamp: Long,
+ currentScreen: OppiaMetricLog.CurrentScreen,
+ loggableMetric: OppiaMetricLog.LoggableMetric
+ ) {
+ logPerformanceMetricsEvent(
+ timestamp,
+ currentScreen,
+ loggableMetric,
+ OppiaMetricLog.Priority.HIGH_PRIORITY
+ )
+ }
+
+ /**
+ * Logs a medium priority performance metric occurring at [currentScreen] defined by [loggableMetric].
+ *
+ * This will schedule a background upload of the event if there's internet connectivity, otherwise
+ * it will cache the event for a later upload.
+ *
+ * Medium priority metrics may be removed from the event cache if device space is limited, and
+ * there's no connectivity for immediately sending events. These metrics will however be
+ * prioritised over Low priority metrics.
+ *
+ * This method should only be used for logging ui-specific metrics like memory usage of the
+ * application. These metrics are important to log (but not as important as high priority metrics)
+ * and should be prioritized over metrics logged via [logLowPriorityMetricEvent].
+ */
+ private fun PerformanceMetricsController.logMediumPriorityMetricEvent(
+ timestamp: Long,
+ currentScreen: OppiaMetricLog.CurrentScreen,
+ loggableMetric: OppiaMetricLog.LoggableMetric
+ ) {
+ logPerformanceMetricsEvent(
+ timestamp,
+ currentScreen,
+ loggableMetric,
+ OppiaMetricLog.Priority.MEDIUM_PRIORITY
+ )
+ }
+
+ /**
+ * Logs a low priority performance metric occurring at [currentScreen] defined by [loggableMetric]
+ * corresponding to time [timestamp].
+ *
+ * This will schedule a background upload of the event if there's internet connectivity, otherwise
+ * it will cache the event for a later upload.
+ *
+ * Low priority metrics may be removed from the event cache if device space is limited, and
+ * there's no connectivity for immediately sending events.
+ *
+ * This method should only be used for logging metrics that are to be logged at the beginning of
+ * the application like apk size and storage usage.
+ *
+ * Callers should use this for events that are nice to have, but okay to miss occasionally (as
+ * it's unexpected for events to actually be dropped since the app is configured to support a
+ * large number of cached events at one time).
+ */
+ private fun PerformanceMetricsController.logLowPriorityMetricEvent(
+ timestamp: Long,
+ currentScreen: OppiaMetricLog.CurrentScreen,
+ loggableMetric: OppiaMetricLog.LoggableMetric
+ ) {
+ logPerformanceMetricsEvent(
+ timestamp,
+ currentScreen,
+ loggableMetric,
+ OppiaMetricLog.Priority.LOW_PRIORITY
+ )
+ }
+ }
+
+ /**
+ * Returns the loggable metric of the performance metric event log indicating the size of the
+ * apk file of the application.
+ */
+ private fun createApkSizeLoggableMetric(
+ apkSize: Long
+ ): OppiaMetricLog.LoggableMetric {
+ return OppiaMetricLog.LoggableMetric.newBuilder()
+ .setApkSizeMetric(
+ OppiaMetricLog.ApkSizeMetric.newBuilder()
+ .setApkSizeBytes(apkSize)
+ .build()
+ ).build()
+ }
+
+ /**
+ * Returns the loggable metric of the performance metric event log indicating the amount of
+ * storage space used by the application on user's device.
+ */
+ private fun createStorageUsageLoggableMetric(
+ storageUsage: Long
+ ): OppiaMetricLog.LoggableMetric {
+ return OppiaMetricLog.LoggableMetric.newBuilder()
+ .setStorageUsageMetric(
+ OppiaMetricLog.StorageUsageMetric.newBuilder()
+ .setStorageUsageBytes(storageUsage)
+ .build()
+ ).build()
+ }
+
+ /**
+ * Returns the loggable metric of the performance metric event log indicating the number of
+ * milliseconds required to start up the application from a cold start.
+ */
+ private fun createStartupLatencyLoggableMetric(
+ startupLatency: Long
+ ): OppiaMetricLog.LoggableMetric {
+ return OppiaMetricLog.LoggableMetric.newBuilder()
+ .setStartupLatencyMetric(
+ OppiaMetricLog.StartupLatencyMetric.newBuilder()
+ .setStartupLatencyMillis(startupLatency)
+ .build()
+ ).build()
+ }
+
+ /**
+ * Returns the loggable metric of the performance metric event log indicating the the amount of
+ * memory used by the application on user's device.
+ */
+ private fun createMemoryUsageLoggableMetric(
+ totalPssBytes: Long
+ ): OppiaMetricLog.LoggableMetric {
+ return OppiaMetricLog.LoggableMetric.newBuilder()
+ .setMemoryUsageMetric(
+ OppiaMetricLog.MemoryUsageMetric.newBuilder()
+ .setTotalPssBytes(totalPssBytes)
+ .build()
+ ).build()
+ }
+
+ /**
+ * Returns the loggable metric of the performance metric event log indicating the the amount of
+ * CPU used by the application on user's device.
+ */
+ private fun createCpuUsageLoggableMetric(
+ cpuUsage: Long
+ ): OppiaMetricLog.LoggableMetric {
+ return OppiaMetricLog.LoggableMetric.newBuilder()
+ .setCpuUsageMetric(
+ OppiaMetricLog.CpuUsageMetric.newBuilder()
+ .setCpuUsageMetric(cpuUsage)
+ .build()
+ ).build()
+ }
+
+ /**
+ * Returns the loggable metric of the performance metric event log indicating the the amount of
+ * network used by the application on user's device.
+ */
+ private fun createNetworkUsageLoggableMetric(
+ totalBytesReceived: Long,
+ totalBytesSent: Long
+ ): OppiaMetricLog.LoggableMetric {
+ return OppiaMetricLog.LoggableMetric.newBuilder()
+ .setNetworkUsageMetric(
+ OppiaMetricLog.NetworkUsageMetric.newBuilder()
+ .setBytesSent(totalBytesSent)
+ .setBytesReceived(totalBytesReceived)
+ .build()
+ ).build()
+ }
+}
diff --git a/domain/src/main/java/org/oppia/android/domain/oppialogger/analytics/PerformanceMetricsLoggerModule.kt b/domain/src/main/java/org/oppia/android/domain/oppialogger/analytics/PerformanceMetricsLoggerModule.kt
new file mode 100644
index 00000000000..e8cf37beac6
--- /dev/null
+++ b/domain/src/main/java/org/oppia/android/domain/oppialogger/analytics/PerformanceMetricsLoggerModule.kt
@@ -0,0 +1,16 @@
+package org.oppia.android.domain.oppialogger.analytics
+
+import dagger.Binds
+import dagger.Module
+import dagger.multibindings.IntoSet
+import org.oppia.android.domain.oppialogger.ApplicationStartupListener
+
+/** Binds [PerformanceMetricsLogger] as an [ApplicationStartupListener] */
+@Module
+abstract class PerformanceMetricsLoggerModule {
+ @Binds
+ @IntoSet
+ abstract fun providePerformanceMetricsLogger(
+ performanceMetricsLogger: PerformanceMetricsLogger
+ ): ApplicationStartupListener
+}
diff --git a/domain/src/main/java/org/oppia/android/domain/oppialogger/analytics/testing/BUILD.bazel b/domain/src/main/java/org/oppia/android/domain/oppialogger/analytics/testing/BUILD.bazel
new file mode 100644
index 00000000000..a92a8aa723a
--- /dev/null
+++ b/domain/src/main/java/org/oppia/android/domain/oppialogger/analytics/testing/BUILD.bazel
@@ -0,0 +1,22 @@
+"""
+Package for testing utilities for log uploading functionality.
+"""
+
+load("@dagger//:workspace_defs.bzl", "dagger_rules")
+load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_android_library")
+
+kt_android_library(
+ name = "fake_log_scheduler",
+ testonly = True,
+ srcs = [
+ "FakeLogScheduler.kt",
+ ],
+ visibility = ["//:oppia_testing_visibility"],
+ deps = [
+ ":dagger",
+ "//utility/src/main/java/org/oppia/android/util/logging:log_uploader",
+ "//utility/src/main/java/org/oppia/android/util/logging:metric_log_scheduler",
+ ],
+)
+
+dagger_rules()
diff --git a/domain/src/main/java/org/oppia/android/domain/oppialogger/analytics/testing/FakeLogScheduler.kt b/domain/src/main/java/org/oppia/android/domain/oppialogger/analytics/testing/FakeLogScheduler.kt
new file mode 100644
index 00000000000..12973e595fa
--- /dev/null
+++ b/domain/src/main/java/org/oppia/android/domain/oppialogger/analytics/testing/FakeLogScheduler.kt
@@ -0,0 +1,58 @@
+package org.oppia.android.domain.oppialogger.analytics.testing
+
+import androidx.work.PeriodicWorkRequest
+import androidx.work.WorkManager
+import org.oppia.android.util.logging.MetricLogScheduler
+import java.util.UUID
+import javax.inject.Inject
+import javax.inject.Singleton
+
+/** A test specific fake for the log uploader. */
+@Singleton
+class FakeLogScheduler @Inject constructor() : MetricLogScheduler {
+ private val schedulingStorageUsageMetricLoggingRequestIdList = mutableListOf()
+ private val schedulingPeriodicUiMetricLoggingRequestIdList = mutableListOf()
+ private val schedulingPeriodicBackgroundMetricsLoggingRequestIdList = mutableListOf()
+
+ override fun enqueueWorkRequestForPeriodicBackgroundMetrics(
+ workManager: WorkManager,
+ workRequest: PeriodicWorkRequest
+ ) {
+ schedulingPeriodicBackgroundMetricsLoggingRequestIdList.add(workRequest.id)
+ }
+
+ override fun enqueueWorkRequestForStorageUsage(
+ workManager: WorkManager,
+ workRequest: PeriodicWorkRequest
+ ) {
+ schedulingStorageUsageMetricLoggingRequestIdList.add(workRequest.id)
+ }
+
+ override fun enqueueWorkRequestForPeriodicUiMetrics(
+ workManager: WorkManager,
+ workRequest: PeriodicWorkRequest
+ ) {
+ schedulingPeriodicUiMetricLoggingRequestIdList.add(workRequest.id)
+ }
+
+ /**
+ * Returns the most recent work request id that's stored in the
+ * [schedulingStorageUsageMetricLoggingRequestIdList].
+ */
+ fun getMostRecentStorageUsageMetricLoggingRequestId() =
+ schedulingStorageUsageMetricLoggingRequestIdList.last()
+
+ /**
+ * Returns the most recent work request id that's stored in the
+ * [schedulingPeriodicUiMetricLoggingRequestIdList].
+ */
+ fun getMostRecentPeriodicUiMetricLoggingRequestId() =
+ schedulingPeriodicUiMetricLoggingRequestIdList.last()
+
+ /**
+ * Returns the most recent work request id that's stored in the
+ * [schedulingPeriodicBackgroundMetricsLoggingRequestIdList].
+ */
+ fun getMostRecentPeriodicBackgroundMetricLoggingRequestId() =
+ schedulingPeriodicBackgroundMetricsLoggingRequestIdList.last()
+}
diff --git a/domain/src/main/java/org/oppia/android/domain/oppialogger/logscheduler/BUILD.bazel b/domain/src/main/java/org/oppia/android/domain/oppialogger/logscheduler/BUILD.bazel
new file mode 100644
index 00000000000..66c38ba23a2
--- /dev/null
+++ b/domain/src/main/java/org/oppia/android/domain/oppialogger/logscheduler/BUILD.bazel
@@ -0,0 +1,61 @@
+"""
+Library for providing log scheduling functionality to the Oppia android app.
+"""
+
+load("@dagger//:workspace_defs.bzl", "dagger_rules")
+load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_android_library")
+
+kt_android_library(
+ name = "performance_metrics_log_scheduler",
+ srcs = [
+ "PerformanceMetricsLogScheduler.kt",
+ ],
+ deps = [
+ ":metric_log_scheduling_worker",
+ "//third_party:androidx_work_work-runtime-ktx",
+ "//utility/src/main/java/org/oppia/android/util/logging:metric_log_scheduler",
+ ],
+)
+
+kt_android_library(
+ name = "metric_log_scheduling_worker",
+ srcs = [
+ "MetricLogSchedulingWorker.kt",
+ ],
+ visibility = ["//:oppia_api_visibility"],
+ deps = [
+ "//domain/src/main/java/org/oppia/android/domain/oppialogger/exceptions:controller",
+ "//domain/src/main/java/org/oppia/android/domain/util:extensions",
+ "//third_party:androidx_work_work-runtime-ktx",
+ "//utility/src/main/java/org/oppia/android/util/logging:console_logger",
+ "//utility/src/main/java/org/oppia/android/util/threading:annotations",
+ ],
+)
+
+kt_android_library(
+ name = "metric_log_scheduling_worker_factory",
+ srcs = [
+ "MetricLogSchedulingWorkerFactory.kt",
+ ],
+ visibility = ["//domain:__pkg__"],
+ deps = [
+ ":metric_log_scheduling_worker",
+ "//third_party:androidx_work_work-runtime-ktx",
+ ],
+)
+
+kt_android_library(
+ name = "metric_log_scheduler_module",
+ srcs = [
+ "MetricLogSchedulerModule.kt",
+ ],
+ visibility = ["//:oppia_prod_module_visibility"],
+ deps = [
+ ":dagger",
+ ":performance_metrics_log_scheduler",
+ "//domain/src/main/java/org/oppia/android/domain/oppialogger:startup_listener",
+ "//utility/src/main/java/org/oppia/android/util/logging:metric_log_scheduler",
+ ],
+)
+
+dagger_rules()
diff --git a/domain/src/main/java/org/oppia/android/domain/oppialogger/logscheduler/MetricLogSchedulerModule.kt b/domain/src/main/java/org/oppia/android/domain/oppialogger/logscheduler/MetricLogSchedulerModule.kt
new file mode 100644
index 00000000000..7594d6460ec
--- /dev/null
+++ b/domain/src/main/java/org/oppia/android/domain/oppialogger/logscheduler/MetricLogSchedulerModule.kt
@@ -0,0 +1,14 @@
+package org.oppia.android.domain.oppialogger.logscheduler
+
+import dagger.Binds
+import dagger.Module
+import org.oppia.android.util.logging.MetricLogScheduler
+
+/** Provides metric log scheduler related dependencies. */
+@Module
+abstract class MetricLogSchedulerModule {
+ @Binds
+ abstract fun provideMetricLogScheduler(
+ performanceMetricLogScheduler: PerformanceMetricsLogScheduler
+ ): MetricLogScheduler
+}
diff --git a/domain/src/main/java/org/oppia/android/domain/oppialogger/logscheduler/MetricLogSchedulingWorker.kt b/domain/src/main/java/org/oppia/android/domain/oppialogger/logscheduler/MetricLogSchedulingWorker.kt
new file mode 100644
index 00000000000..8767b2206a1
--- /dev/null
+++ b/domain/src/main/java/org/oppia/android/domain/oppialogger/logscheduler/MetricLogSchedulingWorker.kt
@@ -0,0 +1,125 @@
+package org.oppia.android.domain.oppialogger.logscheduler
+
+import android.content.Context
+import androidx.work.ListenableWorker
+import androidx.work.WorkerParameters
+import com.google.common.util.concurrent.ListenableFuture
+import com.google.common.util.concurrent.SettableFuture
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.async
+import org.oppia.android.domain.util.getStringFromData
+import org.oppia.android.util.logging.ConsoleLogger
+import org.oppia.android.util.threading.BackgroundDispatcher
+import javax.inject.Inject
+
+/**
+ * Worker class that generates metric log reports regarding the performance of the application
+ * and then stores it in in device cache.
+ */
+class MetricLogSchedulingWorker private constructor(
+ context: Context,
+ params: WorkerParameters,
+ private val consoleLogger: ConsoleLogger,
+ @BackgroundDispatcher private val backgroundDispatcher: CoroutineDispatcher
+) : ListenableWorker(context, params) {
+
+ companion object {
+ private const val TAG = "MetricLogSchedulingWorker"
+ /**
+ * The key for an input key-value pair for [MetricLogSchedulingWorker] where one of
+ * [PERIODIC_BACKGROUND_METRIC_WORKER], [PERIODIC_UI_METRIC_WORKER] and [STORAGE_USAGE_WORKER] indicates what
+ * kind of work to perform.
+ */
+ const val WORKER_CASE_KEY = "metric_log_scheduling_worker_case_key"
+ /**
+ * Indicates to [MetricLogSchedulingWorker] that it should schedule logging for periodic
+ * performance metrics.
+ */
+ const val PERIODIC_BACKGROUND_METRIC_WORKER = "periodic_background_metric_worker"
+ /**
+ * Indicates to [MetricLogSchedulingWorker] that it should schedule logging for storage usage
+ * performance metrics.
+ */
+ const val STORAGE_USAGE_WORKER = "storage_usage_worker"
+ /**
+ * Indicates to [MetricLogSchedulingWorker] that it should schedule logging for ui-related
+ * memory usage performance metrics.
+ */
+ const val PERIODIC_UI_METRIC_WORKER = "periodic_ui_metric_worker"
+ }
+
+ override fun startWork(): ListenableFuture {
+ val backgroundScope = CoroutineScope(backgroundDispatcher)
+ val result = backgroundScope.async {
+ when (inputData.getStringFromData(WORKER_CASE_KEY)) {
+ PERIODIC_BACKGROUND_METRIC_WORKER -> schedulePeriodicBackgroundMetricLogging()
+ STORAGE_USAGE_WORKER -> scheduleStorageUsageMetricLogging()
+ PERIODIC_UI_METRIC_WORKER -> schedulePeriodicUiMetricLogging()
+ else -> Result.failure()
+ }
+ }
+
+ val future = SettableFuture.create()
+ result.invokeOnCompletion { failure ->
+ if (failure != null) {
+ future.setException(failure)
+ } else {
+ future.set(result.getCompleted())
+ }
+ }
+ // TODO(#3715): Add withTimeout() to avoid potential hanging.
+ return future
+ }
+
+ private fun schedulePeriodicBackgroundMetricLogging(): Result {
+ return try {
+ // TODO(#4340): Add functionality to log cpu and network usage performance metrics.
+ Result.success()
+ } catch (e: Exception) {
+ consoleLogger.e(TAG, e.toString(), e)
+ return Result.failure()
+ }
+ }
+
+ private fun scheduleStorageUsageMetricLogging(): Result {
+ return try {
+ // TODO(#4340): Add functionality to log storage usage performance metrics.
+ Result.success()
+ } catch (e: Exception) {
+ consoleLogger.e(TAG, e.toString(), e)
+ return Result.failure()
+ }
+ }
+
+ private fun schedulePeriodicUiMetricLogging(): Result {
+ return try {
+ // TODO(#4340): Add functionality to log memory usage performance metrics.
+ Result.success()
+ } catch (e: Exception) {
+ consoleLogger.e(TAG, e.toString(), e)
+ return Result.failure()
+ }
+ }
+
+ /** Creates an instance of [MetricLogSchedulingWorker] by properly injecting dependencies. */
+ class Factory @Inject constructor(
+ private val consoleLogger: ConsoleLogger,
+ @BackgroundDispatcher private val backgroundDispatcher: CoroutineDispatcher
+ ) {
+ /**
+ * Returns a new [MetricLogSchedulingWorker].
+ *
+ * This [MetricLogSchedulingWorker] implements the [ListenableWorker] for facilitating metric
+ * log scheduling.
+ */
+ fun create(context: Context, params: WorkerParameters): ListenableWorker {
+ return MetricLogSchedulingWorker(
+ context,
+ params,
+ consoleLogger,
+ backgroundDispatcher
+ )
+ }
+ }
+}
diff --git a/domain/src/main/java/org/oppia/android/domain/oppialogger/logscheduler/MetricLogSchedulingWorkerFactory.kt b/domain/src/main/java/org/oppia/android/domain/oppialogger/logscheduler/MetricLogSchedulingWorkerFactory.kt
new file mode 100644
index 00000000000..c8dae69942e
--- /dev/null
+++ b/domain/src/main/java/org/oppia/android/domain/oppialogger/logscheduler/MetricLogSchedulingWorkerFactory.kt
@@ -0,0 +1,22 @@
+package org.oppia.android.domain.oppialogger.logscheduler
+
+import android.content.Context
+import androidx.work.ListenableWorker
+import androidx.work.WorkerFactory
+import androidx.work.WorkerParameters
+import javax.inject.Inject
+
+/** Custom [WorkerFactory] for the [MetricLogSchedulingWorker]. */
+class MetricLogSchedulingWorkerFactory @Inject constructor(
+ private val workerFactory: MetricLogSchedulingWorker.Factory
+) : WorkerFactory() {
+
+ /** Returns a new [MetricLogSchedulingWorker] for the given context and parameters. */
+ override fun createWorker(
+ appContext: Context,
+ workerClassName: String,
+ workerParameters: WorkerParameters
+ ): ListenableWorker {
+ return workerFactory.create(appContext, workerParameters)
+ }
+}
diff --git a/domain/src/main/java/org/oppia/android/domain/oppialogger/logscheduler/PerformanceMetricsLogScheduler.kt b/domain/src/main/java/org/oppia/android/domain/oppialogger/logscheduler/PerformanceMetricsLogScheduler.kt
new file mode 100644
index 00000000000..de82dc42dfa
--- /dev/null
+++ b/domain/src/main/java/org/oppia/android/domain/oppialogger/logscheduler/PerformanceMetricsLogScheduler.kt
@@ -0,0 +1,50 @@
+package org.oppia.android.domain.oppialogger.logscheduler
+
+import androidx.work.ExistingPeriodicWorkPolicy
+import androidx.work.PeriodicWorkRequest
+import androidx.work.WorkManager
+import org.oppia.android.util.logging.MetricLogScheduler
+import javax.inject.Inject
+
+private const val OPPIA_PERIODIC_METRIC_WORK = "OPPIA_PERIODIC_METRIC_WORK"
+private const val OPPIA_STORAGE_USAGE_WORK = "OPPIA_STORAGE_USAGE_WORK"
+private const val OPPIA_MEMORY_USAGE_WORK = "OPPIA_MEMORY_USAGE_WORK"
+
+/**
+ * Enqueues work requests for generating metric log reports for gaining an insight regarding into
+ * the performance of the application.
+ */
+class PerformanceMetricsLogScheduler @Inject constructor() : MetricLogScheduler {
+ override fun enqueueWorkRequestForPeriodicBackgroundMetrics(
+ workManager: WorkManager,
+ workRequest: PeriodicWorkRequest
+ ) {
+ workManager.enqueueUniquePeriodicWork(
+ OPPIA_PERIODIC_METRIC_WORK,
+ ExistingPeriodicWorkPolicy.KEEP,
+ workRequest
+ )
+ }
+
+ override fun enqueueWorkRequestForStorageUsage(
+ workManager: WorkManager,
+ workRequest: PeriodicWorkRequest
+ ) {
+ workManager.enqueueUniquePeriodicWork(
+ OPPIA_STORAGE_USAGE_WORK,
+ ExistingPeriodicWorkPolicy.KEEP,
+ workRequest
+ )
+ }
+
+ override fun enqueueWorkRequestForPeriodicUiMetrics(
+ workManager: WorkManager,
+ workRequest: PeriodicWorkRequest
+ ) {
+ workManager.enqueueUniquePeriodicWork(
+ OPPIA_MEMORY_USAGE_WORK,
+ ExistingPeriodicWorkPolicy.KEEP,
+ workRequest
+ )
+ }
+}
diff --git a/domain/src/main/java/org/oppia/android/domain/oppialogger/loguploader/BUILD.bazel b/domain/src/main/java/org/oppia/android/domain/oppialogger/loguploader/BUILD.bazel
index dceb88ec499..5b8f53e4f17 100644
--- a/domain/src/main/java/org/oppia/android/domain/oppialogger/loguploader/BUILD.bazel
+++ b/domain/src/main/java/org/oppia/android/domain/oppialogger/loguploader/BUILD.bazel
@@ -8,13 +8,15 @@ load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_android_library")
kt_android_library(
name = "initializer",
srcs = [
- "LogUploadWorkManagerInitializer.kt",
+ "LogReportWorkManagerInitializer.kt",
],
deps = [
":worker",
"//domain/src/main/java/org/oppia/android/domain/oppialogger:startup_listener",
+ "//domain/src/main/java/org/oppia/android/domain/oppialogger/logscheduler:metric_log_scheduling_worker",
"//third_party:androidx_work_work-runtime-ktx",
"//utility/src/main/java/org/oppia/android/util/logging:log_uploader",
+ "//utility/src/main/java/org/oppia/android/util/logging:metric_log_scheduler",
],
)
@@ -50,7 +52,7 @@ kt_android_library(
kt_android_library(
name = "worker_module",
srcs = [
- "LogUploadWorkerModule.kt",
+ "LogReportWorkerModule.kt",
],
visibility = ["//:oppia_prod_module_visibility"],
deps = [
diff --git a/domain/src/main/java/org/oppia/android/domain/oppialogger/loguploader/LogReportWorkManagerInitializer.kt b/domain/src/main/java/org/oppia/android/domain/oppialogger/loguploader/LogReportWorkManagerInitializer.kt
new file mode 100644
index 00000000000..3bab2316a2b
--- /dev/null
+++ b/domain/src/main/java/org/oppia/android/domain/oppialogger/loguploader/LogReportWorkManagerInitializer.kt
@@ -0,0 +1,195 @@
+package org.oppia.android.domain.oppialogger.loguploader
+
+import android.content.Context
+import androidx.work.Constraints
+import androidx.work.Data
+import androidx.work.NetworkType
+import androidx.work.PeriodicWorkRequest
+import androidx.work.WorkManager
+import org.oppia.android.domain.oppialogger.ApplicationStartupListener
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulingWorker
+import org.oppia.android.util.logging.LogUploader
+import org.oppia.android.util.logging.MetricLogScheduler
+import org.oppia.android.util.platformparameter.PerformanceMetricsCollectionHighFrequencyTimeIntervalInMinutes
+import org.oppia.android.util.platformparameter.PerformanceMetricsCollectionLowFrequencyTimeIntervalInMinutes
+import org.oppia.android.util.platformparameter.PlatformParameterValue
+import java.util.UUID
+import java.util.concurrent.TimeUnit
+import javax.inject.Inject
+
+/**
+ * Enqueues unique periodic work requests for uploading events and exceptions to the remote service
+ * on application creation.
+ */
+class LogReportWorkManagerInitializer @Inject constructor(
+ private val context: Context,
+ private val logUploader: LogUploader,
+ private val metricLogScheduler: MetricLogScheduler,
+ @PerformanceMetricsCollectionHighFrequencyTimeIntervalInMinutes
+ performanceMetricsCollectionHighFrequencyTimeInterval: PlatformParameterValue,
+ @PerformanceMetricsCollectionLowFrequencyTimeIntervalInMinutes
+ performanceMetricCollectionLowFrequencyTimeInterval: PlatformParameterValue
+) : ApplicationStartupListener {
+
+ private val logReportWorkerConstraints = Constraints.Builder()
+ .setRequiredNetworkType(NetworkType.CONNECTED)
+ .setRequiresBatteryNotLow(true)
+ .build()
+
+ private val workerCaseForUploadingEvents: Data = Data.Builder()
+ .putString(
+ LogUploadWorker.WORKER_CASE_KEY,
+ LogUploadWorker.EVENT_WORKER
+ )
+ .build()
+
+ private val workerCaseForUploadingExceptions: Data = Data.Builder()
+ .putString(
+ LogUploadWorker.WORKER_CASE_KEY,
+ LogUploadWorker.EXCEPTION_WORKER
+ )
+ .build()
+
+ private val workerCaseForSchedulingPeriodicBackgroundMetricLogs: Data = Data.Builder()
+ .putString(
+ MetricLogSchedulingWorker.WORKER_CASE_KEY,
+ MetricLogSchedulingWorker.PERIODIC_BACKGROUND_METRIC_WORKER
+ )
+ .build()
+
+ private val workerCaseForSchedulingStorageUsageMetricLogs: Data = Data.Builder()
+ .putString(
+ MetricLogSchedulingWorker.WORKER_CASE_KEY,
+ MetricLogSchedulingWorker.STORAGE_USAGE_WORKER
+ )
+ .build()
+
+ private val workerCaseForSchedulingPeriodicUiMetricLogs: Data = Data.Builder()
+ .putString(
+ MetricLogSchedulingWorker.WORKER_CASE_KEY,
+ MetricLogSchedulingWorker.PERIODIC_UI_METRIC_WORKER
+ )
+ .build()
+
+ private val workRequestForUploadingEvents: PeriodicWorkRequest = PeriodicWorkRequest
+ .Builder(LogUploadWorker::class.java, 6, TimeUnit.HOURS)
+ .setInputData(workerCaseForUploadingEvents)
+ .setConstraints(logReportWorkerConstraints)
+ .build()
+
+ private val workRequestForUploadingExceptions: PeriodicWorkRequest = PeriodicWorkRequest
+ .Builder(LogUploadWorker::class.java, 6, TimeUnit.HOURS)
+ .setInputData(workerCaseForUploadingExceptions)
+ .setConstraints(logReportWorkerConstraints)
+ .build()
+
+ private val workRequestForSchedulingPeriodicBackgroundMetricLogs: PeriodicWorkRequest =
+ PeriodicWorkRequest.Builder(
+ MetricLogSchedulingWorker::class.java,
+ performanceMetricsCollectionHighFrequencyTimeInterval.value.toLong(),
+ TimeUnit.MINUTES
+ )
+ .setInputData(workerCaseForSchedulingPeriodicBackgroundMetricLogs)
+ .setConstraints(logReportWorkerConstraints)
+ .build()
+
+ private val workRequestForSchedulingStorageUsageMetricLogs: PeriodicWorkRequest =
+ PeriodicWorkRequest.Builder(
+ MetricLogSchedulingWorker::class.java,
+ performanceMetricCollectionLowFrequencyTimeInterval.value.toLong(),
+ TimeUnit.MINUTES
+ )
+ .setInputData(workerCaseForSchedulingStorageUsageMetricLogs)
+ .setConstraints(logReportWorkerConstraints)
+ .build()
+
+ private val workRequestForSchedulingPeriodicUiMetricLogs: PeriodicWorkRequest =
+ PeriodicWorkRequest.Builder(
+ MetricLogSchedulingWorker::class.java,
+ performanceMetricsCollectionHighFrequencyTimeInterval.value.toLong(),
+ TimeUnit.MINUTES
+ )
+ .setInputData(workerCaseForSchedulingPeriodicUiMetricLogs)
+ .setConstraints(logReportWorkerConstraints)
+ .build()
+
+ override fun onCreate() {
+ val workManager = WorkManager.getInstance(context)
+ logUploader.enqueueWorkRequestForEvents(workManager, workRequestForUploadingEvents)
+ logUploader.enqueueWorkRequestForExceptions(workManager, workRequestForUploadingExceptions)
+ metricLogScheduler.enqueueWorkRequestForPeriodicBackgroundMetrics(
+ workManager,
+ workRequestForSchedulingPeriodicBackgroundMetricLogs
+ )
+ metricLogScheduler.enqueueWorkRequestForStorageUsage(
+ workManager,
+ workRequestForSchedulingStorageUsageMetricLogs
+ )
+ metricLogScheduler.enqueueWorkRequestForPeriodicUiMetrics(
+ workManager,
+ workRequestForSchedulingPeriodicUiMetricLogs
+ )
+ }
+
+ /** Returns the worker constraints set for the log reporting work requests. */
+ fun getLogReportWorkerConstraints(): Constraints = logReportWorkerConstraints
+
+ /** Returns the [UUID] of the work request that is enqueued for uploading event logs. */
+ fun getWorkRequestForEventsId(): UUID = workRequestForUploadingEvents.id
+
+ /** Returns the [UUID] of the work request that is enqueued for uploading exception logs. */
+ fun getWorkRequestForExceptionsId(): UUID = workRequestForUploadingExceptions.id
+
+ /**
+ * Returns the [UUID] of the work request that is enqueued for scheduling memory usage
+ * performance metrics collection.
+ */
+ fun getWorkRequestForSchedulingPeriodicUiMetricLogsId(): UUID =
+ workRequestForSchedulingPeriodicUiMetricLogs.id
+
+ /**
+ * Returns the [UUID] of the work request that is enqueued for scheduling storage usage
+ * performance metrics collection.
+ */
+ fun getWorkRequestForSchedulingStorageUsageMetricLogsId(): UUID =
+ workRequestForSchedulingStorageUsageMetricLogs.id
+
+ /**
+ * Returns the [UUID] of the work request that is enqueued for scheduling periodic performance
+ * metrics collection.
+ */
+ fun getWorkRequestForSchedulingPeriodicBackgroundPerformanceMetricLogsId(): UUID =
+ workRequestForSchedulingPeriodicBackgroundMetricLogs.id
+
+ /**
+ * Returns the [Data] that goes into the work request that is enqueued for uploading event logs.
+ */
+ fun getWorkRequestDataForEvents(): Data = workerCaseForUploadingEvents
+
+ /**
+ * Returns the [Data] that goes into the work request that is enqueued for uploading exception
+ * logs.
+ */
+ fun getWorkRequestDataForExceptions(): Data = workerCaseForUploadingExceptions
+
+ /**
+ * Returns the [Data] that goes into the work request that is enqueued for scheduling storage
+ * usage performance metrics collection.
+ */
+ fun getWorkRequestDataForSchedulingStorageUsageMetricLogs(): Data =
+ workerCaseForSchedulingStorageUsageMetricLogs
+
+ /**
+ * Returns the [Data] that goes into the work request that is enqueued for scheduling memory
+ * usage performance metrics collection.
+ */
+ fun getWorkRequestDataForSchedulingPeriodicUiMetricLogs(): Data =
+ workerCaseForSchedulingPeriodicUiMetricLogs
+
+ /**
+ * Returns the [Data] that goes into the work request that is enqueued for scheduling periodic
+ * performance metrics collection.
+ */
+ fun getWorkRequestDataForSchedulingPeriodicBackgroundPerformanceMetricLogs(): Data =
+ workerCaseForSchedulingPeriodicBackgroundMetricLogs
+}
diff --git a/domain/src/main/java/org/oppia/android/domain/oppialogger/loguploader/LogUploadWorkerModule.kt b/domain/src/main/java/org/oppia/android/domain/oppialogger/loguploader/LogReportWorkerModule.kt
similarity index 71%
rename from domain/src/main/java/org/oppia/android/domain/oppialogger/loguploader/LogUploadWorkerModule.kt
rename to domain/src/main/java/org/oppia/android/domain/oppialogger/loguploader/LogReportWorkerModule.kt
index 97da4387bc0..d3b8e0efbfc 100644
--- a/domain/src/main/java/org/oppia/android/domain/oppialogger/loguploader/LogUploadWorkerModule.kt
+++ b/domain/src/main/java/org/oppia/android/domain/oppialogger/loguploader/LogReportWorkerModule.kt
@@ -7,11 +7,11 @@ import org.oppia.android.domain.oppialogger.ApplicationStartupListener
/** Provides [LogUploadWorker] related dependencies. */
@Module
-interface LogUploadWorkerModule {
+interface LogReportWorkerModule {
@Binds
@IntoSet
- fun bindLogUploadWorkRequest(
- logUploadWorkManagerInitializer: LogUploadWorkManagerInitializer
+ fun bindLogReportWorkRequest(
+ logReportWorkManagerInitializer: LogReportWorkManagerInitializer
): ApplicationStartupListener
}
diff --git a/domain/src/main/java/org/oppia/android/domain/oppialogger/loguploader/LogUploadWorkManagerInitializer.kt b/domain/src/main/java/org/oppia/android/domain/oppialogger/loguploader/LogUploadWorkManagerInitializer.kt
deleted file mode 100644
index 5eafd701c40..00000000000
--- a/domain/src/main/java/org/oppia/android/domain/oppialogger/loguploader/LogUploadWorkManagerInitializer.kt
+++ /dev/null
@@ -1,74 +0,0 @@
-package org.oppia.android.domain.oppialogger.loguploader
-
-import android.content.Context
-import androidx.work.Constraints
-import androidx.work.Data
-import androidx.work.NetworkType
-import androidx.work.PeriodicWorkRequest
-import androidx.work.WorkManager
-import org.oppia.android.domain.oppialogger.ApplicationStartupListener
-import org.oppia.android.util.logging.LogUploader
-import java.util.UUID
-import java.util.concurrent.TimeUnit
-import javax.inject.Inject
-import javax.inject.Singleton
-
-/** Enqueues unique periodic work requests for uploading events and exceptions to the remote service on application creation. */
-@Singleton
-class LogUploadWorkManagerInitializer @Inject constructor(
- private val context: Context,
- private val logUploader: LogUploader
-) : ApplicationStartupListener {
-
- private val logUploadWorkerConstraints = Constraints.Builder()
- .setRequiredNetworkType(NetworkType.CONNECTED)
- .setRequiresBatteryNotLow(true)
- .build()
-
- private val workerCaseForUploadingEvents: Data = Data.Builder()
- .putString(
- LogUploadWorker.WORKER_CASE_KEY,
- LogUploadWorker.EVENT_WORKER
- )
- .build()
-
- private val workerCaseForUploadingExceptions: Data = Data.Builder()
- .putString(
- LogUploadWorker.WORKER_CASE_KEY,
- LogUploadWorker.EXCEPTION_WORKER
- )
- .build()
-
- private val workRequestForUploadingEvents: PeriodicWorkRequest = PeriodicWorkRequest
- .Builder(LogUploadWorker::class.java, 6, TimeUnit.HOURS)
- .setInputData(workerCaseForUploadingEvents)
- .setConstraints(logUploadWorkerConstraints)
- .build()
-
- private val workRequestForUploadingExceptions: PeriodicWorkRequest = PeriodicWorkRequest
- .Builder(LogUploadWorker::class.java, 6, TimeUnit.HOURS)
- .setInputData(workerCaseForUploadingExceptions)
- .setConstraints(logUploadWorkerConstraints)
- .build()
-
- override fun onCreate() {
- val workManager = WorkManager.getInstance(context)
- logUploader.enqueueWorkRequestForEvents(workManager, workRequestForUploadingEvents)
- logUploader.enqueueWorkRequestForExceptions(workManager, workRequestForUploadingExceptions)
- }
-
- /** Returns the worker constraints set for the log uploading work requests. */
- fun getLogUploadWorkerConstraints(): Constraints = logUploadWorkerConstraints
-
- /** Returns the [UUID] of the work request that is enqueued for uploading event logs. */
- fun getWorkRequestForEventsId(): UUID = workRequestForUploadingEvents.id
-
- /** Returns the [UUID] of the work request that is enqueued for uploading exception logs. */
- fun getWorkRequestForExceptionsId(): UUID = workRequestForUploadingExceptions.id
-
- /** Returns the [Data] that goes into the work request that is enqueued for uploading event logs. */
- fun getWorkRequestDataForEvents(): Data = workerCaseForUploadingEvents
-
- /** Returns the [Data] that goes into the work request that is enqueued for uploading exception logs. */
- fun getWorkRequestDataForExceptions(): Data = workerCaseForUploadingExceptions
-}
diff --git a/domain/src/main/java/org/oppia/android/domain/workmanager/WorkManagerConfigurationModule.kt b/domain/src/main/java/org/oppia/android/domain/workmanager/WorkManagerConfigurationModule.kt
index 88244242d3c..11fa8e5f82f 100644
--- a/domain/src/main/java/org/oppia/android/domain/workmanager/WorkManagerConfigurationModule.kt
+++ b/domain/src/main/java/org/oppia/android/domain/workmanager/WorkManagerConfigurationModule.kt
@@ -4,6 +4,7 @@ import androidx.work.Configuration
import androidx.work.DelegatingWorkerFactory
import dagger.Module
import dagger.Provides
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulingWorkerFactory
import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerFactory
import org.oppia.android.domain.platformparameter.syncup.PlatformParameterSyncUpWorkerFactory
import javax.inject.Singleton
@@ -16,11 +17,13 @@ class WorkManagerConfigurationModule {
@Provides
fun provideWorkManagerConfiguration(
logUploadWorkerFactory: LogUploadWorkerFactory,
- platformParameterSyncUpWorkerFactory: PlatformParameterSyncUpWorkerFactory
+ platformParameterSyncUpWorkerFactory: PlatformParameterSyncUpWorkerFactory,
+ metricLogSchedulingWorkerFactory: MetricLogSchedulingWorkerFactory
): Configuration {
val delegatingWorkerFactory = DelegatingWorkerFactory()
delegatingWorkerFactory.addFactory(logUploadWorkerFactory)
delegatingWorkerFactory.addFactory(platformParameterSyncUpWorkerFactory)
+ delegatingWorkerFactory.addFactory(metricLogSchedulingWorkerFactory)
return Configuration.Builder().setWorkerFactory(delegatingWorkerFactory).build()
}
}
diff --git a/domain/src/test/java/org/oppia/android/domain/oppialogger/analytics/ApplicationLifecycleObserverTest.kt b/domain/src/test/java/org/oppia/android/domain/oppialogger/analytics/ApplicationLifecycleObserverTest.kt
index 0b27589fbd2..2127964d663 100644
--- a/domain/src/test/java/org/oppia/android/domain/oppialogger/analytics/ApplicationLifecycleObserverTest.kt
+++ b/domain/src/test/java/org/oppia/android/domain/oppialogger/analytics/ApplicationLifecycleObserverTest.kt
@@ -63,6 +63,7 @@ class ApplicationLifecycleObserverTest {
@Inject lateinit var monitorFactory: DataProviderTestMonitor.Factory
@Inject lateinit var fakeEventLogger: FakeEventLogger
@Inject lateinit var profileManagementController: ProfileManagementController
+ @Inject lateinit var performanceMetricsController: PerformanceMetricsController
@Test
fun testObserver_getSessionId_backgroundApp_thenForeground_limitExceeded_sessionIdUpdated() {
@@ -152,6 +153,22 @@ class ApplicationLifecycleObserverTest {
}
}
+ @Test
+ fun testObserver_onAppInForeground_setsAppInForeground() {
+ setUpTestApplicationComponent()
+ applicationLifecycleObserver.onAppInForeground()
+
+ assertThat(performanceMetricsController.getIsAppInForeground()).isTrue()
+ }
+
+ @Test
+ fun testObserver_onAppInBackground_setsAppInBackground() {
+ setUpTestApplicationComponent()
+ applicationLifecycleObserver.onAppInBackground()
+
+ assertThat(performanceMetricsController.getIsAppInForeground()).isFalse()
+ }
+
private fun waitInBackgroundFor(millis: Long) {
applicationLifecycleObserver.onAppInBackground()
testCoroutineDispatchers.runCurrent()
diff --git a/domain/src/test/java/org/oppia/android/domain/oppialogger/analytics/PerformanceMetricsControllerTest.kt b/domain/src/test/java/org/oppia/android/domain/oppialogger/analytics/PerformanceMetricsControllerTest.kt
new file mode 100644
index 00000000000..df198f52b8b
--- /dev/null
+++ b/domain/src/test/java/org/oppia/android/domain/oppialogger/analytics/PerformanceMetricsControllerTest.kt
@@ -0,0 +1,555 @@
+package org.oppia.android.domain.oppialogger.analytics
+
+import android.app.Application
+import android.content.Context
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.runner.AndroidJUnit4
+import com.google.common.truth.Truth.assertThat
+import dagger.BindsInstance
+import dagger.Component
+import dagger.Module
+import dagger.Provides
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.oppia.android.app.model.OppiaMetricLog
+import org.oppia.android.app.model.OppiaMetricLog.CurrentScreen.SCREEN_UNSPECIFIED
+import org.oppia.android.app.model.OppiaMetricLog.LoggableMetric.LoggableMetricTypeCase.APK_SIZE_METRIC
+import org.oppia.android.app.model.OppiaMetricLog.LoggableMetric.LoggableMetricTypeCase.CPU_USAGE_METRIC
+import org.oppia.android.app.model.OppiaMetricLog.LoggableMetric.LoggableMetricTypeCase.MEMORY_USAGE_METRIC
+import org.oppia.android.app.model.OppiaMetricLog.LoggableMetric.LoggableMetricTypeCase.NETWORK_USAGE_METRIC
+import org.oppia.android.app.model.OppiaMetricLog.LoggableMetric.LoggableMetricTypeCase.STARTUP_LATENCY_METRIC
+import org.oppia.android.app.model.OppiaMetricLog.LoggableMetric.LoggableMetricTypeCase.STORAGE_USAGE_METRIC
+import org.oppia.android.app.model.OppiaMetricLog.Priority.HIGH_PRIORITY
+import org.oppia.android.app.model.OppiaMetricLog.Priority.LOW_PRIORITY
+import org.oppia.android.app.model.OppiaMetricLog.Priority.MEDIUM_PRIORITY
+import org.oppia.android.domain.oppialogger.EventLogStorageCacheSize
+import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
+import org.oppia.android.domain.oppialogger.OppiaLogger
+import org.oppia.android.domain.oppialogger.PerformanceMetricsLogStorageCacheSize
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.platformparameter.PlatformParameterModule
+import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
+import org.oppia.android.testing.FakePerformanceMetricsEventLogger
+import org.oppia.android.testing.TestLogReportingModule
+import org.oppia.android.testing.data.DataProviderTestMonitor
+import org.oppia.android.testing.logging.SyncStatusTestModule
+import org.oppia.android.testing.robolectric.RobolectricModule
+import org.oppia.android.testing.threading.TestDispatcherModule
+import org.oppia.android.testing.time.FakeOppiaClock
+import org.oppia.android.testing.time.FakeOppiaClockModule
+import org.oppia.android.util.data.DataProviders
+import org.oppia.android.util.data.DataProvidersInjector
+import org.oppia.android.util.data.DataProvidersInjectorProvider
+import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EnableConsoleLog
+import org.oppia.android.util.logging.EnableFileLog
+import org.oppia.android.util.logging.GlobalLogLevel
+import org.oppia.android.util.logging.LogLevel
+import org.oppia.android.util.networking.NetworkConnectionDebugUtil
+import org.oppia.android.util.networking.NetworkConnectionUtil.ProdConnectionStatus.NONE
+import org.oppia.android.util.networking.NetworkConnectionUtilDebugModule
+import org.robolectric.annotation.Config
+import org.robolectric.annotation.LooperMode
+import javax.inject.Inject
+import javax.inject.Singleton
+
+private const val TEST_TIMESTAMP = Long.MAX_VALUE
+private const val TEST_CPU_USAGE = Long.MAX_VALUE
+private const val TEST_APK_SIZE = Long.MAX_VALUE
+private const val TEST_STORAGE_USAGE = Long.MAX_VALUE
+private const val TEST_STARTUP_LATENCY = Long.MAX_VALUE
+private const val TEST_NETWORK_USAGE = Long.MAX_VALUE
+private const val TEST_MEMORY_USAGE = Long.MAX_VALUE
+
+/** Tests for [PerformanceMetricsController]. */
+// FunctionName: test names are conventionally named with underscores.
+@Suppress("FunctionName")
+@RunWith(AndroidJUnit4::class)
+@LooperMode(LooperMode.Mode.PAUSED)
+@Config(application = PerformanceMetricsControllerTest.TestApplication::class)
+class PerformanceMetricsControllerTest {
+
+ @Inject
+ lateinit var performanceMetricsController: PerformanceMetricsController
+
+ @Inject
+ lateinit var oppiaLogger: OppiaLogger
+
+ @Inject
+ lateinit var networkConnectionUtil: NetworkConnectionDebugUtil
+
+ @Inject
+ lateinit var fakePerformanceMetricsEventLogger: FakePerformanceMetricsEventLogger
+
+ @Inject
+ lateinit var dataProviders: DataProviders
+
+ @Inject
+ lateinit var monitorFactory: DataProviderTestMonitor.Factory
+
+ @Inject
+ lateinit var fakeOppiaClock: FakeOppiaClock
+
+ private val apkSizeTestLoggableMetric = OppiaMetricLog.LoggableMetric.newBuilder()
+ .setApkSizeMetric(
+ OppiaMetricLog.ApkSizeMetric.newBuilder()
+ .setApkSizeBytes(TEST_APK_SIZE)
+ .build()
+ ).build()
+
+ private val storageUsageTestLoggableMetric = OppiaMetricLog.LoggableMetric.newBuilder()
+ .setStorageUsageMetric(
+ OppiaMetricLog.StorageUsageMetric.newBuilder()
+ .setStorageUsageBytes(TEST_STORAGE_USAGE)
+ .build()
+ ).build()
+
+ private val startupLatencyTestLoggableMetric = OppiaMetricLog.LoggableMetric.newBuilder()
+ .setStartupLatencyMetric(
+ OppiaMetricLog.StartupLatencyMetric.newBuilder()
+ .setStartupLatencyMillis(TEST_STARTUP_LATENCY)
+ .build()
+ ).build()
+
+ private val cpuUsageTestLoggableMetric = OppiaMetricLog.LoggableMetric.newBuilder()
+ .setCpuUsageMetric(
+ OppiaMetricLog.CpuUsageMetric.newBuilder()
+ .setCpuUsageMetric(TEST_CPU_USAGE)
+ .build()
+ ).build()
+
+ private val networkUsageTestLoggableMetric = OppiaMetricLog.LoggableMetric.newBuilder()
+ .setNetworkUsageMetric(
+ OppiaMetricLog.NetworkUsageMetric.newBuilder()
+ .setBytesReceived(TEST_NETWORK_USAGE)
+ .setBytesSent(TEST_NETWORK_USAGE)
+ .build()
+ ).build()
+
+ private val memoryUsageTestLoggableMetric = OppiaMetricLog.LoggableMetric.newBuilder()
+ .setMemoryUsageMetric(
+ OppiaMetricLog.MemoryUsageMetric.newBuilder()
+ .setTotalPssBytes(TEST_MEMORY_USAGE)
+ .build()
+ ).build()
+
+ @Before
+ fun setUp() {
+ setUpTestApplicationComponent()
+ fakeOppiaClock.setFakeTimeMode(FakeOppiaClock.FakeTimeMode.MODE_FIXED_FAKE_TIME)
+ fakeOppiaClock.setCurrentTimeMs(TEST_TIMESTAMP)
+ }
+
+ @Test
+ fun testController_logPerformanceMetric_withApkSizeLoggableMetric_checkLogsMetric() {
+ performanceMetricsController.logPerformanceMetricsEvent(
+ TEST_TIMESTAMP,
+ SCREEN_UNSPECIFIED,
+ apkSizeTestLoggableMetric,
+ LOW_PRIORITY
+ )
+
+ val performanceMetricsLog =
+ fakePerformanceMetricsEventLogger.getMostRecentPerformanceMetricsEvent()
+
+ assertThat(performanceMetricsLog.timestampMillis).isEqualTo(TEST_TIMESTAMP)
+ assertThat(performanceMetricsLog.currentScreen).isEqualTo(SCREEN_UNSPECIFIED)
+ assertThat(performanceMetricsLog.priority).isEqualTo(LOW_PRIORITY)
+ assertThat(performanceMetricsLog.loggableMetric.loggableMetricTypeCase).isEqualTo(
+ APK_SIZE_METRIC
+ )
+ }
+
+ @Test
+ fun testController_logPerformanceMetric_withStorageUsageLoggableMetric_checkLogsMetric() {
+ performanceMetricsController.logPerformanceMetricsEvent(
+ TEST_TIMESTAMP,
+ SCREEN_UNSPECIFIED,
+ storageUsageTestLoggableMetric,
+ LOW_PRIORITY
+ )
+
+ val performanceMetricsLog =
+ fakePerformanceMetricsEventLogger.getMostRecentPerformanceMetricsEvent()
+
+ assertThat(performanceMetricsLog.timestampMillis).isEqualTo(TEST_TIMESTAMP)
+ assertThat(performanceMetricsLog.currentScreen).isEqualTo(SCREEN_UNSPECIFIED)
+ assertThat(performanceMetricsLog.priority).isEqualTo(LOW_PRIORITY)
+ assertThat(performanceMetricsLog.loggableMetric.loggableMetricTypeCase).isEqualTo(
+ STORAGE_USAGE_METRIC
+ )
+ }
+
+ @Test
+ fun testController_logPerformanceMetric_withStartupLatencyLoggableMetric_checkLogsMetric() {
+ performanceMetricsController.logPerformanceMetricsEvent(
+ TEST_TIMESTAMP,
+ SCREEN_UNSPECIFIED,
+ startupLatencyTestLoggableMetric,
+ LOW_PRIORITY
+ )
+
+ val performanceMetricsLog =
+ fakePerformanceMetricsEventLogger.getMostRecentPerformanceMetricsEvent()
+
+ assertThat(performanceMetricsLog.timestampMillis).isEqualTo(TEST_TIMESTAMP)
+ assertThat(performanceMetricsLog.currentScreen).isEqualTo(SCREEN_UNSPECIFIED)
+ assertThat(performanceMetricsLog.priority).isEqualTo(LOW_PRIORITY)
+ assertThat(performanceMetricsLog.loggableMetric.loggableMetricTypeCase).isEqualTo(
+ STARTUP_LATENCY_METRIC
+ )
+ }
+
+ @Test
+ fun testController_logPerformanceMetric_withMemoryUsageLoggableMetric_checkLogsMetric() {
+ performanceMetricsController.logPerformanceMetricsEvent(
+ TEST_TIMESTAMP,
+ SCREEN_UNSPECIFIED,
+ memoryUsageTestLoggableMetric,
+ MEDIUM_PRIORITY
+ )
+
+ val performanceMetricsLog =
+ fakePerformanceMetricsEventLogger.getMostRecentPerformanceMetricsEvent()
+
+ assertThat(performanceMetricsLog.timestampMillis).isEqualTo(TEST_TIMESTAMP)
+ assertThat(performanceMetricsLog.currentScreen).isEqualTo(SCREEN_UNSPECIFIED)
+ assertThat(performanceMetricsLog.priority).isEqualTo(MEDIUM_PRIORITY)
+ assertThat(performanceMetricsLog.loggableMetric.loggableMetricTypeCase).isEqualTo(
+ MEMORY_USAGE_METRIC
+ )
+ }
+
+ @Test
+ fun testController_logPerformanceMetric_withNetworkUsageLoggableMetric_checkLogsMetric() {
+ performanceMetricsController.logPerformanceMetricsEvent(
+ TEST_TIMESTAMP,
+ SCREEN_UNSPECIFIED,
+ networkUsageTestLoggableMetric,
+ HIGH_PRIORITY
+ )
+
+ val performanceMetricsLog =
+ fakePerformanceMetricsEventLogger.getMostRecentPerformanceMetricsEvent()
+
+ assertThat(performanceMetricsLog.timestampMillis).isEqualTo(TEST_TIMESTAMP)
+ assertThat(performanceMetricsLog.currentScreen).isEqualTo(SCREEN_UNSPECIFIED)
+ assertThat(performanceMetricsLog.priority).isEqualTo(HIGH_PRIORITY)
+ assertThat(performanceMetricsLog.loggableMetric.loggableMetricTypeCase).isEqualTo(
+ NETWORK_USAGE_METRIC
+ )
+ }
+
+ @Test
+ fun testController_logPerformanceMetric_withCpuUsageLoggableMetric_checkLogsMetric() {
+ performanceMetricsController.logPerformanceMetricsEvent(
+ TEST_TIMESTAMP,
+ SCREEN_UNSPECIFIED,
+ cpuUsageTestLoggableMetric,
+ HIGH_PRIORITY
+ )
+
+ val performanceMetricsLog =
+ fakePerformanceMetricsEventLogger.getMostRecentPerformanceMetricsEvent()
+
+ assertThat(performanceMetricsLog.timestampMillis).isEqualTo(TEST_TIMESTAMP)
+ assertThat(performanceMetricsLog.currentScreen).isEqualTo(SCREEN_UNSPECIFIED)
+ assertThat(performanceMetricsLog.priority).isEqualTo(HIGH_PRIORITY)
+ assertThat(performanceMetricsLog.loggableMetric.loggableMetricTypeCase).isEqualTo(
+ CPU_USAGE_METRIC
+ )
+ }
+
+ @Test
+ fun testController_logPerformanceMetric_withNoNetwork_checkLogsEventToStore() {
+ networkConnectionUtil.setCurrentConnectionStatus(NONE)
+ performanceMetricsController.logPerformanceMetricsEvent(
+ TEST_TIMESTAMP,
+ SCREEN_UNSPECIFIED,
+ apkSizeTestLoggableMetric,
+ LOW_PRIORITY
+ )
+
+ val eventLogsProvider = performanceMetricsController.getMetricLogStore()
+
+ val performanceMetricsLog =
+ monitorFactory.waitForNextSuccessfulResult(eventLogsProvider).getOppiaMetricLog(0)
+ assertThat(performanceMetricsLog.timestampMillis).isEqualTo(TEST_TIMESTAMP)
+ assertThat(performanceMetricsLog.priority).isEqualTo(LOW_PRIORITY)
+ assertThat(performanceMetricsLog.loggableMetric.loggableMetricTypeCase).isEqualTo(
+ APK_SIZE_METRIC
+ )
+ }
+
+ @Test
+ fun testController_logPerformanceMetric_withNoNetwork_exceedLimit_checkEventLogStoreSize() {
+ networkConnectionUtil.setCurrentConnectionStatus(NONE)
+ logMultiplePerformanceMetrics()
+
+ val eventLogsProvider = performanceMetricsController.getMetricLogStore()
+
+ val performanceMetricLogs = monitorFactory.waitForNextSuccessfulResult(eventLogsProvider)
+ assertThat(performanceMetricLogs.oppiaMetricLogList).hasSize(2)
+ }
+
+ @Test
+ fun testController_logMultiplePerformanceMetrics_withNoNetwork_checkOrderInCache() {
+ networkConnectionUtil.setCurrentConnectionStatus(NONE)
+ performanceMetricsController.logPerformanceMetricsEvent(
+ TEST_TIMESTAMP,
+ SCREEN_UNSPECIFIED,
+ apkSizeTestLoggableMetric,
+ LOW_PRIORITY
+ )
+ performanceMetricsController.logPerformanceMetricsEvent(
+ TEST_TIMESTAMP,
+ SCREEN_UNSPECIFIED,
+ cpuUsageTestLoggableMetric,
+ HIGH_PRIORITY
+ )
+
+ val metricLogsProvider = performanceMetricsController.getMetricLogStore()
+
+ val metricLogs = monitorFactory.waitForNextSuccessfulResult(metricLogsProvider)
+ val firstEventLog = metricLogs.getOppiaMetricLog(0)
+ val secondEventLog = metricLogs.getOppiaMetricLog(1)
+
+ assertThat(firstEventLog.priority).isEqualTo(LOW_PRIORITY)
+ assertThat(secondEventLog.priority).isEqualTo(HIGH_PRIORITY)
+ }
+
+ @Test
+ fun testController_logPerformanceMetric_switchToNoNetwork_logPerformanceMetric_checkManagement() {
+ performanceMetricsController.logPerformanceMetricsEvent(
+ TEST_TIMESTAMP,
+ SCREEN_UNSPECIFIED,
+ cpuUsageTestLoggableMetric,
+ HIGH_PRIORITY
+ )
+ networkConnectionUtil.setCurrentConnectionStatus(NONE)
+ performanceMetricsController.logPerformanceMetricsEvent(
+ TEST_TIMESTAMP,
+ SCREEN_UNSPECIFIED,
+ apkSizeTestLoggableMetric,
+ LOW_PRIORITY
+ )
+
+ val metricLogsProvider = performanceMetricsController.getMetricLogStore()
+
+ val uploadedMetricLog = fakePerformanceMetricsEventLogger.getMostRecentPerformanceMetricsEvent()
+ val cachedMetricLog =
+ monitorFactory.waitForNextSuccessfulResult(metricLogsProvider).getOppiaMetricLog(0)
+
+ assertThat(uploadedMetricLog.timestampMillis).isEqualTo(TEST_TIMESTAMP)
+ assertThat(uploadedMetricLog.priority).isEqualTo(HIGH_PRIORITY)
+ assertThat(uploadedMetricLog.loggableMetric.loggableMetricTypeCase).isEqualTo(CPU_USAGE_METRIC)
+
+ assertThat(cachedMetricLog.timestampMillis).isEqualTo(TEST_TIMESTAMP)
+ assertThat(cachedMetricLog.priority).isEqualTo(LOW_PRIORITY)
+ assertThat(cachedMetricLog.loggableMetric.loggableMetricTypeCase).isEqualTo(APK_SIZE_METRIC)
+ }
+
+ @Test
+ fun testController_logPerformanceMetrics_exceedLimit_withNoNetwork_checkCorrectEventIsEvicted() {
+ networkConnectionUtil.setCurrentConnectionStatus(NONE)
+ logMultiplePerformanceMetrics()
+
+ val metricLogsProvider = performanceMetricsController.getMetricLogStore()
+
+ val metricLogs = monitorFactory.waitForNextSuccessfulResult(metricLogsProvider)
+ val firstMetricLog = metricLogs.getOppiaMetricLog(0)
+ val secondMetricLog = metricLogs.getOppiaMetricLog(1)
+ assertThat(metricLogs.oppiaMetricLogList).hasSize(2)
+ // In this case, 1 LOW, 1 HIGH and 2 MEDIUM priority metric logs were logged. So while pruning,
+ // only records with HIGH and MEDIUM priority should be retained.
+ assertThat(firstMetricLog.priority).isEqualTo(HIGH_PRIORITY)
+ assertThat(secondMetricLog.priority).isEqualTo(HIGH_PRIORITY)
+ // If we analyse the implementation of logMultiplePerformanceMetrics(), we can see that record
+ // pruning will begin from the logging of the third record. At first, the first event log will
+ // be removed as it has LOW priority and the event logged at the third place will become the
+ // event record at the second place in the store. When the forth event gets logged then the
+ // pruning will again happen on the basis of priority as MEDIUM priority event will be evicted.
+ // Now, when the fifth event gets logged then pruning happen based on purely based on timestamp
+ // of the event as both event logs have HIGH priority. As the second event's timestamp was
+ // lesser than that of the fourth event, it will be pruned from the store and the fifth event
+ // will become the second event in the store.
+ assertThat(firstMetricLog.timestampMillis).isEqualTo(1556093110000)
+ assertThat(secondMetricLog.timestampMillis).isEqualTo(1556094110000)
+ }
+
+ @Test
+ fun testController_setAppInForeground_getIsAppInForeground_returnsCorrectValue() {
+ performanceMetricsController.setAppInForeground()
+
+ val isAppInForeground = performanceMetricsController.getIsAppInForeground()
+
+ assertThat(isAppInForeground).isTrue()
+ }
+
+ @Test
+ fun testController_setAppInForeground_logMetric_logsMetricWithAppInForeground() {
+ performanceMetricsController.setAppInForeground()
+ performanceMetricsController.logPerformanceMetricsEvent(
+ TEST_TIMESTAMP,
+ SCREEN_UNSPECIFIED,
+ apkSizeTestLoggableMetric,
+ LOW_PRIORITY
+ )
+
+ val performanceMetricsLog =
+ fakePerformanceMetricsEventLogger.getMostRecentPerformanceMetricsEvent()
+
+ assertThat(performanceMetricsLog.timestampMillis).isEqualTo(TEST_TIMESTAMP)
+ assertThat(performanceMetricsLog.currentScreen).isEqualTo(SCREEN_UNSPECIFIED)
+ assertThat(performanceMetricsLog.priority).isEqualTo(LOW_PRIORITY)
+ assertThat(performanceMetricsLog.loggableMetric.loggableMetricTypeCase).isEqualTo(
+ APK_SIZE_METRIC
+ )
+ assertThat(performanceMetricsLog.isAppInForeground).isTrue()
+ }
+
+ @Test
+ fun testController_setAppInBackground_getIsAppInForeground_returnsCorrectValue() {
+ performanceMetricsController.setAppInBackground()
+
+ val isAppInForeground = performanceMetricsController.getIsAppInForeground()
+
+ assertThat(isAppInForeground).isFalse()
+ }
+
+ @Test
+ fun testController_setAppInBackground_logMetric_logsMetricWithAppInBackground() {
+ performanceMetricsController.setAppInBackground()
+ performanceMetricsController.logPerformanceMetricsEvent(
+ TEST_TIMESTAMP,
+ SCREEN_UNSPECIFIED,
+ apkSizeTestLoggableMetric,
+ LOW_PRIORITY
+ )
+
+ val performanceMetricsLog =
+ fakePerformanceMetricsEventLogger.getMostRecentPerformanceMetricsEvent()
+
+ assertThat(performanceMetricsLog.timestampMillis).isEqualTo(TEST_TIMESTAMP)
+ assertThat(performanceMetricsLog.currentScreen).isEqualTo(SCREEN_UNSPECIFIED)
+ assertThat(performanceMetricsLog.priority).isEqualTo(LOW_PRIORITY)
+ assertThat(performanceMetricsLog.loggableMetric.loggableMetricTypeCase).isEqualTo(
+ APK_SIZE_METRIC
+ )
+ assertThat(performanceMetricsLog.isAppInForeground).isFalse()
+ }
+
+ private fun logMultiplePerformanceMetrics() {
+ performanceMetricsController.logPerformanceMetricsEvent(
+ 1556094120000,
+ SCREEN_UNSPECIFIED,
+ apkSizeTestLoggableMetric,
+ LOW_PRIORITY
+ )
+
+ performanceMetricsController.logPerformanceMetricsEvent(
+ 1556090110000,
+ SCREEN_UNSPECIFIED,
+ apkSizeTestLoggableMetric,
+ HIGH_PRIORITY
+ )
+
+ performanceMetricsController.logPerformanceMetricsEvent(
+ 1556092100000,
+ SCREEN_UNSPECIFIED,
+ apkSizeTestLoggableMetric,
+ MEDIUM_PRIORITY
+ )
+
+ performanceMetricsController.logPerformanceMetricsEvent(
+ 1556093110000,
+ SCREEN_UNSPECIFIED,
+ apkSizeTestLoggableMetric,
+ HIGH_PRIORITY
+ )
+
+ performanceMetricsController.logPerformanceMetricsEvent(
+ 1556094110000,
+ SCREEN_UNSPECIFIED,
+ apkSizeTestLoggableMetric,
+ HIGH_PRIORITY
+ )
+ }
+
+ private fun setUpTestApplicationComponent() {
+ ApplicationProvider.getApplicationContext().inject(this)
+ }
+
+ // TODO(#89): Move this to a common test application component.
+ @Module
+ class TestModule {
+ @Provides
+ @Singleton
+ fun provideContext(application: Application): Context {
+ return application
+ }
+
+ // TODO(#59): Either isolate these to their own shared test module, or use the real logging
+ // module in tests to avoid needing to specify these settings for tests.
+ @EnableConsoleLog
+ @Provides
+ fun provideEnableConsoleLog(): Boolean = true
+
+ @EnableFileLog
+ @Provides
+ fun provideEnableFileLog(): Boolean = false
+
+ @GlobalLogLevel
+ @Provides
+ fun provideGlobalLogLevel(): LogLevel = LogLevel.VERBOSE
+ }
+
+ @Module
+ class TestLogStorageModule {
+
+ @Provides
+ @PerformanceMetricsLogStorageCacheSize
+ fun providePerformanceMetricsLogStorageCacheSize(): Int = 2
+
+ @Provides
+ @EventLogStorageCacheSize
+ fun provideEventLogStorageCacheSize(): Int = 2
+ }
+
+ // TODO(#89): Move this to a common test application component.
+ @Singleton
+ @Component(
+ modules = [
+ TestModule::class, TestLogReportingModule::class, RobolectricModule::class,
+ TestDispatcherModule::class, TestLogStorageModule::class,
+ NetworkConnectionUtilDebugModule::class, LocaleProdModule::class, FakeOppiaClockModule::class,
+ PlatformParameterModule::class, PlatformParameterSingletonModule::class,
+ LoggingIdentifierModule::class, SyncStatusTestModule::class, MetricLogSchedulerModule::class
+ ]
+ )
+ interface TestApplicationComponent : DataProvidersInjector {
+ @Component.Builder
+ interface Builder {
+ @BindsInstance
+ fun setApplication(application: Application): Builder
+ fun build(): TestApplicationComponent
+ }
+
+ fun inject(performanceMetricsControllerTest: PerformanceMetricsControllerTest)
+ }
+
+ class TestApplication : Application(), DataProvidersInjectorProvider {
+ private val component: TestApplicationComponent by lazy {
+ DaggerPerformanceMetricsControllerTest_TestApplicationComponent.builder()
+ .setApplication(this)
+ .build()
+ }
+
+ fun inject(performanceMetricsControllerTest: PerformanceMetricsControllerTest) {
+ component.inject(performanceMetricsControllerTest)
+ }
+
+ override fun getDataProvidersInjector(): DataProvidersInjector = component
+ }
+}
diff --git a/domain/src/test/java/org/oppia/android/domain/oppialogger/analytics/PerformanceMetricsLoggerModuleTest.kt b/domain/src/test/java/org/oppia/android/domain/oppialogger/analytics/PerformanceMetricsLoggerModuleTest.kt
new file mode 100644
index 00000000000..d52ead57e0f
--- /dev/null
+++ b/domain/src/test/java/org/oppia/android/domain/oppialogger/analytics/PerformanceMetricsLoggerModuleTest.kt
@@ -0,0 +1,106 @@
+package org.oppia.android.domain.oppialogger.analytics
+
+import android.app.Application
+import android.content.Context
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.google.common.truth.Truth.assertThat
+import dagger.Binds
+import dagger.BindsInstance
+import dagger.Component
+import dagger.Module
+import dagger.multibindings.Multibinds
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.oppia.android.domain.oppialogger.ApplicationStartupListener
+import org.oppia.android.domain.oppialogger.LogStorageModule
+import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
+import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
+import org.oppia.android.testing.TestLogReportingModule
+import org.oppia.android.testing.platformparameter.TestPlatformParameterModule
+import org.oppia.android.testing.robolectric.RobolectricModule
+import org.oppia.android.testing.threading.TestDispatcherModule
+import org.oppia.android.testing.time.FakeOppiaClockModule
+import org.oppia.android.util.data.DataProvidersInjector
+import org.oppia.android.util.data.DataProvidersInjectorProvider
+import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.LoggerModule
+import org.oppia.android.util.logging.SyncStatusModule
+import org.oppia.android.util.networking.NetworkConnectionUtilDebugModule
+import org.robolectric.annotation.Config
+import org.robolectric.annotation.LooperMode
+import javax.inject.Inject
+import javax.inject.Singleton
+
+/** Tests for [PerformanceMetricsLoggerModule]. */
+// FunctionName: test names are conventionally named with underscores.
+@Suppress("FunctionName")
+@RunWith(AndroidJUnit4::class)
+@LooperMode(LooperMode.Mode.PAUSED)
+@Config(application = PerformanceMetricsLoggerModuleTest.TestApplication::class)
+class PerformanceMetricsLoggerModuleTest {
+ @Inject
+ lateinit var startupListeners: Set<@JvmSuppressWildcards ApplicationStartupListener>
+
+ @Before
+ fun setUp() {
+ setUpTestApplicationComponent()
+ }
+
+ @Test
+ fun testInjectApplicationStartupListenerSet_includesPerformanceMetricsLogger() {
+ assertThat(startupListeners.any { it is PerformanceMetricsLogger }).isTrue()
+ }
+
+ private fun setUpTestApplicationComponent() {
+ ApplicationProvider.getApplicationContext().inject(this)
+ }
+
+ // TODO(#89): Move this to a common test application component.
+ @Module
+ interface TestModule {
+ @Binds
+ fun provideContext(application: Application): Context
+
+ @Multibinds
+ fun bindStartupListenerSet(): Set
+ }
+
+ // TODO(#89): Move this to a common test application component.
+ @Singleton
+ @Component(
+ modules = [
+ TestModule::class, TestLogReportingModule::class, LogStorageModule::class,
+ TestDispatcherModule::class, RobolectricModule::class, FakeOppiaClockModule::class,
+ NetworkConnectionUtilDebugModule::class, LocaleProdModule::class,
+ TestPlatformParameterModule::class, PlatformParameterSingletonModule::class,
+ LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
+ LoggerModule::class, SyncStatusModule::class, PerformanceMetricsLoggerModule::class
+ ]
+ )
+ interface TestApplicationComponent : DataProvidersInjector {
+ @Component.Builder
+ interface Builder {
+ @BindsInstance
+ fun setApplication(application: Application): Builder
+ fun build(): TestApplicationComponent
+ }
+
+ fun inject(test: PerformanceMetricsLoggerModuleTest)
+ }
+
+ class TestApplication : Application(), DataProvidersInjectorProvider {
+ private val component: TestApplicationComponent by lazy {
+ DaggerPerformanceMetricsLoggerModuleTest_TestApplicationComponent.builder()
+ .setApplication(this)
+ .build()
+ }
+
+ fun inject(test: PerformanceMetricsLoggerModuleTest) {
+ component.inject(test)
+ }
+
+ override fun getDataProvidersInjector(): DataProvidersInjector = component
+ }
+}
diff --git a/domain/src/test/java/org/oppia/android/domain/oppialogger/analytics/PerformanceMetricsLoggerTest.kt b/domain/src/test/java/org/oppia/android/domain/oppialogger/analytics/PerformanceMetricsLoggerTest.kt
new file mode 100644
index 00000000000..e26b8767689
--- /dev/null
+++ b/domain/src/test/java/org/oppia/android/domain/oppialogger/analytics/PerformanceMetricsLoggerTest.kt
@@ -0,0 +1,315 @@
+package org.oppia.android.domain.oppialogger.analytics
+
+import android.app.Application
+import android.content.Context
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.google.common.truth.Truth.assertThat
+import dagger.Binds
+import dagger.BindsInstance
+import dagger.Component
+import dagger.Module
+import dagger.Provides
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.oppia.android.app.model.OppiaMetricLog
+import org.oppia.android.app.model.OppiaMetricLog.CurrentScreen.HOME_SCREEN
+import org.oppia.android.app.model.OppiaMetricLog.CurrentScreen.SCREEN_UNSPECIFIED
+import org.oppia.android.app.model.OppiaMetricLog.LoggableMetric.LoggableMetricTypeCase.APK_SIZE_METRIC
+import org.oppia.android.app.model.OppiaMetricLog.LoggableMetric.LoggableMetricTypeCase.CPU_USAGE_METRIC
+import org.oppia.android.app.model.OppiaMetricLog.LoggableMetric.LoggableMetricTypeCase.MEMORY_USAGE_METRIC
+import org.oppia.android.app.model.OppiaMetricLog.LoggableMetric.LoggableMetricTypeCase.NETWORK_USAGE_METRIC
+import org.oppia.android.app.model.OppiaMetricLog.LoggableMetric.LoggableMetricTypeCase.STARTUP_LATENCY_METRIC
+import org.oppia.android.app.model.OppiaMetricLog.LoggableMetric.LoggableMetricTypeCase.STORAGE_USAGE_METRIC
+import org.oppia.android.app.model.OppiaMetricLog.Priority.HIGH_PRIORITY
+import org.oppia.android.app.model.OppiaMetricLog.Priority.LOW_PRIORITY
+import org.oppia.android.app.model.OppiaMetricLog.Priority.MEDIUM_PRIORITY
+import org.oppia.android.domain.oppialogger.EventLogStorageCacheSize
+import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
+import org.oppia.android.domain.oppialogger.PerformanceMetricsLogStorageCacheSize
+import org.oppia.android.domain.platformparameter.PlatformParameterModule
+import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
+import org.oppia.android.testing.FakePerformanceMetricAssessor
+import org.oppia.android.testing.FakePerformanceMetricsEventLogger
+import org.oppia.android.testing.TestLogReportingModule
+import org.oppia.android.testing.logging.SyncStatusTestModule
+import org.oppia.android.testing.robolectric.RobolectricModule
+import org.oppia.android.testing.threading.TestDispatcherModule
+import org.oppia.android.testing.time.FakeOppiaClock
+import org.oppia.android.testing.time.FakeOppiaClockModule
+import org.oppia.android.util.data.DataProvidersInjector
+import org.oppia.android.util.data.DataProvidersInjectorProvider
+import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EnableConsoleLog
+import org.oppia.android.util.logging.EnableFileLog
+import org.oppia.android.util.logging.GlobalLogLevel
+import org.oppia.android.util.logging.LogLevel
+import org.oppia.android.util.logging.performancemetrics.PerformanceMetricsAssessor
+import org.oppia.android.util.networking.NetworkConnectionUtilDebugModule
+import org.robolectric.annotation.Config
+import org.robolectric.annotation.LooperMode
+import javax.inject.Inject
+import javax.inject.Singleton
+
+private const val TEST_TIMESTAMP = Long.MAX_VALUE
+private const val TEST_CPU_USAGE = Long.MAX_VALUE
+private const val TEST_APK_SIZE = Long.MAX_VALUE
+private const val TEST_STORAGE_USAGE = Long.MAX_VALUE
+private const val TEST_TOTAL_PSS = Long.MAX_VALUE
+private const val TEST_BYTES_SENT = Long.MAX_VALUE
+private const val TEST_BYTES_RECEIVED = Long.MAX_VALUE
+
+/** Tests for [PerformanceMetricsLoggerTest]. */
+// FunctionName: test names are conventionally named with underscores.
+@Suppress("FunctionName")
+@RunWith(AndroidJUnit4::class)
+@LooperMode(LooperMode.Mode.PAUSED)
+@Config(application = PerformanceMetricsLoggerTest.TestApplication::class)
+class PerformanceMetricsLoggerTest {
+
+ @Inject
+ lateinit var performanceMetricsLogger: PerformanceMetricsLogger
+
+ @Inject
+ lateinit var performanceMetricsController: PerformanceMetricsController
+
+ @Inject
+ lateinit var fakePerformanceMetricsEventLogger: FakePerformanceMetricsEventLogger
+
+ @Inject
+ lateinit var fakeOppiaClock: FakeOppiaClock
+
+ @Inject
+ lateinit var fakePerformanceMetricAssessor: FakePerformanceMetricAssessor
+
+ @Mock
+ lateinit var context: Context
+
+ private val testDeviceStorageTier = OppiaMetricLog.StorageTier.MEDIUM_STORAGE
+ private val testDeviceMemoryTier = OppiaMetricLog.MemoryTier.MEDIUM_MEMORY_TIER
+
+ @Before
+ fun setUp() {
+ setUpTestApplicationComponent()
+ setUpFakePerformanceMetricsUtils()
+ fakeOppiaClock.setFakeTimeMode(FakeOppiaClock.FakeTimeMode.MODE_FIXED_FAKE_TIME)
+ fakeOppiaClock.setCurrentTimeMs(TEST_TIMESTAMP)
+ }
+
+ @Test
+ fun testLogger_logApkSizePerformanceMetric_verifyLogsMetricCorrectly() {
+ val apkSize = fakePerformanceMetricAssessor.getApkSize()
+ val memoryTier = fakePerformanceMetricAssessor.getDeviceMemoryTier()
+ val storageTier = fakePerformanceMetricAssessor.getDeviceStorageTier()
+ val isAppInForeground = performanceMetricsController.getIsAppInForeground()
+ performanceMetricsLogger.logApkSize(HOME_SCREEN)
+
+ val loggedEvent = fakePerformanceMetricsEventLogger.getMostRecentPerformanceMetricsEvent()
+ assertThat(loggedEvent.timestampMillis).isEqualTo(TEST_TIMESTAMP)
+ assertThat(loggedEvent.priority).isEqualTo(LOW_PRIORITY)
+ assertThat(loggedEvent.currentScreen).isEqualTo(HOME_SCREEN)
+ assertThat(loggedEvent.loggableMetric.loggableMetricTypeCase).isEqualTo(APK_SIZE_METRIC)
+ assertThat(loggedEvent.loggableMetric.apkSizeMetric.apkSizeBytes).isEqualTo(apkSize)
+ assertThat(loggedEvent.memoryTier).isEqualTo(memoryTier)
+ assertThat(loggedEvent.storageTier).isEqualTo(storageTier)
+ assertThat(loggedEvent.isAppInForeground).isEqualTo(isAppInForeground)
+ }
+
+ @Test
+ fun testLogger_logStorageUsagePerformanceMetric_verifyLogsMetricCorrectly() {
+ val memoryTier = fakePerformanceMetricAssessor.getDeviceMemoryTier()
+ val storageTier = fakePerformanceMetricAssessor.getDeviceStorageTier()
+ val isAppInForeground = performanceMetricsController.getIsAppInForeground()
+ val storageUsage = fakePerformanceMetricAssessor.getUsedStorage()
+ performanceMetricsLogger.logStorageUsage(HOME_SCREEN)
+
+ val loggedEvent = fakePerformanceMetricsEventLogger.getMostRecentPerformanceMetricsEvent()
+ assertThat(loggedEvent.timestampMillis).isEqualTo(TEST_TIMESTAMP)
+ assertThat(loggedEvent.priority).isEqualTo(LOW_PRIORITY)
+ assertThat(loggedEvent.currentScreen).isEqualTo(HOME_SCREEN)
+ assertThat(loggedEvent.loggableMetric.loggableMetricTypeCase).isEqualTo(STORAGE_USAGE_METRIC)
+ assertThat(loggedEvent.loggableMetric.storageUsageMetric.storageUsageBytes).isEqualTo(
+ storageUsage
+ )
+ assertThat(loggedEvent.memoryTier).isEqualTo(memoryTier)
+ assertThat(loggedEvent.storageTier).isEqualTo(storageTier)
+ assertThat(loggedEvent.isAppInForeground).isEqualTo(isAppInForeground)
+ }
+
+ @Test
+ fun testLogger_logMemoryUsagePerformanceMetric_verifyLogsMetricCorrectly() {
+ val memoryUsage = fakePerformanceMetricAssessor.getTotalPssUsed()
+ val memoryTier = fakePerformanceMetricAssessor.getDeviceMemoryTier()
+ val storageTier = fakePerformanceMetricAssessor.getDeviceStorageTier()
+ val isAppInForeground = performanceMetricsController.getIsAppInForeground()
+ performanceMetricsLogger.logMemoryUsage(SCREEN_UNSPECIFIED)
+
+ val loggedEvent = fakePerformanceMetricsEventLogger.getMostRecentPerformanceMetricsEvent()
+ assertThat(loggedEvent.timestampMillis).isEqualTo(TEST_TIMESTAMP)
+ assertThat(loggedEvent.priority).isEqualTo(MEDIUM_PRIORITY)
+ assertThat(loggedEvent.currentScreen).isEqualTo(SCREEN_UNSPECIFIED)
+ assertThat(loggedEvent.loggableMetric.loggableMetricTypeCase).isEqualTo(MEMORY_USAGE_METRIC)
+ assertThat(loggedEvent.loggableMetric.memoryUsageMetric.totalPssBytes).isEqualTo(memoryUsage)
+ assertThat(loggedEvent.memoryTier).isEqualTo(memoryTier)
+ assertThat(loggedEvent.storageTier).isEqualTo(storageTier)
+ assertThat(loggedEvent.isAppInForeground).isEqualTo(isAppInForeground)
+ }
+
+ @Test
+ fun testLogger_logStartupLatencyPerformanceMetric_verifyLogsMetricCorrectly() {
+ val memoryTier = fakePerformanceMetricAssessor.getDeviceMemoryTier()
+ val storageTier = fakePerformanceMetricAssessor.getDeviceStorageTier()
+ val isAppInForeground = performanceMetricsController.getIsAppInForeground()
+ performanceMetricsLogger.logStartupLatency(HOME_SCREEN)
+
+ val loggedEvent = fakePerformanceMetricsEventLogger.getMostRecentPerformanceMetricsEvent()
+ assertThat(loggedEvent.timestampMillis).isEqualTo(TEST_TIMESTAMP)
+ assertThat(loggedEvent.priority).isEqualTo(LOW_PRIORITY)
+ assertThat(loggedEvent.currentScreen).isEqualTo(HOME_SCREEN)
+ assertThat(loggedEvent.loggableMetric.loggableMetricTypeCase).isEqualTo(STARTUP_LATENCY_METRIC)
+ // Startup latency millis will be equal to 0 since the initial timestamp is equal to
+ // Long.MAX_VALUE and using FakeOppiaClock we've set the recording timestamp to also be
+ // Long.MAX_VALUE. The difference between the two equals 0 and hence the startup latency millis.
+ assertThat(loggedEvent.loggableMetric.startupLatencyMetric.startupLatencyMillis).isEqualTo(0)
+ assertThat(loggedEvent.memoryTier).isEqualTo(memoryTier)
+ assertThat(loggedEvent.storageTier).isEqualTo(storageTier)
+ assertThat(loggedEvent.isAppInForeground).isEqualTo(isAppInForeground)
+ }
+
+ @Test
+ fun testLogger_logCpuUsagePerformanceMetric_verifyLogsMetricCorrectly() {
+ val memoryTier = fakePerformanceMetricAssessor.getDeviceMemoryTier()
+ val storageTier = fakePerformanceMetricAssessor.getDeviceStorageTier()
+ val isAppInForeground = performanceMetricsController.getIsAppInForeground()
+ performanceMetricsLogger.logCpuUsage(TEST_CPU_USAGE, SCREEN_UNSPECIFIED)
+
+ val loggedEvent = fakePerformanceMetricsEventLogger.getMostRecentPerformanceMetricsEvent()
+ assertThat(loggedEvent.timestampMillis).isEqualTo(TEST_TIMESTAMP)
+ assertThat(loggedEvent.priority).isEqualTo(HIGH_PRIORITY)
+ assertThat(loggedEvent.currentScreen).isEqualTo(SCREEN_UNSPECIFIED)
+ assertThat(loggedEvent.loggableMetric.loggableMetricTypeCase).isEqualTo(CPU_USAGE_METRIC)
+ assertThat(loggedEvent.loggableMetric.cpuUsageMetric.cpuUsageMetric).isEqualTo(TEST_CPU_USAGE)
+ assertThat(loggedEvent.memoryTier).isEqualTo(memoryTier)
+ assertThat(loggedEvent.storageTier).isEqualTo(storageTier)
+ assertThat(loggedEvent.isAppInForeground).isEqualTo(isAppInForeground)
+ }
+
+ @Test
+ fun testLogger_logNetworkUsagePerformanceMetric_verifyLogsMetricCorrectly() {
+ val bytesSent = fakePerformanceMetricAssessor.getTotalSentBytes()
+ val bytesReceived = fakePerformanceMetricAssessor.getTotalReceivedBytes()
+ val memoryTier = fakePerformanceMetricAssessor.getDeviceMemoryTier()
+ val storageTier = fakePerformanceMetricAssessor.getDeviceStorageTier()
+ val isAppInForeground = performanceMetricsController.getIsAppInForeground()
+ performanceMetricsLogger.logNetworkUsage(SCREEN_UNSPECIFIED)
+
+ val loggedEvent = fakePerformanceMetricsEventLogger.getMostRecentPerformanceMetricsEvent()
+ assertThat(loggedEvent.timestampMillis).isEqualTo(TEST_TIMESTAMP)
+ assertThat(loggedEvent.priority).isEqualTo(HIGH_PRIORITY)
+ assertThat(loggedEvent.currentScreen).isEqualTo(SCREEN_UNSPECIFIED)
+ assertThat(loggedEvent.loggableMetric.loggableMetricTypeCase).isEqualTo(NETWORK_USAGE_METRIC)
+ assertThat(loggedEvent.loggableMetric.networkUsageMetric.bytesSent).isEqualTo(bytesSent)
+ assertThat(loggedEvent.loggableMetric.networkUsageMetric.bytesReceived).isEqualTo(bytesReceived)
+ assertThat(loggedEvent.memoryTier).isEqualTo(memoryTier)
+ assertThat(loggedEvent.storageTier).isEqualTo(storageTier)
+ assertThat(loggedEvent.isAppInForeground).isEqualTo(isAppInForeground)
+ }
+
+ private fun setUpTestApplicationComponent() {
+ ApplicationProvider.getApplicationContext().inject(this)
+ }
+
+ private fun setUpFakePerformanceMetricsUtils() {
+ fakePerformanceMetricAssessor.apply {
+ setApkSize(TEST_APK_SIZE)
+ setStorageUsage(TEST_STORAGE_USAGE)
+ setTotalPss(TEST_TOTAL_PSS)
+ setTotalSentBytes(TEST_BYTES_SENT)
+ setTotalReceivedBytes(TEST_BYTES_RECEIVED)
+ setDeviceStorageTier(testDeviceStorageTier)
+ setDeviceMemoryTier(testDeviceMemoryTier)
+ }
+ }
+
+ // TODO(#89): Move this to a common test application component.
+ @Module
+ class TestModule {
+ @Provides
+ @Singleton
+ fun provideContext(application: Application): Context {
+ return application
+ }
+
+ // TODO(#59): Either isolate these to their own shared test module, or use the real logging
+ // module in tests to avoid needing to specify these settings for tests.
+ @EnableConsoleLog
+ @Provides
+ fun provideEnableConsoleLog(): Boolean = true
+
+ @EnableFileLog
+ @Provides
+ fun provideEnableFileLog(): Boolean = false
+
+ @GlobalLogLevel
+ @Provides
+ fun provideGlobalLogLevel(): LogLevel = LogLevel.VERBOSE
+ }
+
+ @Module
+ class TestLogStorageModule {
+
+ @Provides
+ @PerformanceMetricsLogStorageCacheSize
+ fun providePerformanceMetricsLogStorageCacheSize(): Int = 2
+
+ @Provides
+ @EventLogStorageCacheSize
+ fun provideEventLogStorageCacheSize(): Int = 2
+ }
+
+ @Module
+ interface TestPerformanceMetricsModule {
+ @Binds
+ fun bindPerformanceMetricsUtils(
+ fakePerformanceMetricAssessor: FakePerformanceMetricAssessor
+ ): PerformanceMetricsAssessor
+ }
+
+ // TODO(#89): Move this to a common test application component.
+ @Singleton
+ @Component(
+ modules = [
+ TestModule::class, TestLogReportingModule::class, RobolectricModule::class,
+ TestDispatcherModule::class, TestLogStorageModule::class,
+ NetworkConnectionUtilDebugModule::class, LocaleProdModule::class, FakeOppiaClockModule::class,
+ PlatformParameterModule::class, PlatformParameterSingletonModule::class,
+ LoggingIdentifierModule::class, SyncStatusTestModule::class
+ ]
+ )
+ interface TestApplicationComponent : DataProvidersInjector {
+ @Component.Builder
+ interface Builder {
+ @BindsInstance
+ fun setApplication(application: Application): Builder
+ fun build(): TestApplicationComponent
+ }
+
+ fun inject(performanceMetricsLoggerTest: PerformanceMetricsLoggerTest)
+ }
+
+ class TestApplication : Application(), DataProvidersInjectorProvider {
+ private val component: TestApplicationComponent by lazy {
+ DaggerPerformanceMetricsLoggerTest_TestApplicationComponent.builder()
+ .setApplication(this)
+ .build()
+ }
+
+ fun inject(performanceMetricsLoggerTest: PerformanceMetricsLoggerTest) {
+ component.inject(performanceMetricsLoggerTest)
+ }
+
+ override fun getDataProvidersInjector(): DataProvidersInjector = component
+ }
+}
diff --git a/domain/src/test/java/org/oppia/android/domain/oppialogger/analytics/testing/FakeLogSchedulerTest.kt b/domain/src/test/java/org/oppia/android/domain/oppialogger/analytics/testing/FakeLogSchedulerTest.kt
new file mode 100644
index 00000000000..f0be27177ef
--- /dev/null
+++ b/domain/src/test/java/org/oppia/android/domain/oppialogger/analytics/testing/FakeLogSchedulerTest.kt
@@ -0,0 +1,182 @@
+package org.oppia.android.domain.oppialogger.analytics.testing
+
+import android.app.Application
+import android.content.Context
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.work.Configuration
+import androidx.work.Data
+import androidx.work.PeriodicWorkRequestBuilder
+import androidx.work.WorkManager
+import androidx.work.testing.SynchronousExecutor
+import androidx.work.testing.WorkManagerTestInitHelper
+import com.google.common.truth.Truth.assertThat
+import dagger.Binds
+import dagger.BindsInstance
+import dagger.Component
+import dagger.Module
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulingWorker
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulingWorkerFactory
+import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorker
+import org.oppia.android.testing.robolectric.RobolectricModule
+import org.oppia.android.testing.threading.TestDispatcherModule
+import org.oppia.android.util.data.DataProvidersInjector
+import org.oppia.android.util.data.DataProvidersInjectorProvider
+import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.LoggerModule
+import org.oppia.android.util.logging.MetricLogScheduler
+import org.oppia.android.util.logging.firebase.LogReportingModule
+import org.oppia.android.util.logging.performancemetrics.PerformanceMetricsAssessorModule
+import org.oppia.android.util.logging.performancemetrics.PerformanceMetricsConfigurationsModule
+import org.oppia.android.util.system.OppiaClockModule
+import org.robolectric.annotation.Config
+import org.robolectric.annotation.LooperMode
+import java.util.concurrent.TimeUnit
+import javax.inject.Inject
+import javax.inject.Singleton
+
+/** Tests for [FakeLogScheduler]. */
+// FunctionName: test names are conventionally named with underscores.
+@Suppress("FunctionName")
+@RunWith(AndroidJUnit4::class)
+@LooperMode(LooperMode.Mode.PAUSED)
+@Config(application = FakeLogSchedulerTest.TestApplication::class)
+class FakeLogSchedulerTest {
+
+ @Inject
+ lateinit var fakeLogScheduler: FakeLogScheduler
+
+ @Inject
+ lateinit var workerFactory: MetricLogSchedulingWorkerFactory
+
+ @Inject
+ lateinit var context: Context
+
+ @Before
+ fun setUp() {
+ setUpTestApplicationComponent()
+ val config = Configuration.Builder()
+ .setExecutor(SynchronousExecutor())
+ .setWorkerFactory(workerFactory)
+ .build()
+ WorkManagerTestInitHelper.initializeTestWorkManager(context, config)
+ }
+
+ @Test
+ fun testFakeScheduler_scheduleStorageLogging_verifyScheduling() {
+ val workManager = WorkManager.getInstance(context)
+
+ val inputData = Data.Builder().putString(
+ MetricLogSchedulingWorker.WORKER_CASE_KEY,
+ MetricLogSchedulingWorker.STORAGE_USAGE_WORKER
+ ).build()
+
+ val request = PeriodicWorkRequestBuilder(10, TimeUnit.SECONDS)
+ .setInputData(inputData)
+ .build()
+
+ fakeLogScheduler.enqueueWorkRequestForStorageUsage(
+ workManager,
+ request
+ )
+
+ assertThat(fakeLogScheduler.getMostRecentStorageUsageMetricLoggingRequestId())
+ .isEqualTo(request.id)
+ }
+
+ @Test
+ fun testFakeScheduler_schedulePeriodicBackgroundMetricsLogging_verifyScheduling() {
+ val workManager = WorkManager.getInstance(context)
+
+ val inputData = Data.Builder().putString(
+ MetricLogSchedulingWorker.WORKER_CASE_KEY,
+ MetricLogSchedulingWorker.PERIODIC_BACKGROUND_METRIC_WORKER
+ ).build()
+
+ val request = PeriodicWorkRequestBuilder(10, TimeUnit.SECONDS)
+ .setInputData(inputData)
+ .build()
+
+ fakeLogScheduler.enqueueWorkRequestForPeriodicBackgroundMetrics(
+ workManager,
+ request
+ )
+
+ assertThat(fakeLogScheduler.getMostRecentPeriodicBackgroundMetricLoggingRequestId())
+ .isEqualTo(request.id)
+ }
+
+ @Test
+ fun testFakeScheduler_schedulePeriodicUiMetricsLogging_verifyScheduling() {
+ val workManager = WorkManager.getInstance(context)
+
+ val inputData = Data.Builder().putString(
+ MetricLogSchedulingWorker.WORKER_CASE_KEY,
+ MetricLogSchedulingWorker.PERIODIC_UI_METRIC_WORKER
+ ).build()
+
+ val request = PeriodicWorkRequestBuilder(10, TimeUnit.SECONDS)
+ .setInputData(inputData)
+ .build()
+
+ fakeLogScheduler.enqueueWorkRequestForPeriodicUiMetrics(
+ workManager,
+ request
+ )
+
+ assertThat(fakeLogScheduler.getMostRecentPeriodicUiMetricLoggingRequestId())
+ .isEqualTo(request.id)
+ }
+
+ private fun setUpTestApplicationComponent() {
+ ApplicationProvider.getApplicationContext().inject(this)
+ }
+
+ // TODO(#89): Move this to a common test application component.
+ @Module
+ interface TestModule {
+ @Binds
+ fun provideContext(application: Application): Context
+
+ @Binds
+ fun bindMetricLogScheduler(fakeLogScheduler: FakeLogScheduler): MetricLogScheduler
+ }
+
+ // TODO(#89): Move this to a common test application component.
+ @Singleton
+ @Component(
+ modules = [
+ TestModule::class, PerformanceMetricsAssessorModule::class, LoggerModule::class,
+ TestDispatcherModule::class, LogReportingModule::class, RobolectricModule::class,
+ PerformanceMetricsConfigurationsModule::class, LocaleProdModule::class,
+ OppiaClockModule::class
+ ]
+ )
+ interface TestApplicationComponent : DataProvidersInjector {
+ @Component.Builder
+ interface Builder {
+ @BindsInstance
+ fun setApplication(application: Application): Builder
+ fun build(): TestApplicationComponent
+ }
+
+ fun inject(test: FakeLogSchedulerTest)
+ }
+
+ class TestApplication : Application(), DataProvidersInjectorProvider {
+ private val component: TestApplicationComponent by lazy {
+ DaggerFakeLogSchedulerTest_TestApplicationComponent.builder()
+ .setApplication(this)
+ .build()
+ }
+
+ fun inject(test: FakeLogSchedulerTest) {
+ component.inject(test)
+ }
+
+ override fun getDataProvidersInjector(): DataProvidersInjector = component
+ }
+}
diff --git a/domain/src/test/java/org/oppia/android/domain/oppialogger/logscheduler/MetricLogSchedulerModuleTest.kt b/domain/src/test/java/org/oppia/android/domain/oppialogger/logscheduler/MetricLogSchedulerModuleTest.kt
new file mode 100644
index 00000000000..ac65b6d1c92
--- /dev/null
+++ b/domain/src/test/java/org/oppia/android/domain/oppialogger/logscheduler/MetricLogSchedulerModuleTest.kt
@@ -0,0 +1,79 @@
+package org.oppia.android.domain.oppialogger.logscheduler
+
+import android.app.Application
+import android.content.Context
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.google.common.truth.Truth.assertThat
+import dagger.Binds
+import dagger.BindsInstance
+import dagger.Component
+import dagger.Module
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.oppia.android.testing.robolectric.RobolectricModule
+import org.oppia.android.testing.time.FakeOppiaClockModule
+import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.LoggerModule
+import org.oppia.android.util.logging.MetricLogScheduler
+import org.robolectric.annotation.Config
+import org.robolectric.annotation.LooperMode
+import javax.inject.Inject
+import javax.inject.Singleton
+
+/** Tests for [MetricLogSchedulerModule]. */
+// FunctionName: test names are conventionally named with underscores.
+@Suppress("FunctionName")
+@RunWith(AndroidJUnit4::class)
+@LooperMode(LooperMode.Mode.PAUSED)
+@Config(manifest = Config.NONE)
+class MetricLogSchedulerModuleTest {
+
+ @Inject
+ lateinit var metricLogScheduler: MetricLogScheduler
+
+ @Before
+ fun setUp() {
+ setUpTestApplicationComponent()
+ }
+
+ @Test
+ fun testModule_injectsProductionImplementationOfMetricLogScheduler() {
+ assertThat(metricLogScheduler).isInstanceOf(PerformanceMetricsLogScheduler::class.java)
+ }
+
+ private fun setUpTestApplicationComponent() {
+ DaggerMetricLogSchedulerModuleTest_TestApplicationComponent.builder()
+ .setApplication(ApplicationProvider.getApplicationContext())
+ .build()
+ .inject(this)
+ }
+
+ // TODO(#89): Move this to a common test application component.
+ @Module
+ interface TestModule {
+ @Binds
+ fun provideContext(application: Application): Context
+ }
+
+ // TODO(#89): Move this to a common test application component.
+ @Singleton
+ @Component(
+ modules = [
+ TestModule::class, MetricLogSchedulerModule::class, LoggerModule::class,
+ RobolectricModule::class, LocaleProdModule::class, FakeOppiaClockModule::class
+ ]
+ )
+ interface TestApplicationComponent {
+ @Component.Builder
+ interface Builder {
+ @BindsInstance
+ fun setApplication(application: Application): Builder
+
+ fun build(): TestApplicationComponent
+ }
+
+ fun inject(metricLogSchedulerModuleTest: MetricLogSchedulerModuleTest)
+ }
+}
diff --git a/domain/src/test/java/org/oppia/android/domain/oppialogger/logscheduler/MetricLogSchedulingWorkerTest.kt b/domain/src/test/java/org/oppia/android/domain/oppialogger/logscheduler/MetricLogSchedulingWorkerTest.kt
new file mode 100644
index 00000000000..57c32579979
--- /dev/null
+++ b/domain/src/test/java/org/oppia/android/domain/oppialogger/logscheduler/MetricLogSchedulingWorkerTest.kt
@@ -0,0 +1,292 @@
+package org.oppia.android.domain.oppialogger.logscheduler
+
+import android.app.Application
+import android.content.Context
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.work.Configuration
+import androidx.work.Data
+import androidx.work.OneTimeWorkRequest
+import androidx.work.OneTimeWorkRequestBuilder
+import androidx.work.WorkInfo
+import androidx.work.WorkManager
+import androidx.work.testing.SynchronousExecutor
+import androidx.work.testing.WorkManagerTestInitHelper
+import com.google.common.truth.Truth.assertThat
+import dagger.Binds
+import dagger.BindsInstance
+import dagger.Component
+import dagger.Module
+import dagger.Provides
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.oppia.android.domain.oppialogger.EventLogStorageCacheSize
+import org.oppia.android.domain.oppialogger.ExceptionLogStorageCacheSize
+import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
+import org.oppia.android.domain.oppialogger.OppiaLogger
+import org.oppia.android.domain.oppialogger.PerformanceMetricsLogStorageCacheSize
+import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
+import org.oppia.android.domain.oppialogger.analytics.PerformanceMetricsController
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorker
+import org.oppia.android.domain.platformparameter.PlatformParameterModule
+import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
+import org.oppia.android.domain.testing.oppialogger.loguploader.FakeLogUploader
+import org.oppia.android.testing.FakeEventLogger
+import org.oppia.android.testing.FakeExceptionLogger
+import org.oppia.android.testing.FakePerformanceMetricsEventLogger
+import org.oppia.android.testing.logging.SyncStatusTestModule
+import org.oppia.android.testing.robolectric.RobolectricModule
+import org.oppia.android.testing.threading.TestCoroutineDispatchers
+import org.oppia.android.testing.threading.TestDispatcherModule
+import org.oppia.android.testing.time.FakeOppiaClockModule
+import org.oppia.android.util.caching.AssetModule
+import org.oppia.android.util.data.DataProviders
+import org.oppia.android.util.data.DataProvidersInjector
+import org.oppia.android.util.data.DataProvidersInjectorProvider
+import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLogger
+import org.oppia.android.util.logging.ExceptionLogger
+import org.oppia.android.util.logging.LogUploader
+import org.oppia.android.util.logging.LoggerModule
+import org.oppia.android.util.logging.performancemetrics.PerformanceMetricsAssessorModule
+import org.oppia.android.util.logging.performancemetrics.PerformanceMetricsConfigurationsModule
+import org.oppia.android.util.logging.performancemetrics.PerformanceMetricsEventLogger
+import org.oppia.android.util.networking.NetworkConnectionDebugUtil
+import org.oppia.android.util.networking.NetworkConnectionUtilDebugModule
+import org.robolectric.annotation.Config
+import org.robolectric.annotation.LooperMode
+import javax.inject.Inject
+import javax.inject.Singleton
+
+private const val INCORRECT_WORKER_CASE = "incorrect_worker_case"
+
+/** Tests for [MetricLogSchedulingWorker]. */
+// FunctionName: test names are conventionally named with underscores.
+@Suppress("FunctionName")
+@RunWith(AndroidJUnit4::class)
+@LooperMode(LooperMode.Mode.PAUSED)
+@Config(application = MetricLogSchedulingWorkerTest.TestApplication::class)
+class MetricLogSchedulingWorkerTest {
+ @Inject
+ lateinit var networkConnectionUtil: NetworkConnectionDebugUtil
+
+ @Inject
+ lateinit var fakePerformanceMetricsEventLogger: FakePerformanceMetricsEventLogger
+
+ @Inject
+ lateinit var oppiaLogger: OppiaLogger
+
+ @Inject
+ lateinit var performanceMetricsController: PerformanceMetricsController
+
+ @Inject
+ lateinit var metricLogSchedulingWorkerFactory: MetricLogSchedulingWorkerFactory
+
+ @Inject
+ lateinit var dataProviders: DataProviders
+
+ @Inject
+ lateinit var testCoroutineDispatchers: TestCoroutineDispatchers
+
+ private lateinit var context: Context
+
+ @Before
+ fun setUp() {
+ setUpTestApplicationComponent()
+ context = InstrumentationRegistry.getInstrumentation().targetContext
+ val config = Configuration.Builder()
+ .setExecutor(SynchronousExecutor())
+ .setWorkerFactory(metricLogSchedulingWorkerFactory)
+ .build()
+ WorkManagerTestInitHelper.initializeTestWorkManager(context, config)
+ }
+
+ @Test
+ fun testWorker_enqueueRequest_verifyStorageUsagePerformanceMetricLogging() {
+ val workManager = WorkManager.getInstance(ApplicationProvider.getApplicationContext())
+
+ val inputData = Data.Builder().putString(
+ MetricLogSchedulingWorker.WORKER_CASE_KEY,
+ MetricLogSchedulingWorker.STORAGE_USAGE_WORKER
+ ).build()
+
+ val request: OneTimeWorkRequest = OneTimeWorkRequestBuilder()
+ .setInputData(inputData)
+ .build()
+
+ workManager.enqueue(request)
+ testCoroutineDispatchers.runCurrent()
+ val workInfo = workManager.getWorkInfoById(request.id)
+
+ assertThat(workInfo.get().state).isEqualTo(WorkInfo.State.SUCCEEDED)
+ // TODO(#4340): Verify functionality to log storage usage performance metrics.
+ }
+
+ @Test
+ fun testWorker_enqueueRequest_verifyPeriodicBackgroundPerformanceMetricsLogging() {
+ val workManager = WorkManager.getInstance(ApplicationProvider.getApplicationContext())
+
+ val inputData = Data.Builder().putString(
+ MetricLogSchedulingWorker.WORKER_CASE_KEY,
+ MetricLogSchedulingWorker.PERIODIC_BACKGROUND_METRIC_WORKER
+ ).build()
+
+ val request: OneTimeWorkRequest = OneTimeWorkRequestBuilder()
+ .setInputData(inputData)
+ .build()
+
+ workManager.enqueue(request)
+ testCoroutineDispatchers.runCurrent()
+ val workInfo = workManager.getWorkInfoById(request.id)
+
+ assertThat(workInfo.get().state).isEqualTo(WorkInfo.State.SUCCEEDED)
+ // TODO(#4340): Verify functionality to log cpu and network usage performance metrics.
+ }
+
+ @Test
+ fun testWorker_enqueueRequest_verifyPeriodicUiPerformanceMetricsLogging() {
+ val workManager = WorkManager.getInstance(ApplicationProvider.getApplicationContext())
+
+ val inputData = Data.Builder().putString(
+ MetricLogSchedulingWorker.WORKER_CASE_KEY,
+ MetricLogSchedulingWorker.PERIODIC_UI_METRIC_WORKER
+ ).build()
+
+ val request: OneTimeWorkRequest = OneTimeWorkRequestBuilder()
+ .setInputData(inputData)
+ .build()
+
+ workManager.enqueue(request)
+ testCoroutineDispatchers.runCurrent()
+ val workInfo = workManager.getWorkInfoById(request.id)
+
+ assertThat(workInfo.get().state).isEqualTo(WorkInfo.State.SUCCEEDED)
+ // TODO(#4340): Verify functionality to log memory usage performance metrics.
+ }
+
+ @Test
+ fun testWorker_enqueueRequest_writeFails_verifyFailure() {
+ val workManager = WorkManager.getInstance(ApplicationProvider.getApplicationContext())
+
+ val request: OneTimeWorkRequest = OneTimeWorkRequestBuilder()
+ .build()
+
+ workManager.enqueue(request)
+ testCoroutineDispatchers.runCurrent()
+ val workInfo = workManager.getWorkInfoById(request.id)
+
+ assertThat(workInfo.get().state).isEqualTo(WorkInfo.State.FAILED)
+ assertThat(fakePerformanceMetricsEventLogger.noPerformanceMetricsEventsPresent()).isTrue()
+ }
+
+ @Test
+ fun testScheduler_enqueueRequestForIncorrectWorkerCase_verifyWorkRequestReturnsFailureResult() {
+ val workManager = WorkManager.getInstance(ApplicationProvider.getApplicationContext())
+
+ val inputData: Data = Data.Builder()
+ .putString(
+ MetricLogSchedulingWorker.WORKER_CASE_KEY,
+ INCORRECT_WORKER_CASE
+ ).build()
+
+ val request = OneTimeWorkRequestBuilder()
+ .setInputData(inputData)
+ .build()
+
+ workManager.enqueue(request)
+ testCoroutineDispatchers.runCurrent()
+ val workInfo = workManager.getWorkInfoById(request.id)
+
+ assertThat(workInfo.get().state).isEqualTo(WorkInfo.State.FAILED)
+ }
+
+ private fun setUpTestApplicationComponent() {
+ DaggerMetricLogSchedulingWorkerTest_TestApplicationComponent.builder()
+ .setApplication(ApplicationProvider.getApplicationContext())
+ .build()
+ .inject(this)
+ }
+
+ // TODO(#89): Move this to a common test application component.
+ @Module
+ class TestModule {
+ @Provides
+ fun provideContext(application: Application): Context = application
+
+ @Provides
+ fun bindFakeEventLogger(fakeEventLogger: FakeEventLogger): EventLogger = fakeEventLogger
+
+ @Provides
+ fun bindFakeExceptionLogger(fakeLogger: FakeExceptionLogger): ExceptionLogger = fakeLogger
+
+ @Provides
+ fun bindFakePerformanceMetricsEventLogger(
+ fakePerformanceMetricsEventLogger: FakePerformanceMetricsEventLogger
+ ): PerformanceMetricsEventLogger = fakePerformanceMetricsEventLogger
+ }
+
+ @Module
+ class TestLogStorageModule {
+
+ @Provides
+ @EventLogStorageCacheSize
+ fun provideEventLogStorageCacheSize(): Int = 2
+
+ @Provides
+ @ExceptionLogStorageCacheSize
+ fun provideExceptionLogStorageSize(): Int = 2
+
+ @Provides
+ @PerformanceMetricsLogStorageCacheSize
+ fun providePerformanceMetricsLogStorageCacheSize(): Int = 2
+ }
+
+ @Module
+ interface TestFirebaseLogUploaderModule {
+
+ @Binds
+ fun bindsFakeLogUploader(fakeLogUploader: FakeLogUploader): LogUploader
+ }
+
+ // TODO(#89): Move this to a common test application component.
+ @Singleton
+ @Component(
+ modules = [
+ TestModule::class, RobolectricModule::class, TestLogStorageModule::class,
+ TestDispatcherModule::class, LogReportWorkerModule::class,
+ TestFirebaseLogUploaderModule::class, FakeOppiaClockModule::class,
+ NetworkConnectionUtilDebugModule::class, LocaleProdModule::class, LoggerModule::class,
+ AssetModule::class, PlatformParameterModule::class, PlatformParameterSingletonModule::class,
+ LoggingIdentifierModule::class, SyncStatusTestModule::class,
+ PerformanceMetricsAssessorModule::class, PerformanceMetricsConfigurationsModule::class,
+ ApplicationLifecycleModule::class
+ ]
+ )
+ interface TestApplicationComponent : DataProvidersInjector {
+ @Component.Builder
+ interface Builder {
+ @BindsInstance
+ fun setApplication(application: Application): Builder
+ fun build(): TestApplicationComponent
+ }
+
+ fun inject(metricLogSchedulingWorkerTest: MetricLogSchedulingWorkerTest)
+ }
+
+ class TestApplication : Application(), DataProvidersInjectorProvider {
+ private val component: TestApplicationComponent by lazy {
+ DaggerMetricLogSchedulingWorkerTest_TestApplicationComponent.builder()
+ .setApplication(this)
+ .build()
+ }
+
+ fun inject(metricLogSchedulingWorkerTest: MetricLogSchedulingWorkerTest) {
+ component.inject(metricLogSchedulingWorkerTest)
+ }
+
+ override fun getDataProvidersInjector(): DataProvidersInjector = component
+ }
+}
diff --git a/domain/src/test/java/org/oppia/android/domain/oppialogger/logscheduler/PerformanceMetricsLogSchedulerTest.kt b/domain/src/test/java/org/oppia/android/domain/oppialogger/logscheduler/PerformanceMetricsLogSchedulerTest.kt
new file mode 100644
index 00000000000..7d8985f71b2
--- /dev/null
+++ b/domain/src/test/java/org/oppia/android/domain/oppialogger/logscheduler/PerformanceMetricsLogSchedulerTest.kt
@@ -0,0 +1,205 @@
+package org.oppia.android.domain.oppialogger.logscheduler
+
+import android.app.Application
+import android.content.Context
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.work.Configuration
+import androidx.work.Data
+import androidx.work.PeriodicWorkRequest
+import androidx.work.WorkInfo
+import androidx.work.WorkManager
+import androidx.work.testing.SynchronousExecutor
+import androidx.work.testing.WorkManagerTestInitHelper
+import com.google.common.truth.Truth.assertThat
+import dagger.Binds
+import dagger.BindsInstance
+import dagger.Component
+import dagger.Module
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
+import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
+import org.oppia.android.domain.platformparameter.PlatformParameterModule
+import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
+import org.oppia.android.testing.logging.SyncStatusTestModule
+import org.oppia.android.testing.robolectric.RobolectricModule
+import org.oppia.android.testing.threading.TestCoroutineDispatchers
+import org.oppia.android.testing.threading.TestDispatcherModule
+import org.oppia.android.testing.time.FakeOppiaClockModule
+import org.oppia.android.util.caching.AssetModule
+import org.oppia.android.util.data.DataProvidersInjector
+import org.oppia.android.util.data.DataProvidersInjectorProvider
+import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.LoggerModule
+import org.oppia.android.util.logging.firebase.LogReportingModule
+import org.oppia.android.util.logging.performancemetrics.PerformanceMetricsAssessorModule
+import org.oppia.android.util.logging.performancemetrics.PerformanceMetricsConfigurationsModule
+import org.oppia.android.util.networking.NetworkConnectionUtilDebugModule
+import org.robolectric.annotation.Config
+import org.robolectric.annotation.LooperMode
+import java.util.concurrent.TimeUnit
+import javax.inject.Inject
+import javax.inject.Singleton
+
+/** Tests for [PerformanceMetricsLogScheduler]. */
+// FunctionName: test names are conventionally named with underscores.
+@Suppress("FunctionName")
+@RunWith(AndroidJUnit4::class)
+@LooperMode(LooperMode.Mode.PAUSED)
+@Config(application = PerformanceMetricsLogSchedulerTest.TestApplication::class)
+class PerformanceMetricsLogSchedulerTest {
+
+ @Inject
+ lateinit var performanceMetricsLogScheduler: PerformanceMetricsLogScheduler
+
+ @Inject
+ lateinit var metricLogSchedulingWorkerFactory: MetricLogSchedulingWorkerFactory
+
+ @Inject
+ lateinit var testCoroutineDispatchers: TestCoroutineDispatchers
+
+ @Inject
+ lateinit var context: Context
+
+ private lateinit var workManager: WorkManager
+
+ private val workerCaseForSchedulingPeriodicBackgroundMetricLogs: Data = Data.Builder()
+ .putString(
+ MetricLogSchedulingWorker.WORKER_CASE_KEY,
+ MetricLogSchedulingWorker.PERIODIC_BACKGROUND_METRIC_WORKER
+ )
+ .build()
+
+ private val workerCaseForSchedulingStorageUsageMetricLogs: Data = Data.Builder()
+ .putString(
+ MetricLogSchedulingWorker.WORKER_CASE_KEY,
+ MetricLogSchedulingWorker.STORAGE_USAGE_WORKER
+ )
+ .build()
+
+ private val workerCaseForSchedulingPeriodicUiMetricLogs: Data = Data.Builder()
+ .putString(
+ MetricLogSchedulingWorker.WORKER_CASE_KEY,
+ MetricLogSchedulingWorker.PERIODIC_UI_METRIC_WORKER
+ )
+ .build()
+
+ @Before
+ fun setUp() {
+ setUpTestApplicationComponent()
+ val config = Configuration.Builder()
+ .setExecutor(SynchronousExecutor())
+ .setWorkerFactory(metricLogSchedulingWorkerFactory)
+ .build()
+ WorkManagerTestInitHelper.initializeTestWorkManager(context, config)
+ workManager = WorkManager.getInstance(ApplicationProvider.getApplicationContext())
+ }
+
+ @Test
+ fun testScheduler_enqueueRequestForPeriodicBackgroundMetrics_workRequestGetsEnqueued() {
+ val request = PeriodicWorkRequest
+ .Builder(MetricLogSchedulingWorker::class.java, 15, TimeUnit.MINUTES)
+ .setInputData(workerCaseForSchedulingPeriodicBackgroundMetricLogs)
+ .build()
+
+ performanceMetricsLogScheduler.enqueueWorkRequestForPeriodicBackgroundMetrics(
+ workManager,
+ request
+ )
+ testCoroutineDispatchers.runCurrent()
+ val workInfo = workManager.getWorkInfoById(request.id)
+
+ assertThat(workInfo.get().state).isEqualTo(WorkInfo.State.ENQUEUED)
+ }
+
+ @Test
+ fun testScheduler_enqueueRequestForPeriodicUiMetric_workRequestGetsEnqueued() {
+ val request = PeriodicWorkRequest
+ .Builder(MetricLogSchedulingWorker::class.java, 15, TimeUnit.MINUTES)
+ .setInputData(workerCaseForSchedulingPeriodicUiMetricLogs)
+ .build()
+
+ performanceMetricsLogScheduler.enqueueWorkRequestForPeriodicUiMetrics(
+ workManager,
+ request
+ )
+ testCoroutineDispatchers.runCurrent()
+ val workInfo = workManager.getWorkInfoById(request.id)
+
+ assertThat(workInfo.get().state).isEqualTo(WorkInfo.State.ENQUEUED)
+ }
+
+ @Test
+ fun testScheduler_enqueueRequestForStorageMetric_workRequestGetsEnqueued() {
+ val request = PeriodicWorkRequest
+ .Builder(MetricLogSchedulingWorker::class.java, 15, TimeUnit.MINUTES)
+ .setInputData(workerCaseForSchedulingStorageUsageMetricLogs)
+ .build()
+
+ performanceMetricsLogScheduler.enqueueWorkRequestForStorageUsage(
+ workManager,
+ request
+ )
+ testCoroutineDispatchers.runCurrent()
+ val workInfo = workManager.getWorkInfoById(request.id)
+
+ assertThat(workInfo.get().state).isEqualTo(WorkInfo.State.ENQUEUED)
+ }
+
+ private fun setUpTestApplicationComponent() {
+ DaggerPerformanceMetricsLogSchedulerTest_TestApplicationComponent.builder()
+ .setApplication(ApplicationProvider.getApplicationContext())
+ .build()
+ .inject(this)
+ }
+
+ // TODO(#89): Move this to a common test application component.
+ @Module
+ interface TestModule {
+ @Binds
+ fun provideContext(application: Application): Context
+ }
+
+ // TODO(#89): Move this to a common test application component.
+ @Singleton
+ @Component(
+ modules = [
+ TestModule::class, MetricLogSchedulerModule::class, LoggerModule::class,
+ RobolectricModule::class, LocaleProdModule::class, FakeOppiaClockModule::class,
+ TestDispatcherModule::class, LogReportWorkerModule::class, FakeOppiaClockModule::class,
+ NetworkConnectionUtilDebugModule::class, LocaleProdModule::class, LoggerModule::class,
+ AssetModule::class, PlatformParameterModule::class, PlatformParameterSingletonModule::class,
+ LoggingIdentifierModule::class, SyncStatusTestModule::class,
+ PerformanceMetricsAssessorModule::class, ApplicationLifecycleModule::class,
+ LogReportingModule::class, PerformanceMetricsConfigurationsModule::class
+ ]
+ )
+ interface TestApplicationComponent : DataProvidersInjector {
+ @Component.Builder
+ interface Builder {
+ @BindsInstance
+ fun setApplication(application: Application): Builder
+
+ fun build(): TestApplicationComponent
+ }
+
+ fun inject(performanceMetricsLogSchedulerTest: PerformanceMetricsLogSchedulerTest)
+ }
+
+ class TestApplication : Application(), DataProvidersInjectorProvider {
+ private val component: TestApplicationComponent by lazy {
+ DaggerPerformanceMetricsLogSchedulerTest_TestApplicationComponent.builder()
+ .setApplication(this)
+ .build()
+ }
+
+ fun inject(performanceMetricsLogSchedulerTest: PerformanceMetricsLogSchedulerTest) {
+ component.inject(performanceMetricsLogSchedulerTest)
+ }
+
+ override fun getDataProvidersInjector(): DataProvidersInjector = component
+ }
+}
diff --git a/domain/src/test/java/org/oppia/android/domain/oppialogger/loguploader/LogUploadWorkManagerInitializerTest.kt b/domain/src/test/java/org/oppia/android/domain/oppialogger/loguploader/LogReportWorkManagerInitializerTest.kt
similarity index 59%
rename from domain/src/test/java/org/oppia/android/domain/oppialogger/loguploader/LogUploadWorkManagerInitializerTest.kt
rename to domain/src/test/java/org/oppia/android/domain/oppialogger/loguploader/LogReportWorkManagerInitializerTest.kt
index 141d90098b9..50b92a0573e 100644
--- a/domain/src/test/java/org/oppia/android/domain/oppialogger/loguploader/LogUploadWorkManagerInitializerTest.kt
+++ b/domain/src/test/java/org/oppia/android/domain/oppialogger/loguploader/LogReportWorkManagerInitializerTest.kt
@@ -8,6 +8,7 @@ import androidx.test.platform.app.InstrumentationRegistry
import androidx.work.Configuration
import androidx.work.Constraints
import androidx.work.Data
+import androidx.work.DelegatingWorkerFactory
import androidx.work.NetworkType
import androidx.work.testing.SynchronousExecutor
import androidx.work.testing.WorkManagerTestInitHelper
@@ -24,8 +25,12 @@ import org.oppia.android.domain.oppialogger.EventLogStorageCacheSize
import org.oppia.android.domain.oppialogger.ExceptionLogStorageCacheSize
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.OppiaLogger
+import org.oppia.android.domain.oppialogger.PerformanceMetricsLogStorageCacheSize
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
+import org.oppia.android.domain.oppialogger.analytics.testing.FakeLogScheduler
import org.oppia.android.domain.oppialogger.exceptions.ExceptionsController
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulingWorker
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulingWorkerFactory
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.testing.oppialogger.loguploader.FakeLogUploader
@@ -41,6 +46,7 @@ import org.oppia.android.util.data.DataProviders
import org.oppia.android.util.locale.LocaleProdModule
import org.oppia.android.util.logging.LogUploader
import org.oppia.android.util.logging.LoggerModule
+import org.oppia.android.util.logging.MetricLogScheduler
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.networking.NetworkConnectionDebugUtil
import org.oppia.android.util.networking.NetworkConnectionUtilDebugModule
@@ -52,13 +58,16 @@ import javax.inject.Singleton
@RunWith(AndroidJUnit4::class)
@LooperMode(LooperMode.Mode.PAUSED)
@Config(manifest = Config.NONE)
-class LogUploadWorkManagerInitializerTest {
+class LogReportWorkManagerInitializerTest {
@Inject
lateinit var logUploadWorkerFactory: LogUploadWorkerFactory
@Inject
- lateinit var logUploadWorkManagerInitializer: LogUploadWorkManagerInitializer
+ lateinit var metricLogSchedulingWorkerFactory: MetricLogSchedulingWorkerFactory
+
+ @Inject
+ lateinit var logReportWorkManagerInitializer: LogReportWorkManagerInitializer
@Inject
lateinit var exceptionsController: ExceptionsController
@@ -81,6 +90,9 @@ class LogUploadWorkManagerInitializerTest {
@Inject
lateinit var fakeLogUploader: FakeLogUploader
+ @Inject
+ lateinit var fakeLogScheduler: FakeLogScheduler
+
@Inject
lateinit var testCoroutineDispatchers: TestCoroutineDispatchers
@@ -90,26 +102,47 @@ class LogUploadWorkManagerInitializerTest {
fun setUp() {
setUpTestApplicationComponent()
context = InstrumentationRegistry.getInstrumentation().targetContext
+
+ val delegatingWorkerFactory = DelegatingWorkerFactory()
+ delegatingWorkerFactory.addFactory(logUploadWorkerFactory)
+ delegatingWorkerFactory.addFactory(metricLogSchedulingWorkerFactory)
+
val config = Configuration.Builder()
.setExecutor(SynchronousExecutor())
- .setWorkerFactory(logUploadWorkerFactory)
+ .setWorkerFactory(delegatingWorkerFactory)
.build()
WorkManagerTestInitHelper.initializeTestWorkManager(context, config)
}
@Test
fun testWorkRequest_onCreate_enqueuesRequest_verifyRequestId() {
- logUploadWorkManagerInitializer.onCreate()
+ logReportWorkManagerInitializer.onCreate()
testCoroutineDispatchers.runCurrent()
- val enqueuedEventWorkRequestId = logUploadWorkManagerInitializer.getWorkRequestForEventsId()
+ val enqueuedEventWorkRequestId = logReportWorkManagerInitializer.getWorkRequestForEventsId()
val enqueuedExceptionWorkRequestId =
- logUploadWorkManagerInitializer.getWorkRequestForExceptionsId()
+ logReportWorkManagerInitializer.getWorkRequestForExceptionsId()
+ val enqueuedSchedulingStorageUsageMetricWorkRequestId =
+ logReportWorkManagerInitializer.getWorkRequestForSchedulingStorageUsageMetricLogsId()
+ val enqueuedSchedulingPeriodicUiMetricWorkRequestId =
+ logReportWorkManagerInitializer.getWorkRequestForSchedulingPeriodicUiMetricLogsId()
+ val enqueuedSchedulingPeriodicBackgroundPerformanceMetricWorkRequestId =
+ logReportWorkManagerInitializer
+ .getWorkRequestForSchedulingPeriodicBackgroundPerformanceMetricLogsId()
assertThat(fakeLogUploader.getMostRecentEventRequestId()).isEqualTo(enqueuedEventWorkRequestId)
assertThat(fakeLogUploader.getMostRecentExceptionRequestId()).isEqualTo(
enqueuedExceptionWorkRequestId
)
+ assertThat(fakeLogScheduler.getMostRecentStorageUsageMetricLoggingRequestId()).isEqualTo(
+ enqueuedSchedulingStorageUsageMetricWorkRequestId
+ )
+ assertThat(fakeLogScheduler.getMostRecentPeriodicUiMetricLoggingRequestId()).isEqualTo(
+ enqueuedSchedulingPeriodicUiMetricWorkRequestId
+ )
+ assertThat(fakeLogScheduler.getMostRecentPeriodicBackgroundMetricLoggingRequestId()).isEqualTo(
+ enqueuedSchedulingPeriodicBackgroundPerformanceMetricWorkRequestId
+ )
}
@Test
@@ -120,7 +153,7 @@ class LogUploadWorkManagerInitializerTest {
.build()
val logUploadingWorkRequestConstraints =
- logUploadWorkManagerInitializer.getLogUploadWorkerConstraints()
+ logReportWorkManagerInitializer.getLogReportWorkerConstraints()
assertThat(logUploadingWorkRequestConstraints).isEqualTo(workerConstraints)
}
@@ -134,7 +167,7 @@ class LogUploadWorkManagerInitializerTest {
)
.build()
- assertThat(logUploadWorkManagerInitializer.getWorkRequestDataForEvents()).isEqualTo(
+ assertThat(logReportWorkManagerInitializer.getWorkRequestDataForEvents()).isEqualTo(
workerCaseForUploadingEvents
)
}
@@ -148,13 +181,56 @@ class LogUploadWorkManagerInitializerTest {
)
.build()
- assertThat(logUploadWorkManagerInitializer.getWorkRequestDataForExceptions()).isEqualTo(
- workerCaseForUploadingExceptions
- )
+ assertThat(
+ logReportWorkManagerInitializer.getWorkRequestDataForExceptions()
+ ).isEqualTo(workerCaseForUploadingExceptions)
+ }
+
+ @Test
+ fun testWorkRequest_verifyWorkRequestData_forSchedulingStorageUsageMetricLogs() {
+ val workerCaseForSchedulingStorageUsageMetricLogs: Data = Data.Builder()
+ .putString(
+ MetricLogSchedulingWorker.WORKER_CASE_KEY,
+ MetricLogSchedulingWorker.STORAGE_USAGE_WORKER
+ )
+ .build()
+
+ assertThat(
+ logReportWorkManagerInitializer.getWorkRequestDataForSchedulingStorageUsageMetricLogs()
+ ).isEqualTo(workerCaseForSchedulingStorageUsageMetricLogs)
+ }
+
+ @Test
+ fun testWorkRequest_verifyWorkRequestData_forSchedulingPeriodicBackgroundPerformanceMetricLogs() {
+ val workerCaseForSchedulingPeriodicPerformanceMetricLogs: Data = Data.Builder()
+ .putString(
+ MetricLogSchedulingWorker.WORKER_CASE_KEY,
+ MetricLogSchedulingWorker.PERIODIC_BACKGROUND_METRIC_WORKER
+ )
+ .build()
+
+ assertThat(
+ logReportWorkManagerInitializer
+ .getWorkRequestDataForSchedulingPeriodicBackgroundPerformanceMetricLogs()
+ ).isEqualTo(workerCaseForSchedulingPeriodicPerformanceMetricLogs)
+ }
+
+ @Test
+ fun testWorkRequest_verifyWorkRequestData_forSchedulingPeriodicUiMetricLogs() {
+ val workerCaseForSchedulingMemoryUsageMetricLogs: Data = Data.Builder()
+ .putString(
+ MetricLogSchedulingWorker.WORKER_CASE_KEY,
+ MetricLogSchedulingWorker.PERIODIC_UI_METRIC_WORKER
+ )
+ .build()
+
+ assertThat(
+ logReportWorkManagerInitializer.getWorkRequestDataForSchedulingPeriodicUiMetricLogs()
+ ).isEqualTo(workerCaseForSchedulingMemoryUsageMetricLogs)
}
private fun setUpTestApplicationComponent() {
- DaggerLogUploadWorkManagerInitializerTest_TestApplicationComponent.builder()
+ DaggerLogReportWorkManagerInitializerTest_TestApplicationComponent.builder()
.setApplication(ApplicationProvider.getApplicationContext())
.build()
.inject(this)
@@ -180,6 +256,10 @@ class LogUploadWorkManagerInitializerTest {
@Provides
@ExceptionLogStorageCacheSize
fun provideExceptionLogStorageSize(): Int = 2
+
+ @Provides
+ @PerformanceMetricsLogStorageCacheSize
+ fun providePerformanceMetricsLogStorageCacheSize(): Int = 2
}
@Module
@@ -187,6 +267,9 @@ class LogUploadWorkManagerInitializerTest {
@Binds
fun bindsFakeLogUploader(fakeLogUploader: FakeLogUploader): LogUploader
+
+ @Binds
+ fun bindsFakeLogScheduler(fakeLogScheduler: FakeLogScheduler): MetricLogScheduler
}
// TODO(#89): Move this to a common test application component.
@@ -195,7 +278,7 @@ class LogUploadWorkManagerInitializerTest {
modules = [
TestModule::class, TestLogReportingModule::class, RobolectricModule::class,
TestLogStorageModule::class, TestDispatcherModule::class,
- LogUploadWorkerModule::class, TestFirebaseLogUploaderModule::class,
+ LogReportWorkerModule::class, TestFirebaseLogUploaderModule::class,
FakeOppiaClockModule::class, NetworkConnectionUtilDebugModule::class, LocaleProdModule::class,
LoggerModule::class, AssetModule::class, LoggerModule::class, PlatformParameterModule::class,
PlatformParameterSingletonModule::class, LoggingIdentifierModule::class,
@@ -210,6 +293,6 @@ class LogUploadWorkManagerInitializerTest {
fun build(): TestApplicationComponent
}
- fun inject(logUploadWorkRequestTest: LogUploadWorkManagerInitializerTest)
+ fun inject(logUploadWorkRequestTest: LogReportWorkManagerInitializerTest)
}
}
diff --git a/domain/src/test/java/org/oppia/android/domain/oppialogger/loguploader/LogUploadWorkerTest.kt b/domain/src/test/java/org/oppia/android/domain/oppialogger/loguploader/LogUploadWorkerTest.kt
index ffdd501d390..3e7881b4525 100644
--- a/domain/src/test/java/org/oppia/android/domain/oppialogger/loguploader/LogUploadWorkerTest.kt
+++ b/domain/src/test/java/org/oppia/android/domain/oppialogger/loguploader/LogUploadWorkerTest.kt
@@ -336,7 +336,7 @@ class LogUploadWorkerTest {
@Component(
modules = [
TestModule::class, RobolectricModule::class, TestLogStorageModule::class,
- TestDispatcherModule::class, LogUploadWorkerModule::class,
+ TestDispatcherModule::class, LogReportWorkerModule::class,
TestFirebaseLogUploaderModule::class, FakeOppiaClockModule::class,
NetworkConnectionUtilDebugModule::class, LocaleProdModule::class, LoggerModule::class,
AssetModule::class, PlatformParameterModule::class, PlatformParameterSingletonModule::class,
diff --git a/instrumentation/src/java/org/oppia/android/instrumentation/application/TestApplicationComponent.kt b/instrumentation/src/java/org/oppia/android/instrumentation/application/TestApplicationComponent.kt
index 22bedb239cb..b8f2ba6422a 100644
--- a/instrumentation/src/java/org/oppia/android/instrumentation/application/TestApplicationComponent.kt
+++ b/instrumentation/src/java/org/oppia/android/instrumentation/application/TestApplicationComponent.kt
@@ -33,8 +33,10 @@ import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
+import org.oppia.android.domain.oppialogger.analytics.PerformanceMetricsLoggerModule
import org.oppia.android.domain.oppialogger.exceptions.UncaughtExceptionLoggerModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.platformparameter.syncup.PlatformParameterSyncUpWorkerModule
@@ -49,6 +51,8 @@ import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.DebugLogReportingModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
+import org.oppia.android.util.logging.performancemetrics.PerformanceMetricsAssessorModule
+import org.oppia.android.util.logging.performancemetrics.PerformanceMetricsConfigurationsModule
import org.oppia.android.util.networking.NetworkConnectionDebugUtilModule
import org.oppia.android.util.networking.NetworkConnectionUtilDebugModule
import org.oppia.android.util.parser.html.HtmlParserEntityTypeModule
@@ -79,7 +83,7 @@ import javax.inject.Singleton
ViewBindingShimModule::class, PrimeTopicAssetsControllerModule::class,
ExpirationMetaDataRetrieverModule::class, RatioInputModule::class,
UncaughtExceptionLoggerModule::class, ApplicationStartupListenerModule::class,
- LogUploadWorkerModule::class, WorkManagerConfigurationModule::class,
+ LogReportWorkerModule::class, WorkManagerConfigurationModule::class,
HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class,
FirebaseLogUploaderModule::class, NetworkModule::class, PracticeTabModule::class,
PlatformParameterModule::class, PlatformParameterSingletonModule::class,
@@ -90,7 +94,9 @@ import javax.inject.Singleton
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, NetworkConnectionDebugUtilModule::class
+ SyncStatusModule::class, NetworkConnectionDebugUtilModule::class,
+ MetricLogSchedulerModule::class, PerformanceMetricsLoggerModule::class,
+ PerformanceMetricsAssessorModule::class, PerformanceMetricsConfigurationsModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/model/src/main/proto/BUILD.bazel b/model/src/main/proto/BUILD.bazel
index 02838f1c01c..c6d19966e44 100644
--- a/model/src/main/proto/BUILD.bazel
+++ b/model/src/main/proto/BUILD.bazel
@@ -50,6 +50,17 @@ java_lite_proto_library(
deps = [":event_logger_proto"],
)
+oppia_proto_library(
+ name = "performance_metrics_event_logger_proto",
+ srcs = ["performance_metrics.proto"],
+)
+
+java_lite_proto_library(
+ name = "performance_metrics_event_logger_java_proto_lite",
+ visibility = ["//:oppia_api_visibility"],
+ deps = [":performance_metrics_event_logger_proto"],
+)
+
oppia_proto_library(
name = "exploration_checkpoint_proto",
srcs = ["exploration_checkpoint.proto"],
diff --git a/model/src/main/proto/performance_metrics.proto b/model/src/main/proto/performance_metrics.proto
index a6019cfb772..85c54cdd828 100644
--- a/model/src/main/proto/performance_metrics.proto
+++ b/model/src/main/proto/performance_metrics.proto
@@ -85,16 +85,14 @@ message OppiaMetricLog {
// Structure of the network usage metric.
message NetworkUsageMetric {
- // Usage data is collected in discrete bins of time called 'Buckets'. The time interval of this
- // bucket is customizable and depends on the query that we are making. This data is logged after
- // the bucket's timeframe.
+ // Both metrics count the packets across all network interfaces, and always increases
+ // monotonically since device reboot. Statistics are measured at the network layer, so they
+ // include both TCP and UDP usage.
- // This field denotes the number of bytes received by the application on the device during
- // this bucket's time interval.
+ // This field denotes the number of bytes received by the application since device reboot.
int64 bytes_received = 1;
- // This field denotes the number of bytes sent by the application on the device during
- // this bucket's time interval.
+ // This field denotes the number of bytes sent by the application since device reboot.
int64 bytes_sent = 2;
}
diff --git a/scripts/assets/file_content_validation_checks.textproto b/scripts/assets/file_content_validation_checks.textproto
index 369a38ee68d..ab76d9e3ddf 100644
--- a/scripts/assets/file_content_validation_checks.textproto
+++ b/scripts/assets/file_content_validation_checks.textproto
@@ -33,6 +33,7 @@ file_content_checks {
failure_message: "SettableFuture should only be used in pre-approved locations since it's easy to potentially mess up & lead to a hanging ListenableFuture."
exempted_file_name: "domain/src/main/java/org/oppia/android/domain/oppialogger/loguploader/LogUploadWorker.kt"
exempted_file_name: "domain/src/main/java/org/oppia/android/domain/platformparameter/syncup/PlatformParameterSyncUpWorker.kt"
+ exempted_file_name: "domain/src/main/java/org/oppia/android/domain/oppialogger/logscheduler/MetricLogSchedulingWorker.kt"
exempted_file_name: "scripts/src/javatests/org/oppia/android/scripts/regex/RegexPatternValidationCheckTest.kt"
}
file_content_checks {
@@ -308,6 +309,7 @@ file_content_checks {
exempted_file_name: "utility/src/test/java/org/oppia/android/util/math/MathTokenizerTest.kt"
exempted_file_name: "utility/src/test/java/org/oppia/android/util/math/PolynomialExtensionsTest.kt"
exempted_file_name: "utility/src/test/java/org/oppia/android/util/math/RealExtensionsTest.kt"
+ exempted_file_name: "utility/src/test/java/org/oppia/android/util/logging/performancemetrics/PerformanceMetricsAssessorImplTest.kt"
exempted_file_patterns: "testing/src/main/java/org/oppia/android/testing/junit/.+?\\.kt"
}
file_content_checks {
diff --git a/scripts/assets/test_file_exemptions.textproto b/scripts/assets/test_file_exemptions.textproto
index fc9609ccae0..24119196db3 100644
--- a/scripts/assets/test_file_exemptions.textproto
+++ b/scripts/assets/test_file_exemptions.textproto
@@ -636,7 +636,7 @@ exempted_file_path: "domain/src/main/java/org/oppia/android/domain/oppialogger/L
exempted_file_path: "domain/src/main/java/org/oppia/android/domain/oppialogger/analytics/LearnerAnalyticsInactivityLimitMillis.kt"
exempted_file_path: "domain/src/main/java/org/oppia/android/domain/oppialogger/exceptions/UncaughtExceptionLoggerModule.kt"
exempted_file_path: "domain/src/main/java/org/oppia/android/domain/oppialogger/loguploader/LogUploadWorkerFactory.kt"
-exempted_file_path: "domain/src/main/java/org/oppia/android/domain/oppialogger/loguploader/LogUploadWorkerModule.kt"
+exempted_file_path: "domain/src/main/java/org/oppia/android/domain/oppialogger/loguploader/LogReportWorkerModule.kt"
exempted_file_path: "domain/src/main/java/org/oppia/android/domain/platformparameter/PlatformParameterAlphaKenyaModule.kt"
exempted_file_path: "domain/src/main/java/org/oppia/android/domain/platformparameter/PlatformParameterSingletonImpl.kt"
exempted_file_path: "domain/src/main/java/org/oppia/android/domain/platformparameter/PlatformParameterSingletonModule.kt"
@@ -824,3 +824,7 @@ exempted_file_path: "utility/src/main/java/org/oppia/android/util/threading/Conc
exempted_file_path: "utility/src/main/java/org/oppia/android/util/threading/DispatcherInjector.kt"
exempted_file_path: "utility/src/main/java/org/oppia/android/util/threading/DispatcherInjectorProvider.kt"
exempted_file_path: "utility/src/main/java/org/oppia/android/util/threading/DispatcherModule.kt"
+exempted_file_path: "utility/src/main/java/org/oppia/android/util/logging/performancemetrics/PerformanceMetricsAssessor.kt"
+exempted_file_path: "utility/src/main/java/org/oppia/android/util/logging/MetricLogScheduler.kt"
+exempted_file_path: "utility/src/main/java/org/oppia/android/util/logging/performancemetrics/PerformanceMetricsEventLogger.kt"
+exempted_file_path: "domain/src/main/java/org/oppia/android/domain/oppialogger/logscheduler/MetricLogSchedulingWorkerFactory.kt"
diff --git a/testing/BUILD.bazel b/testing/BUILD.bazel
index 49cee29f1c1..cfb0a7133a3 100644
--- a/testing/BUILD.bazel
+++ b/testing/BUILD.bazel
@@ -37,6 +37,7 @@ kt_android_library(
"//domain",
"//domain/src/main/java/org/oppia/android/domain/classify:interactions_module",
"//domain/src/main/java/org/oppia/android/domain/profile:profile_management_controller",
+ "//model/src/main/proto:performance_metrics_event_logger_java_proto_lite",
"//testing/src/main/java/org/oppia/android/testing/data:async_result_subject",
"//testing/src/main/java/org/oppia/android/testing/threading:test_coroutine_dispatchers",
"//testing/src/main/java/org/oppia/android/testing/time:fake_oppia_clock",
@@ -61,6 +62,8 @@ kt_android_library(
"//third_party:org_mockito_mockito-core",
"//third_party:org_robolectric_robolectric",
"//utility",
+ "//utility/src/main/java/org/oppia/android/util/logging/performancemetrics:performance_metrics_assessor",
+ "//utility/src/main/java/org/oppia/android/util/logging/performancemetrics:performance_metrics_event_logger",
"//utility/src/main/java/org/oppia/android/util/parser/image:glide_image_loader_module",
"//utility/src/main/java/org/oppia/android/util/parser/image:image_loader",
"//utility/src/main/java/org/oppia/android/util/parser/image:image_parsing_module",
@@ -79,6 +82,7 @@ TEST_DEPS = [
"//domain/src/main/java/org/oppia/android/domain/oppialogger:prod_module",
"//domain/src/main/java/org/oppia/android/domain/oppialogger/analytics:prod_module",
"//domain/src/main/java/org/oppia/android/domain/profile:profile_management_controller",
+ "//model/src/main/proto:performance_metrics_event_logger_java_proto_lite",
"//testing/src/main/java/org/oppia/android/testing/data:async_result_subject",
"//testing/src/main/java/org/oppia/android/testing/data:data_provider_test_monitor",
"//testing/src/main/java/org/oppia/android/testing/espresso:text_input_action",
@@ -109,6 +113,8 @@ TEST_DEPS = [
"//utility/src/main/java/org/oppia/android/util/caching/testing:caching_test_module",
"//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/logging/performancemetrics:performance_metrics_assessor",
+ "//utility/src/main/java/org/oppia/android/util/logging/performancemetrics:performance_metrics_event_logger",
"//utility/src/main/java/org/oppia/android/util/networking:debug_module",
"//utility/src/main/java/org/oppia/android/util/system:prod_module",
]
diff --git a/testing/src/main/java/org/oppia/android/testing/FakePerformanceMetricAssessor.kt b/testing/src/main/java/org/oppia/android/testing/FakePerformanceMetricAssessor.kt
new file mode 100644
index 00000000000..f797b922029
--- /dev/null
+++ b/testing/src/main/java/org/oppia/android/testing/FakePerformanceMetricAssessor.kt
@@ -0,0 +1,67 @@
+package org.oppia.android.testing
+
+import org.oppia.android.app.model.OppiaMetricLog
+import org.oppia.android.util.logging.performancemetrics.PerformanceMetricsAssessor
+import javax.inject.Inject
+import javax.inject.Singleton
+
+/** A test specific fake for performance metric utils. */
+@Singleton
+class FakePerformanceMetricAssessor @Inject constructor() : PerformanceMetricsAssessor {
+ private var testApkSize = 0L
+ private var testStorageUsage = 0L
+ private var testTotalPss = 0L
+ private var testTotalBytesSent = 0L
+ private var testTotalReceivedBytes = 0L
+ private var testDeviceStorageTier = OppiaMetricLog.StorageTier.MEDIUM_STORAGE
+ private var testDeviceMemoryTier = OppiaMetricLog.MemoryTier.MEDIUM_MEMORY_TIER
+
+ override fun getApkSize(): Long = testApkSize
+
+ override fun getUsedStorage(): Long = testStorageUsage
+
+ override fun getTotalPssUsed(): Long = testTotalPss
+
+ override fun getTotalSentBytes(): Long = testTotalBytesSent
+
+ override fun getTotalReceivedBytes(): Long = testTotalReceivedBytes
+
+ override fun getDeviceStorageTier(): OppiaMetricLog.StorageTier = testDeviceStorageTier
+
+ override fun getDeviceMemoryTier(): OppiaMetricLog.MemoryTier = testDeviceMemoryTier
+
+ /** Sets [apkSize] as the value of [testApkSize]. */
+ fun setApkSize(apkSize: Long) {
+ testApkSize = apkSize
+ }
+
+ /** Sets [storageUsage] as the value of [testStorageUsage]. */
+ fun setStorageUsage(storageUsage: Long) {
+ testStorageUsage = storageUsage
+ }
+
+ /** Sets [totalPss] as the value of [testTotalPss]. */
+ fun setTotalPss(totalPss: Long) {
+ testTotalPss = totalPss
+ }
+
+ /** Sets [sentBytes] as the value of [testTotalBytesSent]. */
+ fun setTotalSentBytes(sentBytes: Long) {
+ testTotalBytesSent = sentBytes
+ }
+
+ /** Sets [receivedBytes] as the value of [testTotalReceivedBytes]. */
+ fun setTotalReceivedBytes(receivedBytes: Long) {
+ testTotalReceivedBytes = receivedBytes
+ }
+
+ /** Sets [storageTier] as the value of [testDeviceStorageTier]. */
+ fun setDeviceStorageTier(storageTier: OppiaMetricLog.StorageTier) {
+ testDeviceStorageTier = storageTier
+ }
+
+ /** Sets [memoryTier] as the value of [testDeviceMemoryTier]. */
+ fun setDeviceMemoryTier(memoryTier: OppiaMetricLog.MemoryTier) {
+ testDeviceMemoryTier = memoryTier
+ }
+}
diff --git a/testing/src/main/java/org/oppia/android/testing/FakePerformanceMetricsEventLogger.kt b/testing/src/main/java/org/oppia/android/testing/FakePerformanceMetricsEventLogger.kt
new file mode 100644
index 00000000000..c48666eb680
--- /dev/null
+++ b/testing/src/main/java/org/oppia/android/testing/FakePerformanceMetricsEventLogger.kt
@@ -0,0 +1,41 @@
+package org.oppia.android.testing
+
+import org.oppia.android.app.model.OppiaMetricLog
+import org.oppia.android.util.logging.performancemetrics.PerformanceMetricsEventLogger
+import java.util.concurrent.CopyOnWriteArrayList
+import javax.inject.Inject
+import javax.inject.Singleton
+
+/** A test specific fake for the event logger. */
+@Singleton
+class FakePerformanceMetricsEventLogger @Inject constructor() : PerformanceMetricsEventLogger {
+ private val performanceMetricsEventList = CopyOnWriteArrayList()
+
+ override fun logPerformanceMetric(oppiaMetricLog: OppiaMetricLog) {
+ performanceMetricsEventList.add(oppiaMetricLog)
+ }
+
+ /** Returns the oldest event that's been logged. */
+ fun getOldestPerformanceMetricsEvent(): OppiaMetricLog = performanceMetricsEventList.first()
+
+ /** Returns the most recently logged event. */
+ fun getMostRecentPerformanceMetricsEvent(): OppiaMetricLog =
+ getMostRecentPerformanceMetricsEvents(count = 1).first()
+
+ /** Returns the most recent [count] logged events. */
+ fun getMostRecentPerformanceMetricsEvents(count: Int): List =
+ performanceMetricsEventList.takeLast(count)
+
+ /** Clears all the events that are currently logged. */
+ fun clearAllPerformanceMetricsEvents() = performanceMetricsEventList.clear()
+
+ /** Checks if a certain event has been logged or not. */
+ fun hasPerformanceMetricsEventLogged(oppiaMetricLog: OppiaMetricLog): Boolean =
+ performanceMetricsEventList.contains(oppiaMetricLog)
+
+ /** Returns true if there are no events logged. */
+ fun noPerformanceMetricsEventsPresent(): Boolean = performanceMetricsEventList.isEmpty()
+
+ /** Returns the number of events logged to date (and not cleared by [clearAllPerformanceMetricsEvents]). */
+ fun getPerformanceMetricsEventListCount(): Int = performanceMetricsEventList.size
+}
diff --git a/testing/src/main/java/org/oppia/android/testing/TestLogReportingModule.kt b/testing/src/main/java/org/oppia/android/testing/TestLogReportingModule.kt
index 627577511ac..4d8c7f37753 100644
--- a/testing/src/main/java/org/oppia/android/testing/TestLogReportingModule.kt
+++ b/testing/src/main/java/org/oppia/android/testing/TestLogReportingModule.kt
@@ -4,6 +4,8 @@ import dagger.Binds
import dagger.Module
import org.oppia.android.util.logging.EventLogger
import org.oppia.android.util.logging.ExceptionLogger
+import org.oppia.android.util.logging.performancemetrics.PerformanceMetricsAssessor
+import org.oppia.android.util.logging.performancemetrics.PerformanceMetricsEventLogger
/** Provides fake log reporting dependencies. */
@Module
@@ -14,4 +16,14 @@ interface TestLogReportingModule {
@Binds
fun bindFakeEventLogger(fakeEventLogger: FakeEventLogger): EventLogger
+
+ @Binds
+ fun bindFakePerformanceMetricsEventLogger(
+ fakePerformanceMetricsEventLogger: FakePerformanceMetricsEventLogger
+ ): PerformanceMetricsEventLogger
+
+ @Binds
+ fun bindFakePerformanceMetricsAssessor(
+ fakePerformanceMetricAssessor: FakePerformanceMetricAssessor
+ ): PerformanceMetricsAssessor
}
diff --git a/testing/src/main/java/org/oppia/android/testing/robolectric/BUILD.bazel b/testing/src/main/java/org/oppia/android/testing/robolectric/BUILD.bazel
index 89c998daa24..15870e33871 100644
--- a/testing/src/main/java/org/oppia/android/testing/robolectric/BUILD.bazel
+++ b/testing/src/main/java/org/oppia/android/testing/robolectric/BUILD.bazel
@@ -50,4 +50,28 @@ kt_android_library(
],
)
+kt_android_library(
+ name = "oppia_shadow_activity_manager",
+ testonly = True,
+ srcs = [
+ "OppiaShadowActivityManager.kt",
+ ],
+ visibility = ["//:oppia_testing_visibility"],
+ deps = [
+ "//third_party:org_robolectric_robolectric",
+ ],
+)
+
+kt_android_library(
+ name = "oppia_shadow_traffic_stats",
+ testonly = True,
+ srcs = [
+ "OppiaShadowTrafficStats.kt",
+ ],
+ visibility = ["//:oppia_testing_visibility"],
+ deps = [
+ "//third_party:org_robolectric_robolectric",
+ ],
+)
+
dagger_rules()
diff --git a/testing/src/main/java/org/oppia/android/testing/robolectric/OppiaShadowActivityManager.kt b/testing/src/main/java/org/oppia/android/testing/robolectric/OppiaShadowActivityManager.kt
new file mode 100644
index 00000000000..b2aedb35be0
--- /dev/null
+++ b/testing/src/main/java/org/oppia/android/testing/robolectric/OppiaShadowActivityManager.kt
@@ -0,0 +1,54 @@
+package org.oppia.android.testing.robolectric
+
+import android.app.ActivityManager
+import android.os.Debug
+import org.robolectric.annotation.Implementation
+import org.robolectric.annotation.Implements
+import org.robolectric.shadows.ShadowActivityManager
+
+/**
+ * Shadows the Activity Manager to extend its testing capabilities.
+ *
+ * There is an existing robolectric shadow of Activity Manager but that doesn't provide us enough
+ * control over Debug.MemoryInfo and hence memory usage can't be tested using that.
+ */
+@Implements(ActivityManager::class)
+class OppiaShadowActivityManager : ShadowActivityManager() {
+
+ private var processMemoryInfo: Array? = arrayOf(Debug.MemoryInfo())
+
+ private var memoryInfo: ActivityManager.MemoryInfo = ActivityManager.MemoryInfo()
+
+ /**
+ * Sets [memoryInfo] as part of [processMemoryInfo] which is then returned whenever
+ * [getProcessMemoryInfo] is called.
+ */
+ fun setProcessMemoryInfo(memoryInfo: Debug.MemoryInfo) {
+ processMemoryInfo?.set(0, memoryInfo)
+ }
+
+ /** Sets [memoryInfo] as equal to [memoryInfoValue]. */
+ override fun setMemoryInfo(memoryInfoValue: ActivityManager.MemoryInfo) {
+ this.memoryInfo = memoryInfoValue
+ }
+
+ /**
+ * Robolectric shadow override of [ActivityManager.getProcessMemoryInfo]. Note that the value of
+ * [pids] isn't taken into account in this implementation unlike the actual one.
+ */
+ @Implementation
+ fun getProcessMemoryInfo(pids: IntArray?): Array? {
+ return processMemoryInfo
+ }
+
+ /** Robolectric shadow override of [ActivityManager.getMemoryInfo]. */
+ @Implementation
+ public override fun getMemoryInfo(outInfo: ActivityManager.MemoryInfo) {
+ outInfo.apply {
+ availMem = memoryInfo.availMem
+ outInfo.lowMemory = memoryInfo.lowMemory
+ outInfo.threshold = memoryInfo.threshold
+ outInfo.totalMem = memoryInfo.totalMem
+ }
+ }
+}
diff --git a/testing/src/main/java/org/oppia/android/testing/robolectric/OppiaShadowTrafficStats.kt b/testing/src/main/java/org/oppia/android/testing/robolectric/OppiaShadowTrafficStats.kt
new file mode 100644
index 00000000000..bd418b58025
--- /dev/null
+++ b/testing/src/main/java/org/oppia/android/testing/robolectric/OppiaShadowTrafficStats.kt
@@ -0,0 +1,57 @@
+package org.oppia.android.testing.robolectric
+
+import android.net.TrafficStats
+import org.robolectric.annotation.Implementation
+import org.robolectric.annotation.Implements
+
+private const val DEFAULT_BYTE_VALUE = 0L
+private var uidTxBytes = DEFAULT_BYTE_VALUE
+private var uidRxBytes = DEFAULT_BYTE_VALUE
+
+/**
+ * Shadows the Traffic Stats to extend its testing capabilities.
+ *
+ * There is an existing robolectric shadow of Traffic Stats but that doesn't provide us enough
+ * control over network bytes sent/received for a specific UID and hence network usage can't be
+ * tested using that.
+ */
+@Implements(TrafficStats::class)
+class OppiaShadowTrafficStats {
+
+ /** Sets [uidTxBytes] as equal to [bytes]. */
+ fun setUidTxBytes(bytes: Long) {
+ uidTxBytes = bytes
+ }
+
+ /** Sets [uidRxBytes] as equal to [bytes]. */
+ fun setUidRxBytes(bytes: Long) {
+ uidRxBytes = bytes
+ }
+
+ companion object {
+ /**
+ * Robolectric shadow override of [TrafficStats.getUidRxBytes]. Note that the value of
+ * [uid] isn't taken into account in this implementation unlike the actual one.
+ */
+ @Implementation
+ @JvmStatic
+ fun getUidRxBytes(uid: Int): Long = uidRxBytes
+
+ /**
+ * Robolectric shadow override of [TrafficStats.getUidTxBytes]. Note that the value of
+ * [uid] isn't taken into account in this implementation unlike the actual one.
+ */
+ @Implementation
+ @JvmStatic
+ fun getUidTxBytes(uid: Int): Long = uidTxBytes
+
+ /**
+ * Resets [uidTxBytes] and [uidRxBytes] values. This should always be called in a tear-down
+ * method to avoid leaking state between tests.
+ */
+ fun reset() {
+ uidRxBytes = DEFAULT_BYTE_VALUE
+ uidTxBytes = DEFAULT_BYTE_VALUE
+ }
+ }
+}
diff --git a/testing/src/test/java/org/oppia/android/testing/FakePerformanceMetricAssessorTest.kt b/testing/src/test/java/org/oppia/android/testing/FakePerformanceMetricAssessorTest.kt
new file mode 100644
index 00000000000..cb43cd5aaf0
--- /dev/null
+++ b/testing/src/test/java/org/oppia/android/testing/FakePerformanceMetricAssessorTest.kt
@@ -0,0 +1,174 @@
+package org.oppia.android.testing
+
+import android.app.Application
+import android.content.Context
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.google.common.truth.Truth.assertThat
+import dagger.BindsInstance
+import dagger.Component
+import dagger.Module
+import dagger.Provides
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.oppia.android.app.model.OppiaMetricLog
+import org.robolectric.annotation.Config
+import org.robolectric.annotation.LooperMode
+import javax.inject.Inject
+import javax.inject.Singleton
+
+private const val ONE_MEGABYTE = 1024L * 1024L
+private const val TEST_APK_SIZE = ONE_MEGABYTE * 3L
+private const val TEST_STORAGE_USAGE = ONE_MEGABYTE * 7L
+private const val TEST_TOTAL_PSS = ONE_MEGABYTE * 2L
+private const val TEST_BYTES_SENT = ONE_MEGABYTE
+private const val TEST_BYTES_RECEIVED = ONE_MEGABYTE
+private const val DEFAULT_TEST_APK_SIZE = 0L
+private const val DEFAULT_TEST_STORAGE_USAGE = 0L
+private const val DEFAULT_TEST_TOTAL_PSS = 0L
+private const val DEFAULT_TEST_BYTES_SENT = 0L
+private const val DEFAULT_TEST_BYTES_RECEIVED = 0L
+
+/** Tests for [FakePerformanceMetricAssessor]. */
+@RunWith(AndroidJUnit4::class)
+@LooperMode(LooperMode.Mode.PAUSED)
+@Config(manifest = Config.NONE)
+class FakePerformanceMetricAssessorTest {
+
+ @Inject
+ lateinit var fakePerformanceMetricAssessor: FakePerformanceMetricAssessor
+
+ @Before
+ fun setUp() {
+ setUpTestApplicationComponent()
+ }
+
+ @Test
+ fun testFakeMetricAssessor_setApkSize_returnsCorrectApkSize() {
+ fakePerformanceMetricAssessor.setApkSize(TEST_APK_SIZE)
+
+ assertThat(fakePerformanceMetricAssessor.getApkSize()).isEqualTo(TEST_APK_SIZE)
+ }
+
+ @Test
+ fun testFakeMetricAssessor_getApkSize_returnsDefaultApkSize() {
+ assertThat(fakePerformanceMetricAssessor.getApkSize()).isEqualTo(DEFAULT_TEST_APK_SIZE)
+ }
+
+ @Test
+ fun testFakeMetricAssessor_setStorageUsage_returnsCorrectStorageSize() {
+ fakePerformanceMetricAssessor.setStorageUsage(TEST_STORAGE_USAGE)
+
+ assertThat(fakePerformanceMetricAssessor.getUsedStorage()).isEqualTo(TEST_STORAGE_USAGE)
+ }
+
+ @Test
+ fun testFakeMetricAssessor_getStorageUsage_returnsDefaultStorageUsage() {
+ assertThat(fakePerformanceMetricAssessor.getUsedStorage()).isEqualTo(DEFAULT_TEST_STORAGE_USAGE)
+ }
+
+ @Test
+ fun testFakeMetricAssessor_setTotalPss_returnsCorrectTotalPss() {
+ fakePerformanceMetricAssessor.setTotalPss(TEST_TOTAL_PSS)
+
+ assertThat(fakePerformanceMetricAssessor.getTotalPssUsed()).isEqualTo(TEST_TOTAL_PSS)
+ }
+
+ @Test
+ fun testFakeMetricAssessor_getTotalPss_returnsDefaultTotalPss() {
+ assertThat(fakePerformanceMetricAssessor.getUsedStorage()).isEqualTo(DEFAULT_TEST_TOTAL_PSS)
+ }
+
+ @Test
+ fun testFakeMetricAssessor_setTotalSentBytes_returnsCorrectTotalSentBytes() {
+ fakePerformanceMetricAssessor.setTotalSentBytes(TEST_BYTES_SENT)
+
+ assertThat(fakePerformanceMetricAssessor.getTotalSentBytes()).isEqualTo(TEST_BYTES_SENT)
+ }
+
+ @Test
+ fun testFakeMetricAssessor_getTotalSentBytes_returnsDefaultTotalSentBytes() {
+ assertThat(fakePerformanceMetricAssessor.getTotalSentBytes()).isEqualTo(DEFAULT_TEST_BYTES_SENT)
+ }
+
+ @Test
+ fun testFakeMetricAssessor_setTotalReceivedBytes_returnsCorrectTotalReceivedBytes() {
+ fakePerformanceMetricAssessor.setTotalReceivedBytes(TEST_BYTES_RECEIVED)
+
+ assertThat(fakePerformanceMetricAssessor.getTotalReceivedBytes())
+ .isEqualTo(TEST_BYTES_RECEIVED)
+ }
+
+ @Test
+ fun testFakeMetricAssessor_getTotalReceivedBytes_returnsDefaultTotalReceivedBytes() {
+ assertThat(fakePerformanceMetricAssessor.getTotalReceivedBytes())
+ .isEqualTo(DEFAULT_TEST_BYTES_RECEIVED)
+ }
+
+ @Test
+ fun testFakeMetricAssessor_setDeviceStorageTier_returnsCorrectTotalDeviceStorageTier() {
+ val testDeviceStorageTier = OppiaMetricLog.StorageTier.LOW_STORAGE
+ fakePerformanceMetricAssessor.setDeviceStorageTier(testDeviceStorageTier)
+
+ assertThat(fakePerformanceMetricAssessor.getDeviceStorageTier())
+ .isEqualTo(testDeviceStorageTier)
+ }
+
+ @Test
+ fun testFakeMetricAssessor_getDeviceStorageTier_returnsDefaultTotalDeviceStorageTier() {
+ val defaultTestDeviceStorageTier = OppiaMetricLog.StorageTier.MEDIUM_STORAGE
+
+ assertThat(fakePerformanceMetricAssessor.getDeviceStorageTier()).isEqualTo(
+ defaultTestDeviceStorageTier
+ )
+ }
+
+ @Test
+ fun testFakeMetricAssessor_setDeviceMemoryTier_returnsCorrectTotalDeviceMemoryTier() {
+ val testDeviceMemoryTier = OppiaMetricLog.MemoryTier.LOW_MEMORY_TIER
+ fakePerformanceMetricAssessor.setDeviceMemoryTier(testDeviceMemoryTier)
+
+ assertThat(fakePerformanceMetricAssessor.getDeviceMemoryTier()).isEqualTo(testDeviceMemoryTier)
+ }
+
+ @Test
+ fun testFakeMetricAssessor_getDeviceMemoryTier_returnsDefaultTotalDeviceMemoryTier() {
+ val defaultTestDeviceMemoryTier = OppiaMetricLog.MemoryTier.MEDIUM_MEMORY_TIER
+
+ assertThat(fakePerformanceMetricAssessor.getDeviceMemoryTier()).isEqualTo(
+ defaultTestDeviceMemoryTier
+ )
+ }
+
+ private fun setUpTestApplicationComponent() {
+ DaggerFakePerformanceMetricAssessorTest_TestApplicationComponent.builder()
+ .setApplication(ApplicationProvider.getApplicationContext())
+ .build()
+ .inject(this)
+ }
+
+ // TODO(#89): Move this to a common test application component.
+ @Module
+ class TestModule {
+ @Provides
+ @Singleton
+ fun provideContext(application: Application): Context {
+ return application
+ }
+ }
+
+ // TODO(#89): Move this to a common test application component.
+ @Singleton
+ @Component(modules = [TestModule::class, TestLogReportingModule::class])
+ interface TestApplicationComponent {
+ @Component.Builder
+ interface Builder {
+ @BindsInstance
+ fun setApplication(application: Application): Builder
+ fun build(): TestApplicationComponent
+ }
+
+ fun inject(fakePerformanceMetricAssessorTest: FakePerformanceMetricAssessorTest)
+ }
+}
diff --git a/testing/src/test/java/org/oppia/android/testing/FakePerformanceMetricsEventLoggerTest.kt b/testing/src/test/java/org/oppia/android/testing/FakePerformanceMetricsEventLoggerTest.kt
new file mode 100644
index 00000000000..63afc482661
--- /dev/null
+++ b/testing/src/test/java/org/oppia/android/testing/FakePerformanceMetricsEventLoggerTest.kt
@@ -0,0 +1,324 @@
+package org.oppia.android.testing
+
+import android.app.Application
+import android.content.Context
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.google.common.truth.Truth.assertThat
+import dagger.BindsInstance
+import dagger.Component
+import dagger.Module
+import dagger.Provides
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.oppia.android.app.model.OppiaMetricLog
+import org.oppia.android.app.model.OppiaMetricLog.Priority.HIGH_PRIORITY
+import org.oppia.android.app.model.OppiaMetricLog.Priority.MEDIUM_PRIORITY
+import org.oppia.android.domain.oppialogger.LogStorageModule
+import org.oppia.android.testing.robolectric.RobolectricModule
+import org.oppia.android.testing.threading.TestDispatcherModule
+import org.oppia.android.testing.time.FakeOppiaClockModule
+import org.oppia.android.util.logging.performancemetrics.PerformanceMetricsEventLogger
+import org.robolectric.annotation.Config
+import org.robolectric.annotation.LooperMode
+import javax.inject.Inject
+import javax.inject.Singleton
+
+/** Tests for [FakePerformanceMetricsEventLogger]. */
+// FunctionName: test names are conventionally named with underscores.
+@Suppress("FunctionName")
+@RunWith(AndroidJUnit4::class)
+@LooperMode(LooperMode.Mode.PAUSED)
+@Config(manifest = Config.NONE)
+class FakePerformanceMetricsEventLoggerTest {
+
+ @Inject
+ lateinit var fakePerformanceMetricsEventLogger: FakePerformanceMetricsEventLogger
+ @Inject
+ lateinit var performanceMetricsEventLogger: PerformanceMetricsEventLogger
+
+ private val metricLog1 = OppiaMetricLog.newBuilder().setPriority(HIGH_PRIORITY).build()
+ private val metricLog2 = OppiaMetricLog.newBuilder().setPriority(MEDIUM_PRIORITY).build()
+
+ @Before
+ fun setUp() {
+ setUpTestApplicationComponent()
+ }
+
+ @Test
+ fun testFakeMetricsEventLogger_logPerformanceMetric_returnsMetricEvent() {
+ performanceMetricsEventLogger.logPerformanceMetric(metricLog1)
+ val event = fakePerformanceMetricsEventLogger.getMostRecentPerformanceMetricsEvent()
+
+ assertThat(event).isEqualTo(metricLog1)
+ assertThat(event.priority).isEqualTo(HIGH_PRIORITY)
+ }
+
+ @Test
+ fun testFakeMetricsEventLogger_logMetricEventTwice_returnsLatestEvent() {
+ performanceMetricsEventLogger.logPerformanceMetric(metricLog1)
+ performanceMetricsEventLogger.logPerformanceMetric(metricLog2)
+ val event = fakePerformanceMetricsEventLogger.getMostRecentPerformanceMetricsEvent()
+
+ assertThat(event).isEqualTo(metricLog2)
+ assertThat(event.priority).isEqualTo(MEDIUM_PRIORITY)
+ }
+
+ @Test
+ fun testFakeMetricsEventLogger_logEvent_clearAllEvents_logEventAgain_returnsLatestEvent() {
+ performanceMetricsEventLogger.logPerformanceMetric(metricLog1)
+ fakePerformanceMetricsEventLogger.clearAllPerformanceMetricsEvents()
+ performanceMetricsEventLogger.logPerformanceMetric(metricLog2)
+ val event = fakePerformanceMetricsEventLogger.getMostRecentPerformanceMetricsEvent()
+
+ assertThat(event).isEqualTo(metricLog2)
+ assertThat(event.priority).isEqualTo(MEDIUM_PRIORITY)
+ }
+
+ @Test
+ fun testFakeMetricsEventLogger_logNothing_getMostRecent_returnsFailure() {
+ assertThrows(NoSuchElementException::class) {
+ fakePerformanceMetricsEventLogger.getMostRecentPerformanceMetricsEvent()
+ }
+ }
+
+ @Test
+ fun testFakeMetricsEventLogger_logEvent_clearAllEvents_getMostRecent_returnsFailure() {
+ performanceMetricsEventLogger.logPerformanceMetric(metricLog1)
+ fakePerformanceMetricsEventLogger.clearAllPerformanceMetricsEvents()
+
+ assertThrows(NoSuchElementException::class) {
+ fakePerformanceMetricsEventLogger.getMostRecentPerformanceMetricsEvent()
+ }
+ }
+
+ @Test
+ fun testFakeMetricsEventLogger_clearAllEvents_returnsEmptyList() {
+ fakePerformanceMetricsEventLogger.clearAllPerformanceMetricsEvents()
+ val isListEmpty = fakePerformanceMetricsEventLogger.noPerformanceMetricsEventsPresent()
+
+ assertThat(isListEmpty).isTrue()
+ }
+
+ @Test
+ fun testFakeMetricsEventLogger_logEvent_clearAllEvents_returnsEmptyList() {
+ performanceMetricsEventLogger.logPerformanceMetric(metricLog1)
+ fakePerformanceMetricsEventLogger.clearAllPerformanceMetricsEvents()
+ val isListEmpty = fakePerformanceMetricsEventLogger.noPerformanceMetricsEventsPresent()
+
+ assertThat(isListEmpty).isTrue()
+ }
+
+ @Test
+ fun testFakeMetricsEventLogger_logMultipleEvents_clearAllEvents_returnsEmptyList() {
+ performanceMetricsEventLogger.logPerformanceMetric(metricLog1)
+ performanceMetricsEventLogger.logPerformanceMetric(metricLog2)
+ fakePerformanceMetricsEventLogger.clearAllPerformanceMetricsEvents()
+ val isListEmpty = fakePerformanceMetricsEventLogger.noPerformanceMetricsEventsPresent()
+
+ assertThat(isListEmpty).isTrue()
+ }
+
+ @Test
+ fun testFakeMetricsEventLogger_logEvent_returnsNonEmptyList() {
+ performanceMetricsEventLogger.logPerformanceMetric(metricLog1)
+ val isListEmpty = fakePerformanceMetricsEventLogger.noPerformanceMetricsEventsPresent()
+
+ assertThat(isListEmpty).isFalse()
+ }
+
+ @Test
+ fun testFakeMetricsEventLogger_logMultipleEvents_returnsNonEmptyList() {
+ performanceMetricsEventLogger.logPerformanceMetric(metricLog1)
+ performanceMetricsEventLogger.logPerformanceMetric(metricLog2)
+
+ val eventLogStatus1 = fakePerformanceMetricsEventLogger.hasPerformanceMetricsEventLogged(
+ metricLog1
+ )
+ val eventLogStatus2 = fakePerformanceMetricsEventLogger.hasPerformanceMetricsEventLogged(
+ metricLog2
+ )
+ val eventListStatus = fakePerformanceMetricsEventLogger.noPerformanceMetricsEventsPresent()
+
+ assertThat(eventListStatus).isFalse()
+ assertThat(eventLogStatus1).isTrue()
+ assertThat(eventLogStatus2).isTrue()
+ }
+
+ @Test
+ fun testGetOldestEvent_noEventsLogged_throwsException() {
+ assertThrows(NoSuchElementException::class) {
+ fakePerformanceMetricsEventLogger.getOldestPerformanceMetricsEvent()
+ }
+ }
+
+ @Test
+ fun testGetOldestEvent_oneEventLogged_returnsLoggedEvent() {
+ performanceMetricsEventLogger.logPerformanceMetric(metricLog1)
+
+ val oldestEvent = fakePerformanceMetricsEventLogger.getOldestPerformanceMetricsEvent()
+
+ assertThat(oldestEvent).isEqualTo(metricLog1)
+ }
+
+ @Test
+ fun testGetOldestEvent_twoEventsLogged_returnsFirstEventLogged() {
+ performanceMetricsEventLogger.logPerformanceMetric(metricLog2)
+ performanceMetricsEventLogger.logPerformanceMetric(metricLog1)
+
+ val oldestEvent = fakePerformanceMetricsEventLogger.getOldestPerformanceMetricsEvent()
+
+ assertThat(oldestEvent).isEqualTo(metricLog2)
+ }
+
+ @Test
+ fun testGetOldestEvent_twoEventsLogged_clearEvents_throwsException() {
+ performanceMetricsEventLogger.logPerformanceMetric(metricLog2)
+ performanceMetricsEventLogger.logPerformanceMetric(metricLog1)
+ fakePerformanceMetricsEventLogger.clearAllPerformanceMetricsEvents()
+
+ assertThrows(NoSuchElementException::class) {
+ fakePerformanceMetricsEventLogger.getOldestPerformanceMetricsEvent()
+ }
+ }
+
+ @Test
+ fun testGetOldestEvent_eventLogged_cleared_newEventLogged_returnsLatestEventLog() {
+ performanceMetricsEventLogger.logPerformanceMetric(metricLog2)
+ fakePerformanceMetricsEventLogger.clearAllPerformanceMetricsEvents()
+ performanceMetricsEventLogger.logPerformanceMetric(metricLog1)
+
+ val oldestEvent = fakePerformanceMetricsEventLogger.getOldestPerformanceMetricsEvent()
+
+ assertThat(oldestEvent).isEqualTo(metricLog1)
+ }
+
+ @Test
+ fun testGetMostRecentEvents_twoEvents_noEventsLogged_returnsEmptyList() {
+ val mostRecentEvents = fakePerformanceMetricsEventLogger.getMostRecentPerformanceMetricsEvents(
+ count = 2
+ )
+
+ assertThat(mostRecentEvents).isEmpty()
+ }
+
+ @Test
+ fun testGetMostRecentEvents_twoEvents_oneEventLogged_returnsOneItemList() {
+ performanceMetricsEventLogger.logPerformanceMetric(metricLog1)
+
+ val mostRecentEvents = fakePerformanceMetricsEventLogger.getMostRecentPerformanceMetricsEvents(
+ count = 2
+ )
+
+ assertThat(mostRecentEvents).containsExactly(metricLog1)
+ }
+
+ @Test
+ fun testGetMostRecentEvents_twoEvents_twoEventsLogged_returnsEventsInOrder() {
+ performanceMetricsEventLogger.logPerformanceMetric(metricLog2)
+ performanceMetricsEventLogger.logPerformanceMetric(metricLog1)
+
+ val mostRecentEvents = fakePerformanceMetricsEventLogger.getMostRecentPerformanceMetricsEvents(
+ count = 2
+ )
+
+ assertThat(mostRecentEvents).containsExactly(metricLog2, metricLog1).inOrder()
+ }
+
+ @Test
+ fun testGetMostRecentEvents_oneEvent_twoEventsLogged_returnsSingleLatestEvent() {
+ performanceMetricsEventLogger.logPerformanceMetric(metricLog2)
+ performanceMetricsEventLogger.logPerformanceMetric(metricLog1)
+
+ val mostRecentEvents = fakePerformanceMetricsEventLogger.getMostRecentPerformanceMetricsEvents(
+ count = 1
+ )
+
+ assertThat(mostRecentEvents).containsExactly(metricLog1)
+ }
+
+ @Test
+ fun testGetMostRecentEvents_zeroEvents_twoEventsLogged_returnsEmptyList() {
+ performanceMetricsEventLogger.logPerformanceMetric(metricLog2)
+ performanceMetricsEventLogger.logPerformanceMetric(metricLog1)
+
+ val mostRecentEvents = fakePerformanceMetricsEventLogger.getMostRecentPerformanceMetricsEvents(
+ count = 0
+ )
+
+ assertThat(mostRecentEvents).isEmpty()
+ }
+
+ @Test
+ fun testGetMostRecentEvents_negativeEvents_twoEventsLogged_throwsException() {
+ performanceMetricsEventLogger.logPerformanceMetric(metricLog2)
+ performanceMetricsEventLogger.logPerformanceMetric(metricLog1)
+
+ assertThrows(IllegalArgumentException::class) {
+ fakePerformanceMetricsEventLogger.getMostRecentPerformanceMetricsEvents(count = -1)
+ }
+ }
+
+ @Test
+ fun testGetMostRecentEvents_twoEventsLogged_eventsCleared_returnsEmptyList() {
+ performanceMetricsEventLogger.logPerformanceMetric(metricLog2)
+ performanceMetricsEventLogger.logPerformanceMetric(metricLog1)
+ fakePerformanceMetricsEventLogger.clearAllPerformanceMetricsEvents()
+
+ val mostRecentEvents = fakePerformanceMetricsEventLogger.getMostRecentPerformanceMetricsEvents(
+ count = 2
+ )
+
+ assertThat(mostRecentEvents).isEmpty()
+ }
+
+ @Test
+ fun testGetMostRecentEvents_eventLogged_cleared_newEventLogged_returnsNewestEvent() {
+ performanceMetricsEventLogger.logPerformanceMetric(metricLog1)
+ fakePerformanceMetricsEventLogger.clearAllPerformanceMetricsEvents()
+ performanceMetricsEventLogger.logPerformanceMetric(metricLog2)
+
+ val mostRecentEvents = fakePerformanceMetricsEventLogger.getMostRecentPerformanceMetricsEvents(
+ count = 2
+ )
+
+ assertThat(mostRecentEvents).containsExactly(metricLog2)
+ }
+
+ private fun setUpTestApplicationComponent() {
+ DaggerFakePerformanceMetricsEventLoggerTest_TestApplicationComponent.builder()
+ .setApplication(ApplicationProvider.getApplicationContext())
+ .build()
+ .inject(this)
+ }
+
+ // TODO(#89): Move this to a common test application component.
+ @Module
+ class TestModule {
+ @Provides
+ @Singleton
+ fun provideContext(application: Application): Context {
+ return application
+ }
+ }
+
+ // TODO(#89): Move this to a common test application component.
+ @Singleton
+ @Component(
+ modules = [
+ TestModule::class, TestLogReportingModule::class, RobolectricModule::class,
+ TestDispatcherModule::class, LogStorageModule::class, FakeOppiaClockModule::class
+ ]
+ )
+ interface TestApplicationComponent {
+ @Component.Builder
+ interface Builder {
+ @BindsInstance
+ fun setApplication(application: Application): Builder
+ fun build(): TestApplicationComponent
+ }
+
+ fun inject(fakePerformanceMetricsEventLoggerTest: FakePerformanceMetricsEventLoggerTest)
+ }
+}
diff --git a/testing/src/test/java/org/oppia/android/testing/junit/InitializeDefaultLocaleRuleCustomContextTest.kt b/testing/src/test/java/org/oppia/android/testing/junit/InitializeDefaultLocaleRuleCustomContextTest.kt
index ff396b8c9a1..51e520fb94b 100644
--- a/testing/src/test/java/org/oppia/android/testing/junit/InitializeDefaultLocaleRuleCustomContextTest.kt
+++ b/testing/src/test/java/org/oppia/android/testing/junit/InitializeDefaultLocaleRuleCustomContextTest.kt
@@ -50,7 +50,8 @@ import org.oppia.android.domain.onboarding.testing.ExpirationMetaDataRetrieverTe
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -254,7 +255,7 @@ class InitializeDefaultLocaleRuleCustomContextTest {
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverTestModule::class,
ViewBindingShimModule::class, RatioInputModule::class, NetworkConfigProdModule::class,
ApplicationStartupListenerModule::class, HintsAndSolutionConfigModule::class,
- LogUploadWorkerModule::class, WorkManagerConfigurationModule::class,
+ LogReportWorkerModule::class, WorkManagerConfigurationModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
ExplorationStorageModule::class, NetworkModule::class, HintsAndSolutionProdModule::class,
@@ -264,7 +265,7 @@ class InitializeDefaultLocaleRuleCustomContextTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/testing/src/test/java/org/oppia/android/testing/junit/InitializeDefaultLocaleRuleOmissionTest.kt b/testing/src/test/java/org/oppia/android/testing/junit/InitializeDefaultLocaleRuleOmissionTest.kt
index 455863ee05c..65b3bc82a08 100644
--- a/testing/src/test/java/org/oppia/android/testing/junit/InitializeDefaultLocaleRuleOmissionTest.kt
+++ b/testing/src/test/java/org/oppia/android/testing/junit/InitializeDefaultLocaleRuleOmissionTest.kt
@@ -47,7 +47,8 @@ import org.oppia.android.domain.onboarding.testing.ExpirationMetaDataRetrieverTe
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -130,7 +131,7 @@ class InitializeDefaultLocaleRuleOmissionTest {
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverTestModule::class,
ViewBindingShimModule::class, RatioInputModule::class, NetworkConfigProdModule::class,
ApplicationStartupListenerModule::class, HintsAndSolutionConfigModule::class,
- LogUploadWorkerModule::class, WorkManagerConfigurationModule::class,
+ LogReportWorkerModule::class, WorkManagerConfigurationModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
ExplorationStorageModule::class, NetworkModule::class, HintsAndSolutionProdModule::class,
@@ -140,7 +141,7 @@ class InitializeDefaultLocaleRuleOmissionTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/testing/src/test/java/org/oppia/android/testing/junit/InitializeDefaultLocaleRuleTest.kt b/testing/src/test/java/org/oppia/android/testing/junit/InitializeDefaultLocaleRuleTest.kt
index 79b77aefb03..a53e4b716e0 100644
--- a/testing/src/test/java/org/oppia/android/testing/junit/InitializeDefaultLocaleRuleTest.kt
+++ b/testing/src/test/java/org/oppia/android/testing/junit/InitializeDefaultLocaleRuleTest.kt
@@ -51,7 +51,8 @@ import org.oppia.android.domain.onboarding.testing.ExpirationMetaDataRetrieverTe
import org.oppia.android.domain.oppialogger.LogStorageModule
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
-import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.question.QuestionModule
@@ -134,7 +135,7 @@ class InitializeDefaultLocaleRuleTest {
PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverTestModule::class,
ViewBindingShimModule::class, RatioInputModule::class, NetworkConfigProdModule::class,
ApplicationStartupListenerModule::class, HintsAndSolutionConfigModule::class,
- LogUploadWorkerModule::class, WorkManagerConfigurationModule::class,
+ LogReportWorkerModule::class, WorkManagerConfigurationModule::class,
FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
ExplorationStorageModule::class, NetworkModule::class, HintsAndSolutionProdModule::class,
@@ -144,7 +145,7 @@ class InitializeDefaultLocaleRuleTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/testing/src/test/java/org/oppia/android/testing/robolectric/OppiaShadowActivityManagerTest.kt b/testing/src/test/java/org/oppia/android/testing/robolectric/OppiaShadowActivityManagerTest.kt
new file mode 100644
index 00000000000..b6b6df2c20c
--- /dev/null
+++ b/testing/src/test/java/org/oppia/android/testing/robolectric/OppiaShadowActivityManagerTest.kt
@@ -0,0 +1,160 @@
+package org.oppia.android.testing.robolectric
+
+import android.app.ActivityManager
+import android.app.Application
+import android.content.Context
+import android.os.Build
+import android.os.Debug
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.google.common.truth.Truth.assertThat
+import dagger.BindsInstance
+import dagger.Component
+import dagger.Module
+import dagger.Provides
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.robolectric.Shadows.shadowOf
+import org.robolectric.annotation.Config
+import org.robolectric.annotation.LooperMode
+import javax.inject.Inject
+import javax.inject.Singleton
+
+/** Tests for [OppiaShadowActivityManager]. */
+// FunctionName: test names are conventionally named with underscores.
+@Suppress("FunctionName")
+@RunWith(AndroidJUnit4::class)
+@LooperMode(LooperMode.Mode.PAUSED)
+@Config(
+ manifest = Config.NONE,
+ sdk = [Build.VERSION_CODES.P],
+ shadows = [OppiaShadowActivityManager::class]
+)
+class OppiaShadowActivityManagerTest {
+ @Inject
+ lateinit var context: Context
+
+ private val oppiaShadowActivityManager: OppiaShadowActivityManager
+ get() = shadowOf(
+ context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
+ ) as OppiaShadowActivityManager
+
+ @Before
+ fun setUp() {
+ setUpTestApplicationComponent()
+ }
+
+ @Test
+ fun testCustomShadow_initialState_debugMemoryInfo_returnsDefaultState() {
+ val defaultDebugMemoryShadow = oppiaShadowActivityManager.getProcessMemoryInfo(intArrayOf(0))
+ assertThat(defaultDebugMemoryShadow).isNotNull()
+ assertThat(defaultDebugMemoryShadow?.size).isNotEqualTo(0)
+ assertThat(defaultDebugMemoryShadow?.get(0)?.totalPss).isEqualTo(0)
+ }
+
+ @Test
+ fun testCustomShadow_initialState_memoryInfo_returnsDefaultState() {
+ val outInfo = ActivityManager.MemoryInfo()
+ oppiaShadowActivityManager.getMemoryInfo(outInfo)
+ assertThat(outInfo.totalMem).isEqualTo(0)
+ assertThat(outInfo.availMem).isEqualTo(0)
+ assertThat(outInfo.lowMemory).isEqualTo(false)
+ assertThat(outInfo.threshold).isEqualTo(0)
+ }
+
+ @Test
+ fun testCustomShadow_setDebugMemoryInfo_returnsCorrectValue() {
+ val debugMemoryInfo = Debug.MemoryInfo().apply {
+ this.nativePss = 2
+ this.dalvikPss = 1
+ this.otherPss = 3
+ }
+ oppiaShadowActivityManager.setProcessMemoryInfo(debugMemoryInfo)
+
+ val returnedDebugMemoryInfo = oppiaShadowActivityManager.getProcessMemoryInfo(intArrayOf(0))
+ assertThat(returnedDebugMemoryInfo?.get(0)?.nativePss).isEqualTo(2)
+ assertThat(returnedDebugMemoryInfo?.get(0)?.dalvikPss).isEqualTo(1)
+ assertThat(returnedDebugMemoryInfo?.get(0)?.otherPss).isEqualTo(3)
+ // Since totalPss = nativePss + dalvikPss + otherPss.
+ assertThat(returnedDebugMemoryInfo?.get(0)?.totalPss).isEqualTo(6)
+ }
+
+ @Test
+ fun testCustomShadow_setMemoryInfo_returnsCorrectOutInfo() {
+ val memoryInfo = ActivityManager.MemoryInfo().apply {
+ this.availMem = 1
+ this.totalMem = 2
+ this.lowMemory = true
+ this.threshold = 10
+ }
+ oppiaShadowActivityManager.setMemoryInfo(memoryInfo)
+
+ val outInfo = ActivityManager.MemoryInfo()
+ oppiaShadowActivityManager.getMemoryInfo(outInfo)
+ assertThat(outInfo.totalMem).isEqualTo(2)
+ assertThat(outInfo.availMem).isEqualTo(1)
+ assertThat(outInfo.lowMemory).isEqualTo(true)
+ assertThat(outInfo.threshold).isEqualTo(10)
+ }
+
+ @Test
+ fun testCustomShadow_setMemoryInfo_setDataInOutInfo_returnsCorrectDataInOutInfo() {
+ val memoryInfo = ActivityManager.MemoryInfo().apply {
+ this.availMem = 1
+ this.totalMem = 2
+ this.lowMemory = true
+ this.threshold = 10
+ }
+ oppiaShadowActivityManager.setMemoryInfo(memoryInfo)
+
+ val outInfo = ActivityManager.MemoryInfo().apply {
+ this.availMem = 5
+ this.totalMem = 3
+ this.lowMemory = false
+ this.threshold = 43
+ }
+
+ oppiaShadowActivityManager.getMemoryInfo(outInfo)
+ assertThat(outInfo.totalMem).isEqualTo(2)
+ assertThat(outInfo.availMem).isEqualTo(1)
+ assertThat(outInfo.lowMemory).isTrue()
+ assertThat(outInfo.threshold).isEqualTo(10)
+ }
+
+ private fun setUpTestApplicationComponent() {
+ DaggerOppiaShadowActivityManagerTest_TestApplicationComponent.builder()
+ .setApplication(ApplicationProvider.getApplicationContext())
+ .build()
+ .inject(this)
+ }
+
+ // TODO(#89): Move this to a common test application component.
+ @Module
+ class TestModule {
+ @Provides
+ @Singleton
+ fun provideContext(application: Application): Context {
+ return application
+ }
+ }
+
+ // TODO(#89): Move this to a common test application component.
+ @Singleton
+ @Component(
+ modules = [
+ TestModule::class
+ ]
+ )
+ interface TestApplicationComponent {
+ @Component.Builder
+ interface Builder {
+ @BindsInstance
+ fun setApplication(application: Application): Builder
+
+ fun build(): TestApplicationComponent
+ }
+
+ fun inject(oppiaShadowActivityManagerTest: OppiaShadowActivityManagerTest)
+ }
+}
diff --git a/testing/src/test/java/org/oppia/android/testing/robolectric/OppiaShadowTrafficStatsTest.kt b/testing/src/test/java/org/oppia/android/testing/robolectric/OppiaShadowTrafficStatsTest.kt
new file mode 100644
index 00000000000..4532c593db4
--- /dev/null
+++ b/testing/src/test/java/org/oppia/android/testing/robolectric/OppiaShadowTrafficStatsTest.kt
@@ -0,0 +1,111 @@
+package org.oppia.android.testing.robolectric
+
+import android.app.Application
+import android.content.Context
+import android.net.TrafficStats
+import android.os.Build
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.google.common.truth.Truth.assertThat
+import dagger.BindsInstance
+import dagger.Component
+import dagger.Module
+import dagger.Provides
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.robolectric.annotation.Config
+import org.robolectric.annotation.LooperMode
+import org.robolectric.shadow.api.Shadow
+import javax.inject.Inject
+import javax.inject.Singleton
+
+private const val ARBITRARY_UID = 0
+
+/** Tests for [OppiaShadowTrafficStats]. */
+// FunctionName: test names are conventionally named with underscores.
+@Suppress("FunctionName")
+@RunWith(AndroidJUnit4::class)
+@LooperMode(LooperMode.Mode.PAUSED)
+@Config(
+ manifest = Config.NONE,
+ sdk = [Build.VERSION_CODES.P],
+ shadows = [OppiaShadowTrafficStats::class]
+)
+class OppiaShadowTrafficStatsTest {
+
+ @Inject
+ lateinit var context: Context
+
+ private val oppiaShadowTrafficStats: OppiaShadowTrafficStats
+ get() =
+ Shadow.extract(Shadow.newInstanceOf(TrafficStats::class.java)) as OppiaShadowTrafficStats
+
+ @Before
+ fun setUp() {
+ setUpTestApplicationComponent()
+ }
+
+ @After
+ fun tearDown() {
+ // Make sure this is reset between tests.
+ OppiaShadowTrafficStats.reset()
+ }
+
+ @Test
+ fun testCustomShadow_initialState_returnsDefaultValuesForTxAndRxBytes() {
+ assertThat(OppiaShadowTrafficStats.getUidRxBytes(ARBITRARY_UID)).isEqualTo(0L)
+ assertThat(OppiaShadowTrafficStats.getUidTxBytes(ARBITRARY_UID)).isEqualTo(0L)
+ }
+
+ @Test
+ fun testCustomShadow_setUidTxBytes_returnsCorrectTxBytesValue() {
+ oppiaShadowTrafficStats.setUidTxBytes(9)
+ assertThat(OppiaShadowTrafficStats.getUidTxBytes(ARBITRARY_UID)).isEqualTo(9L)
+ assertThat(OppiaShadowTrafficStats.getUidRxBytes(ARBITRARY_UID)).isEqualTo(0)
+ }
+
+ @Test
+ fun testCustomShadow_setUidRxBytes_returnsCorrectTxBytesValue() {
+ oppiaShadowTrafficStats.setUidRxBytes(9)
+ assertThat(OppiaShadowTrafficStats.getUidRxBytes(ARBITRARY_UID)).isEqualTo(9L)
+ assertThat(OppiaShadowTrafficStats.getUidTxBytes(ARBITRARY_UID)).isEqualTo(0)
+ }
+
+ private fun setUpTestApplicationComponent() {
+ DaggerOppiaShadowTrafficStatsTest_TestApplicationComponent.builder()
+ .setApplication(ApplicationProvider.getApplicationContext())
+ .build()
+ .inject(this)
+ }
+
+ // TODO(#89): Move this to a common test application component.
+ @Module
+ class TestModule {
+ @Provides
+ @Singleton
+ fun provideContext(application: Application): Context {
+ return application
+ }
+ }
+
+ // TODO(#89): Move this to a common test application component.
+ @Singleton
+ @Component(
+ modules = [
+ TestModule::class
+ ]
+ )
+ interface TestApplicationComponent {
+ @Component.Builder
+ interface Builder {
+ @BindsInstance
+ fun setApplication(application: Application): Builder
+
+ fun build(): TestApplicationComponent
+ }
+
+ fun inject(oppiaShadowTrafficStatsTest: OppiaShadowTrafficStatsTest)
+ }
+}
diff --git a/utility/BUILD.bazel b/utility/BUILD.bazel
index 2dabd0d1216..522bd9744c0 100644
--- a/utility/BUILD.bazel
+++ b/utility/BUILD.bazel
@@ -109,7 +109,12 @@ TEST_DEPS = [
"//model/src/main/proto:test_models",
"//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/mockito",
+ "//testing/src/main/java/org/oppia/android/testing/platformparameter:test_module",
+ "//testing/src/main/java/org/oppia/android/testing/robolectric:oppia_shadow_activity_manager",
+ "//testing/src/main/java/org/oppia/android/testing/robolectric:oppia_shadow_traffic_stats",
"//testing/src/main/java/org/oppia/android/testing/robolectric:test_module",
"//testing/src/main/java/org/oppia/android/testing/threading:test_module",
"//testing/src/main/java/org/oppia/android/testing/time:test_module",
@@ -128,6 +133,9 @@ TEST_DEPS = [
"//utility/src/main/java/org/oppia/android/util/extensions:bundle_extensions",
"//utility/src/main/java/org/oppia/android/util/locale:prod_module",
"//utility/src/main/java/org/oppia/android/util/logging:event_bundle_creator",
+ "//utility/src/main/java/org/oppia/android/util/logging/firebase:prod_module",
+ "//utility/src/main/java/org/oppia/android/util/logging/performancemetrics:performance_metrics_assessor_module",
+ "//utility/src/main/java/org/oppia/android/util/logging/performancemetrics:performance_metrics_configurations_module",
"//utility/src/main/java/org/oppia/android/util/networking:debug_module",
"//utility/src/main/java/org/oppia/android/util/parser/html:tag_handlers",
"//utility/src/main/java/org/oppia/android/util/parser/image:glide_image_loader",
diff --git a/utility/src/main/java/org/oppia/android/util/logging/BUILD.bazel b/utility/src/main/java/org/oppia/android/util/logging/BUILD.bazel
index 0354a058096..a96279e3f68 100644
--- a/utility/src/main/java/org/oppia/android/util/logging/BUILD.bazel
+++ b/utility/src/main/java/org/oppia/android/util/logging/BUILD.bazel
@@ -126,6 +126,18 @@ kt_android_library(
],
)
+kt_android_library(
+ name = "metric_log_scheduler",
+ srcs = [
+ "MetricLogScheduler.kt",
+ ],
+ visibility = ["//:oppia_api_visibility"],
+ deps = [
+ "//third_party:androidx_work_work-runtime",
+ "//third_party:androidx_work_work-runtime-ktx",
+ ],
+)
+
kt_android_library(
name = "sync_status_manager",
srcs = [
diff --git a/utility/src/main/java/org/oppia/android/util/logging/MetricLogScheduler.kt b/utility/src/main/java/org/oppia/android/util/logging/MetricLogScheduler.kt
new file mode 100644
index 00000000000..463179cf15a
--- /dev/null
+++ b/utility/src/main/java/org/oppia/android/util/logging/MetricLogScheduler.kt
@@ -0,0 +1,31 @@
+package org.oppia.android.util.logging
+
+import androidx.work.PeriodicWorkRequest
+import androidx.work.WorkManager
+
+/** Scheduler for scheduling metric log reports related to the performance of the application. */
+interface MetricLogScheduler {
+ /**
+ * Enqueues a [workRequest] using the [workManager] for scheduling metric collection of periodic
+ * metrics like network and cpu usage.
+ */
+ fun enqueueWorkRequestForPeriodicBackgroundMetrics(
+ workManager: WorkManager,
+ workRequest: PeriodicWorkRequest
+ )
+
+ /**
+ * Enqueues a [workRequest] using the [workManager] for scheduling metric collection of storage
+ * usage of the application on the current device.
+ */
+ fun enqueueWorkRequestForStorageUsage(workManager: WorkManager, workRequest: PeriodicWorkRequest)
+
+ /**
+ * Enqueues a [workRequest] using the [workManager] for scheduling metric collection of periodic
+ * ui metrics like memory usage.
+ */
+ fun enqueueWorkRequestForPeriodicUiMetrics(
+ workManager: WorkManager,
+ workRequest: PeriodicWorkRequest
+ )
+}
diff --git a/utility/src/main/java/org/oppia/android/util/logging/firebase/BUILD.bazel b/utility/src/main/java/org/oppia/android/util/logging/firebase/BUILD.bazel
index 66454426511..b67cff7f82b 100644
--- a/utility/src/main/java/org/oppia/android/util/logging/firebase/BUILD.bazel
+++ b/utility/src/main/java/org/oppia/android/util/logging/firebase/BUILD.bazel
@@ -24,6 +24,7 @@ kt_android_library(
],
deps = [
"//model/src/main/proto:event_logger_java_proto_lite",
+ "//model/src/main/proto:performance_metrics_event_logger_java_proto_lite",
"//third_party:androidx_work_work-runtime",
"//third_party:androidx_work_work-runtime-ktx",
"//third_party:com_google_firebase_firebase-analytics",
@@ -32,6 +33,7 @@ kt_android_library(
"//utility/src/main/java/org/oppia/android/util/logging:event_logger",
"//utility/src/main/java/org/oppia/android/util/logging:log_uploader",
"//utility/src/main/java/org/oppia/android/util/logging:sync_status_manager",
+ "//utility/src/main/java/org/oppia/android/util/logging/performancemetrics:performance_metrics_event_logger",
"//utility/src/main/java/org/oppia/android/util/networking:network_connection_util",
],
)
diff --git a/utility/src/main/java/org/oppia/android/util/logging/firebase/DebugLogReportingModule.kt b/utility/src/main/java/org/oppia/android/util/logging/firebase/DebugLogReportingModule.kt
index 0b628a3190e..d31b656aba3 100644
--- a/utility/src/main/java/org/oppia/android/util/logging/firebase/DebugLogReportingModule.kt
+++ b/utility/src/main/java/org/oppia/android/util/logging/firebase/DebugLogReportingModule.kt
@@ -5,6 +5,7 @@ import dagger.Module
import dagger.Provides
import org.oppia.android.util.logging.EventLogger
import org.oppia.android.util.logging.ExceptionLogger
+import org.oppia.android.util.logging.performancemetrics.PerformanceMetricsEventLogger
import javax.inject.Singleton
/** Provides debug log reporting dependencies. */
@@ -18,4 +19,11 @@ class DebugLogReportingModule {
@Provides
@Singleton
fun provideDebugEventLogger(debugEventLogger: DebugEventLogger): EventLogger = debugEventLogger
+
+ @Provides
+ @Singleton
+ fun providePerformanceMetricsEventLogger(
+ factory: FirebaseEventLogger.Factory
+ ): PerformanceMetricsEventLogger =
+ factory.createPerformanceMetricEventLogger()
}
diff --git a/utility/src/main/java/org/oppia/android/util/logging/firebase/FirebaseEventLogger.kt b/utility/src/main/java/org/oppia/android/util/logging/firebase/FirebaseEventLogger.kt
index a4f61516e54..b2a1f71d4ef 100644
--- a/utility/src/main/java/org/oppia/android/util/logging/firebase/FirebaseEventLogger.kt
+++ b/utility/src/main/java/org/oppia/android/util/logging/firebase/FirebaseEventLogger.kt
@@ -5,8 +5,10 @@ import android.content.Context
import android.os.Bundle
import com.google.firebase.analytics.FirebaseAnalytics
import org.oppia.android.app.model.EventLog
+import org.oppia.android.app.model.OppiaMetricLog
import org.oppia.android.util.logging.EventBundleCreator
import org.oppia.android.util.logging.EventLogger
+import org.oppia.android.util.logging.performancemetrics.PerformanceMetricsEventLogger
import org.oppia.android.util.networking.NetworkConnectionUtil
import java.util.Locale
import javax.inject.Inject
@@ -19,7 +21,7 @@ class FirebaseEventLogger private constructor(
private val firebaseAnalytics: FirebaseAnalytics,
private val networkConnectionUtil: NetworkConnectionUtil,
private val eventBundleCreator: EventBundleCreator
-) : EventLogger {
+) : EventLogger, PerformanceMetricsEventLogger {
/**
* Logs an event to Firebase Analytics with [NETWORK_USER_PROPERTY] and [COUNTRY_USER_PROPERTY].
*/
@@ -32,6 +34,13 @@ class FirebaseEventLogger private constructor(
firebaseAnalytics.setUserProperty(NETWORK_USER_PROPERTY, getNetworkStatus())
}
+ /**
+ * Logs a performance metric to Firebase Analytics with [NETWORK_USER_PROPERTY] and [COUNTRY_USER_PROPERTY].
+ */
+ override fun logPerformanceMetric(oppiaMetricLog: OppiaMetricLog) {
+ // TODO(#4335): Add implementation to upload performance metrics logs to firebase.
+ }
+
private fun getNetworkStatus(): String {
return when (networkConnectionUtil.getCurrentConnectionStatus()) {
NetworkConnectionUtil.ProdConnectionStatus.LOCAL ->
@@ -57,8 +66,20 @@ class FirebaseEventLogger private constructor(
* Returns a new [FirebaseEventLogger] for the current application context.
*
* Generally, only one of these needs to be created per application.
+ *
+ * This [FirebaseEventLogger] implements the [EventLogger] for facilitating analytics log
+ * reporting.
*/
fun create(): EventLogger =
FirebaseEventLogger(firebaseAnalytics, networkConnectionUtil, eventBundleCreator)
+
+ /**
+ * Returns a new [FirebaseEventLogger] for the current application context.
+ *
+ * This [FirebaseEventLogger] implements the [PerformanceMetricsEventLogger] for facilitating
+ * performance metrics log reporting.
+ */
+ fun createPerformanceMetricEventLogger(): PerformanceMetricsEventLogger =
+ FirebaseEventLogger(firebaseAnalytics, networkConnectionUtil, eventBundleCreator)
}
}
diff --git a/utility/src/main/java/org/oppia/android/util/logging/firebase/LogReportingModule.kt b/utility/src/main/java/org/oppia/android/util/logging/firebase/LogReportingModule.kt
index 21d8fd20345..aaa8bd329c4 100644
--- a/utility/src/main/java/org/oppia/android/util/logging/firebase/LogReportingModule.kt
+++ b/utility/src/main/java/org/oppia/android/util/logging/firebase/LogReportingModule.kt
@@ -5,6 +5,7 @@ import dagger.Module
import dagger.Provides
import org.oppia.android.util.logging.EventLogger
import org.oppia.android.util.logging.ExceptionLogger
+import org.oppia.android.util.logging.performancemetrics.PerformanceMetricsEventLogger
import javax.inject.Singleton
/** Provides Firebase-specific logging implementations. */
@@ -18,4 +19,11 @@ class LogReportingModule {
@Provides
@Singleton
fun provideEventLogger(factory: FirebaseEventLogger.Factory): EventLogger = factory.create()
+
+ @Provides
+ @Singleton
+ fun providePerformanceMetricsEventLogger(
+ factory: FirebaseEventLogger.Factory
+ ): PerformanceMetricsEventLogger =
+ factory.createPerformanceMetricEventLogger()
}
diff --git a/utility/src/main/java/org/oppia/android/util/logging/performancemetrics/BUILD.bazel b/utility/src/main/java/org/oppia/android/util/logging/performancemetrics/BUILD.bazel
new file mode 100644
index 00000000000..3e83fdcdb06
--- /dev/null
+++ b/utility/src/main/java/org/oppia/android/util/logging/performancemetrics/BUILD.bazel
@@ -0,0 +1,71 @@
+"""
+General purpose utilities for performance metrics logging.
+"""
+
+load("@dagger//:workspace_defs.bzl", "dagger_rules")
+load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_android_library")
+
+kt_android_library(
+ name = "performance_metrics_event_logger",
+ srcs = [
+ "PerformanceMetricsEventLogger.kt",
+ ],
+ visibility = ["//:oppia_api_visibility"],
+ deps = [
+ "//model/src/main/proto:performance_metrics_event_logger_java_proto_lite",
+ ],
+)
+
+kt_android_library(
+ name = "performance_metrics_assessor",
+ srcs = [
+ "PerformanceMetricsAssessor.kt",
+ ],
+ visibility = ["//:oppia_api_visibility"],
+ deps = [
+ "//model/src/main/proto:performance_metrics_event_logger_java_proto_lite",
+ ],
+)
+
+kt_android_library(
+ name = "performance_metrics_assessor_module",
+ srcs = [
+ "PerformanceMetricsAssessorModule.kt",
+ ],
+ visibility = ["//:oppia_prod_module_visibility"],
+ deps = [
+ ":dagger",
+ ":performance_metrics_assessor_impl",
+ "//model/src/main/proto:performance_metrics_event_logger_java_proto_lite",
+ "//third_party:javax_inject_javax_inject",
+ ],
+)
+
+kt_android_library(
+ name = "performance_metrics_assessor_impl",
+ srcs = [
+ "PerformanceMetricsAssessorImpl.kt",
+ ],
+ visibility = ["//:oppia_api_visibility"],
+ deps = [
+ ":performance_metrics_assessor",
+ ":performance_metrics_configurations_module",
+ "//model/src/main/proto:performance_metrics_event_logger_java_proto_lite",
+ "//third_party:javax_inject_javax_inject",
+ ],
+)
+
+kt_android_library(
+ name = "performance_metrics_configurations_module",
+ srcs = [
+ "PerformanceMetricsConfigurationsModule.kt",
+ ],
+ visibility = ["//:oppia_prod_module_visibility"],
+ deps = [
+ ":dagger",
+ "//model/src/main/proto:performance_metrics_event_logger_java_proto_lite",
+ "//third_party:javax_inject_javax_inject",
+ ],
+)
+
+dagger_rules()
diff --git a/utility/src/main/java/org/oppia/android/util/logging/performancemetrics/PerformanceMetricsAssessor.kt b/utility/src/main/java/org/oppia/android/util/logging/performancemetrics/PerformanceMetricsAssessor.kt
new file mode 100644
index 00000000000..5bdd9ba5761
--- /dev/null
+++ b/utility/src/main/java/org/oppia/android/util/logging/performancemetrics/PerformanceMetricsAssessor.kt
@@ -0,0 +1,38 @@
+package org.oppia.android.util.logging.performancemetrics
+
+import org.oppia.android.app.model.OppiaMetricLog
+
+/** Utility to extract performance metrics from the underlying Android system. */
+interface PerformanceMetricsAssessor {
+
+ /** Returns the size of the app's installed APK file, in bytes. */
+ fun getApkSize(): Long
+
+ /**
+ * Returns the amount of storage usage by the app on user's device in bytes.
+ * This storage size is the cumulative size of app-specific files which include the application
+ * cache but not the apk size.
+ */
+ fun getUsedStorage(): Long
+
+ /** Returns the number of bytes sent by the application over a network since device reboot. */
+ fun getTotalSentBytes(): Long
+
+ /** Returns the number of bytes received by the application over a network since device reboot. */
+ fun getTotalReceivedBytes(): Long
+
+ /** Returns the amount of memory used by the application on the device in bytes. */
+ fun getTotalPssUsed(): Long
+
+ /**
+ * Returns the [OppiaMetricLog.StorageTier] of the device by analysing the total storage
+ * capacity of the device.
+ */
+ fun getDeviceStorageTier(): OppiaMetricLog.StorageTier
+
+ /**
+ * Returns the [OppiaMetricLog.MemoryTier] of the device by analysing the total memory
+ * capacity of the device.
+ */
+ fun getDeviceMemoryTier(): OppiaMetricLog.MemoryTier
+}
diff --git a/utility/src/main/java/org/oppia/android/util/logging/performancemetrics/PerformanceMetricsAssessorImpl.kt b/utility/src/main/java/org/oppia/android/util/logging/performancemetrics/PerformanceMetricsAssessorImpl.kt
new file mode 100644
index 00000000000..d8a0818c60c
--- /dev/null
+++ b/utility/src/main/java/org/oppia/android/util/logging/performancemetrics/PerformanceMetricsAssessorImpl.kt
@@ -0,0 +1,73 @@
+package org.oppia.android.util.logging.performancemetrics
+
+import android.app.ActivityManager
+import android.content.Context
+import android.net.TrafficStats
+import org.oppia.android.app.model.OppiaMetricLog
+import org.oppia.android.app.model.OppiaMetricLog.MemoryTier.HIGH_MEMORY_TIER
+import org.oppia.android.app.model.OppiaMetricLog.MemoryTier.LOW_MEMORY_TIER
+import org.oppia.android.app.model.OppiaMetricLog.MemoryTier.MEDIUM_MEMORY_TIER
+import org.oppia.android.app.model.OppiaMetricLog.StorageTier.HIGH_STORAGE
+import org.oppia.android.app.model.OppiaMetricLog.StorageTier.LOW_STORAGE
+import org.oppia.android.app.model.OppiaMetricLog.StorageTier.MEDIUM_STORAGE
+import java.io.File
+import javax.inject.Inject
+import javax.inject.Singleton
+
+/** Utility to extract performance metrics from the underlying Android system. */
+@Singleton
+class PerformanceMetricsAssessorImpl @Inject constructor(
+ private val context: Context,
+ @LowStorageTierUpperBound private val lowStorageTierUpperBound: Long,
+ @MediumStorageTierUpperBound private val mediumStorageTierUpperBound: Long,
+ @LowMemoryTierUpperBound private val lowMemoryTierUpperBound: Long,
+ @MediumMemoryTierUpperBound private val mediumMemoryTierUpperBound: Long
+) : PerformanceMetricsAssessor {
+
+ private val activityManager: ActivityManager by lazy {
+ context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
+ }
+
+ override fun getApkSize(): Long {
+ val apkPath =
+ context.packageManager.getPackageInfo(context.packageName, 0).applicationInfo.sourceDir
+ return File(apkPath).length()
+ }
+
+ override fun getUsedStorage(): Long {
+ val permanentStorageUsage = context.filesDir?.listFiles()?.map { it.length() }?.sum() ?: 0L
+ val cacheStorageUsage = context.cacheDir?.listFiles()?.map { it.length() }?.sum() ?: 0L
+ return permanentStorageUsage + cacheStorageUsage
+ }
+
+ override fun getTotalSentBytes(): Long = TrafficStats.getUidTxBytes(context.applicationInfo.uid)
+
+ override fun getTotalReceivedBytes(): Long =
+ TrafficStats.getUidRxBytes(context.applicationInfo.uid)
+
+ override fun getTotalPssUsed(): Long {
+ val pid = ActivityManager.RunningAppProcessInfo().pid
+ val processMemoryInfo = activityManager.getProcessMemoryInfo(intArrayOf(pid))
+ return processMemoryInfo?.map { it.totalPss }?.sum()?.toLong() ?: 0L
+ }
+
+ override fun getDeviceStorageTier(): OppiaMetricLog.StorageTier {
+ val usedStorage = getUsedStorage()
+ return when {
+ usedStorage <= lowStorageTierUpperBound -> LOW_STORAGE
+ usedStorage <= mediumStorageTierUpperBound -> MEDIUM_STORAGE
+ else -> HIGH_STORAGE
+ }
+ }
+
+ override fun getDeviceMemoryTier(): OppiaMetricLog.MemoryTier {
+ val memoryInfo = ActivityManager.MemoryInfo()
+ activityManager.getMemoryInfo(memoryInfo)
+ val totalMemory = memoryInfo.totalMem
+ return when {
+ totalMemory <= lowMemoryTierUpperBound -> LOW_MEMORY_TIER
+ totalMemory <= mediumMemoryTierUpperBound -> MEDIUM_MEMORY_TIER
+ else -> HIGH_MEMORY_TIER
+ }
+ }
+}
diff --git a/utility/src/main/java/org/oppia/android/util/logging/performancemetrics/PerformanceMetricsAssessorModule.kt b/utility/src/main/java/org/oppia/android/util/logging/performancemetrics/PerformanceMetricsAssessorModule.kt
new file mode 100644
index 00000000000..603ff9fe14b
--- /dev/null
+++ b/utility/src/main/java/org/oppia/android/util/logging/performancemetrics/PerformanceMetricsAssessorModule.kt
@@ -0,0 +1,14 @@
+package org.oppia.android.util.logging.performancemetrics
+
+import dagger.Module
+import dagger.Provides
+
+/** Provides production-specific performance metrics utilities related dependencies. */
+@Module
+class PerformanceMetricsAssessorModule {
+
+ @Provides
+ fun providePerformanceMetricsAssessor(
+ performanceMetricsAssessorImpl: PerformanceMetricsAssessorImpl
+ ): PerformanceMetricsAssessor = performanceMetricsAssessorImpl
+}
diff --git a/utility/src/main/java/org/oppia/android/util/logging/performancemetrics/PerformanceMetricsConfigurationsModule.kt b/utility/src/main/java/org/oppia/android/util/logging/performancemetrics/PerformanceMetricsConfigurationsModule.kt
new file mode 100644
index 00000000000..33e0b408446
--- /dev/null
+++ b/utility/src/main/java/org/oppia/android/util/logging/performancemetrics/PerformanceMetricsConfigurationsModule.kt
@@ -0,0 +1,51 @@
+package org.oppia.android.util.logging.performancemetrics
+
+import dagger.Module
+import dagger.Provides
+import org.oppia.android.app.model.OppiaMetricLog.MemoryTier
+import org.oppia.android.app.model.OppiaMetricLog.StorageTier
+import javax.inject.Qualifier
+
+private const val ONE_GIGABYTE = 1024L * 1024L * 1024L
+private const val TWO_GIGABYTES = ONE_GIGABYTE * 2L
+private const val THREE_GIGABYTES = ONE_GIGABYTE * 3L
+private const val THIRTY_TWO_GIGABYTES = ONE_GIGABYTE * 32L
+private const val SIXTY_FOUR_GIGABYTES = ONE_GIGABYTE * 64L
+
+/** Corresponds to a long value that denotes the non-inclusive upper bound of [StorageTier.LOW_STORAGE]. */
+@Qualifier
+annotation class LowStorageTierUpperBound
+
+/** Corresponds to a long value that denotes the inclusive upper bound of [StorageTier.MEDIUM_STORAGE]. */
+@Qualifier
+annotation class MediumStorageTierUpperBound
+
+/** Corresponds to a long value that denotes the non-inclusive upper bound of [MemoryTier.LOW_MEMORY_TIER]. */
+@Qualifier
+annotation class LowMemoryTierUpperBound
+
+/** Corresponds to a long value that denotes the inclusive upper bound of [MemoryTier.MEDIUM_MEMORY_TIER]. */
+@Qualifier
+annotation class MediumMemoryTierUpperBound
+
+/**
+ * Provides production-specific metrics-related storage and memory configuration values.
+ */
+@Module
+class PerformanceMetricsConfigurationsModule {
+ @Provides
+ @LowStorageTierUpperBound
+ fun provideLowStorageTierUpperBound(): Long = THIRTY_TWO_GIGABYTES
+
+ @Provides
+ @MediumStorageTierUpperBound
+ fun provideMediumStorageTierUpperBound(): Long = SIXTY_FOUR_GIGABYTES
+
+ @Provides
+ @LowMemoryTierUpperBound
+ fun provideLowMemoryTierUpperBound(): Long = TWO_GIGABYTES
+
+ @Provides
+ @MediumMemoryTierUpperBound
+ fun provideMediumMemoryTierUpperBound(): Long = THREE_GIGABYTES
+}
diff --git a/utility/src/main/java/org/oppia/android/util/logging/performancemetrics/PerformanceMetricsEventLogger.kt b/utility/src/main/java/org/oppia/android/util/logging/performancemetrics/PerformanceMetricsEventLogger.kt
new file mode 100644
index 00000000000..a224aa08b70
--- /dev/null
+++ b/utility/src/main/java/org/oppia/android/util/logging/performancemetrics/PerformanceMetricsEventLogger.kt
@@ -0,0 +1,13 @@
+package org.oppia.android.util.logging.performancemetrics
+
+import org.oppia.android.app.model.OppiaMetricLog
+
+/** Logger for uploading performance metrics event logs to remote services. */
+interface PerformanceMetricsEventLogger {
+ /**
+ * Logs a performance metric to remote services.
+ *
+ * @param oppiaMetricLog refers to the log object which contains all the relevant data to be reported.
+ */
+ fun logPerformanceMetric(oppiaMetricLog: OppiaMetricLog)
+}
diff --git a/utility/src/test/java/org/oppia/android/util/logging/performancemetrics/PerformanceMetricsAssessorImplTest.kt b/utility/src/test/java/org/oppia/android/util/logging/performancemetrics/PerformanceMetricsAssessorImplTest.kt
new file mode 100644
index 00000000000..d6b3cb6185e
--- /dev/null
+++ b/utility/src/test/java/org/oppia/android/util/logging/performancemetrics/PerformanceMetricsAssessorImplTest.kt
@@ -0,0 +1,343 @@
+package org.oppia.android.util.logging.performancemetrics
+
+import android.app.ActivityManager
+import android.app.Application
+import android.content.Context
+import android.content.pm.PackageInfo
+import android.net.TrafficStats
+import android.os.Debug
+import androidx.test.core.app.ApplicationProvider
+import com.google.common.truth.Truth.assertThat
+import dagger.BindsInstance
+import dagger.Component
+import dagger.Module
+import dagger.Provides
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.oppia.android.app.model.OppiaMetricLog
+import org.oppia.android.testing.TestLogReportingModule
+import org.oppia.android.testing.junit.OppiaParameterizedTestRunner
+import org.oppia.android.testing.junit.OppiaParameterizedTestRunner.Parameter
+import org.oppia.android.testing.junit.OppiaParameterizedTestRunner.RunParameterized
+import org.oppia.android.testing.junit.OppiaParameterizedTestRunner.SelectRunnerPlatform
+import org.oppia.android.testing.junit.ParameterizedRobolectricTestRunner
+import org.oppia.android.testing.platformparameter.TestPlatformParameterModule
+import org.oppia.android.testing.robolectric.OppiaShadowActivityManager
+import org.oppia.android.testing.robolectric.OppiaShadowTrafficStats
+import org.oppia.android.testing.robolectric.RobolectricModule
+import org.oppia.android.testing.threading.TestDispatcherModule
+import org.oppia.android.testing.time.FakeOppiaClockModule
+import org.oppia.android.util.data.DataProvidersInjector
+import org.oppia.android.util.data.DataProvidersInjectorProvider
+import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EnableConsoleLog
+import org.oppia.android.util.logging.EnableFileLog
+import org.oppia.android.util.logging.GlobalLogLevel
+import org.oppia.android.util.logging.LogLevel
+import org.oppia.android.util.logging.SyncStatusModule
+import org.oppia.android.util.networking.NetworkConnectionUtilDebugModule
+import org.robolectric.Shadows.shadowOf
+import org.robolectric.annotation.Config
+import org.robolectric.annotation.LooperMode
+import org.robolectric.shadow.api.Shadow.extract
+import org.robolectric.shadow.api.Shadow.newInstanceOf
+import java.io.File
+import javax.inject.Inject
+import javax.inject.Singleton
+
+private const val TEST_APP_PATH = "TEST_APP_PATH"
+private const val TEST_APP_PATH_CACHE = "TEST_APP_PATH_CACHE"
+private const val TEST_APP_SUB_PATH = "TEST_APP_SUB_PATH"
+private const val TEST_APP_SEMI_SUB_PATH = "TEST_APP_SEMI_SUB_PATH"
+private const val TEST_FILE_NAME = "TEST_FILE_NAME"
+private const val ONE_KILOBYTE = 1024
+private const val ONE_MEGABYTE = ONE_KILOBYTE * 1024
+private const val TWO_MEGABYTES = ONE_MEGABYTE * 2L
+private const val TWO_AND_HALF_MEGABYTES = ONE_MEGABYTE * 2.5
+private const val THREE_MEGABYTES = ONE_MEGABYTE * 3L
+private const val ONE_GIGABYTE = ONE_MEGABYTE * 1024
+private const val TWO_GIGABYTES = ONE_GIGABYTE * 2L
+private const val THREE_GIGABYTES = ONE_GIGABYTE * 3L
+
+/** Tests for [PerformanceMetricsAssessorImpl]. */
+// FunctionName: test names are conventionally named with underscores.
+@Suppress("FunctionName")
+@LooperMode(LooperMode.Mode.PAUSED)
+@RunWith(OppiaParameterizedTestRunner::class)
+@SelectRunnerPlatform(ParameterizedRobolectricTestRunner::class)
+@Config(
+ application = PerformanceMetricsAssessorImplTest.TestApplication::class,
+ shadows = [OppiaShadowActivityManager::class, OppiaShadowTrafficStats::class]
+)
+class PerformanceMetricsAssessorImplTest {
+
+ @Parameter
+ var totalMemory: Long = Long.MIN_VALUE // Inited because primitives can't be lateinit.
+
+ @Inject
+ lateinit var performanceMetricsAssessorImpl: PerformanceMetricsAssessorImpl
+
+ @Inject
+ lateinit var context: Context
+
+ private val shadowActivityManager by lazy {
+ shadowOf(
+ context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
+ ) as OppiaShadowActivityManager
+ }
+
+ private val shadowTrafficStats by lazy {
+ extract(newInstanceOf(TrafficStats::class.java)) as OppiaShadowTrafficStats
+ }
+
+ @Before
+ fun setUp() {
+ setUpTestApplicationComponent()
+ }
+
+ @Test
+ fun testAssessor_createFilesWithContent_getTotalStorageUsed_retsCorrectStorageUsage() {
+ context.openFileOutput(TEST_APP_PATH, Context.MODE_PRIVATE)
+ .write(ByteArray(ONE_MEGABYTE))
+ File.createTempFile(TEST_FILE_NAME, null, context.cacheDir)
+ .writeBytes(ByteArray(ONE_MEGABYTE))
+
+ assertThat(performanceMetricsAssessorImpl.getUsedStorage()).isEqualTo(ONE_MEGABYTE * 2)
+ }
+
+ @Test
+ fun testAssessor_createFilesWithContent_withNesting_getTotStorageUsed_retsCorrectStorageUsage() {
+ val mainFile = File(TEST_APP_PATH)
+ val cacheFile = File.createTempFile(TEST_APP_PATH_CACHE, null, context.cacheDir)
+ val subFile = File(mainFile, TEST_APP_SUB_PATH)
+ val semiSubFile = File(subFile, TEST_APP_SEMI_SUB_PATH)
+
+ context.openFileOutput(TEST_APP_PATH, Context.MODE_PRIVATE).write(ByteArray(ONE_MEGABYTE))
+ cacheFile.writeBytes(ByteArray(ONE_MEGABYTE))
+ context.openFileOutput(subFile.name, Context.MODE_PRIVATE).write(ByteArray(ONE_MEGABYTE))
+ context.openFileOutput(semiSubFile.name, Context.MODE_PRIVATE).write(ByteArray(ONE_MEGABYTE))
+
+ assertThat(performanceMetricsAssessorImpl.getUsedStorage()).isEqualTo(ONE_MEGABYTE * 4)
+ }
+
+ @Test
+ fun testAssessor_writeBytesLowerThanLowTierHigherBound_retsLowStorageUsageTier() {
+ context.openFileOutput(TEST_APP_PATH, Context.MODE_PRIVATE)
+ .write(ByteArray(ONE_KILOBYTE))
+ assertThat(performanceMetricsAssessorImpl.getDeviceStorageTier())
+ .isEqualTo(OppiaMetricLog.StorageTier.LOW_STORAGE)
+ }
+
+ @Test
+ fun testAssessor_writeBytesEqualToLowTierHigherBound_retsLowStorageUsageTier() {
+ context.openFileOutput(TEST_APP_PATH, Context.MODE_PRIVATE)
+ .write(ByteArray(ONE_MEGABYTE))
+ assertThat(performanceMetricsAssessorImpl.getDeviceStorageTier())
+ .isEqualTo(OppiaMetricLog.StorageTier.LOW_STORAGE)
+ }
+
+ @Test
+ fun testAssessor_writeBytesGreaterThanMediumTierLowerBound_retsMediumStorageUsageTier() {
+ context.openFileOutput(TEST_APP_PATH, Context.MODE_PRIVATE)
+ .write(ByteArray(TWO_AND_HALF_MEGABYTES.toInt()))
+ assertThat(performanceMetricsAssessorImpl.getDeviceStorageTier())
+ .isEqualTo(OppiaMetricLog.StorageTier.MEDIUM_STORAGE)
+ }
+
+ @Test
+ fun testAssessor_writeBytesEqualToMedTierHigherBound_retsMediumStorageUsageTier() {
+ context.openFileOutput(TEST_APP_PATH, Context.MODE_PRIVATE)
+ .write(ByteArray(THREE_MEGABYTES.toInt()))
+ assertThat(performanceMetricsAssessorImpl.getDeviceStorageTier())
+ .isEqualTo(OppiaMetricLog.StorageTier.MEDIUM_STORAGE)
+ }
+
+ @Test
+ fun testAssessor_writeBytesGreaterThanHighTierLowerBound_retsHighStorageTier() {
+ context.openFileOutput(TEST_APP_PATH, Context.MODE_PRIVATE)
+ .write(ByteArray(TWO_MEGABYTES.toInt() * 2))
+ assertThat(performanceMetricsAssessorImpl.getDeviceStorageTier())
+ .isEqualTo(OppiaMetricLog.StorageTier.HIGH_STORAGE)
+ }
+
+ @Test
+ fun testAssessor_getBytesSent_returnsCorrectAmountOfNetworkBytesSent() {
+ shadowTrafficStats.setUidTxBytes(20L)
+
+ assertThat(performanceMetricsAssessorImpl.getTotalSentBytes()).isEqualTo(20L)
+ }
+
+ @Test
+ fun testAssessor_getBytesReceived_returnsCorrectAmountOfNetworkBytesReceived() {
+ shadowTrafficStats.setUidRxBytes(20L)
+
+ assertThat(performanceMetricsAssessorImpl.getTotalReceivedBytes()).isEqualTo(20L)
+ }
+
+ @Test
+ fun testAssessor_setProcessMemoryInfo_setTotalPss_returnsCorrectMemoryUsage() {
+ shadowActivityManager.setProcessMemoryInfo(
+ Debug.MemoryInfo().apply {
+ this.nativePss = 2
+ this.dalvikPss = 1
+ this.otherPss = 4
+ }
+ )
+
+ assertThat(performanceMetricsAssessorImpl.getTotalPssUsed()).isEqualTo(7)
+ }
+
+ @Test
+ fun testAssessor_removeCurrentApp_installTestApp_returnsCorrectApkSize() {
+ val shadowPackageManager = shadowOf(context.packageManager)
+ File(TEST_APP_PATH).writeBytes(ByteArray(ONE_MEGABYTE))
+ val applicationInfo = context.applicationInfo.apply {
+ this.sourceDir = TEST_APP_PATH
+ }
+ shadowPackageManager.removePackage(context.packageName)
+ shadowPackageManager.installPackage(
+ PackageInfo().apply {
+ this.packageName = context.packageName
+ this.applicationInfo = applicationInfo
+ }
+ )
+ val apkSize = performanceMetricsAssessorImpl.getApkSize()
+ assertThat(apkSize).isEqualTo(ONE_MEGABYTE)
+ }
+
+ @Test
+ @RunParameterized(
+ OppiaParameterizedTestRunner.Iteration("memoryEqualToLowerBound", "totalMemory=0"),
+ OppiaParameterizedTestRunner.Iteration("memoryInRange", "totalMemory=1147483648"),
+ OppiaParameterizedTestRunner.Iteration("memoryJustBelowUpperBound", "totalMemory=2147483647")
+ )
+ fun testAssessor_setTotalMemoryForLowMemoryRange_returnsCorrectLowMemoryTier() {
+ val memoryInfo = ActivityManager.MemoryInfo()
+ memoryInfo.totalMem = totalMemory
+ shadowActivityManager.setMemoryInfo(memoryInfo)
+ val memoryTier = performanceMetricsAssessorImpl.getDeviceMemoryTier()
+
+ assertThat(memoryTier).isEqualTo(OppiaMetricLog.MemoryTier.LOW_MEMORY_TIER)
+ }
+
+ @Test
+ @RunParameterized(
+ OppiaParameterizedTestRunner.Iteration("memoryEqualToLowerBound", "totalMemory=2147483649"),
+ OppiaParameterizedTestRunner.Iteration("memoryInRange", "totalMemory=2684354560"),
+ OppiaParameterizedTestRunner.Iteration("memoryEqualToUpperBound", "totalMemory=3221225472")
+ )
+ fun testAssessor_setTotalMemoryForMediumMemoryRange_retsCorrectMediumMemoryTier() {
+ val memoryInfo = ActivityManager.MemoryInfo()
+ memoryInfo.totalMem = totalMemory
+ shadowActivityManager.setMemoryInfo(memoryInfo)
+ val memoryTier = performanceMetricsAssessorImpl.getDeviceMemoryTier()
+
+ assertThat(memoryTier).isEqualTo(OppiaMetricLog.MemoryTier.MEDIUM_MEMORY_TIER)
+ }
+
+ @Test
+ @RunParameterized(
+ OppiaParameterizedTestRunner.Iteration("memoryEqualToLowerBound", "totalMemory=3221225473"),
+ OppiaParameterizedTestRunner.Iteration("memoryInRange", "totalMemory=5221225472"),
+ OppiaParameterizedTestRunner.Iteration(
+ "memoryEqualToMaxValue",
+ "totalMemory=9223372036854775807"
+ )
+ )
+ fun testAssessor_setTotalMemoryForHighMemoryRange_retsCorrectHighMemoryTier() {
+ val memoryInfo = ActivityManager.MemoryInfo()
+ memoryInfo.totalMem = totalMemory
+ shadowActivityManager.setMemoryInfo(memoryInfo)
+ val memoryTier = performanceMetricsAssessorImpl.getDeviceMemoryTier()
+
+ assertThat(memoryTier).isEqualTo(OppiaMetricLog.MemoryTier.HIGH_MEMORY_TIER)
+ }
+
+ private fun setUpTestApplicationComponent() {
+ ApplicationProvider.getApplicationContext().inject(this)
+ }
+
+ // TODO(#89): Move this to a common test application component.
+ @Module
+ class TestModule {
+
+ @Provides
+ @Singleton
+ fun providesContext(application: Application): Context = application
+
+ // TODO(#59): Either isolate these to their own shared test module, or use the real logging
+ // module in tests to avoid needing to specify these settings for tests.
+ @EnableConsoleLog
+ @Provides
+ fun provideEnableConsoleLog(): Boolean = true
+
+ @EnableFileLog
+ @Provides
+ fun provideEnableFileLog(): Boolean = false
+
+ @GlobalLogLevel
+ @Provides
+ fun provideGlobalLogLevel(): LogLevel = LogLevel.VERBOSE
+ }
+
+ @Module
+ class TestPerformanceMetricsAssessorModule {
+ @Provides
+ fun providePerformanceMetricsAssessor(
+ performanceMetricsAssessorImpl: PerformanceMetricsAssessorImpl
+ ): PerformanceMetricsAssessor = performanceMetricsAssessorImpl
+
+ @Provides
+ @LowStorageTierUpperBound
+ fun provideLowStorageTierUpperBound(): Long = TWO_MEGABYTES
+
+ @Provides
+ @MediumStorageTierUpperBound
+ fun provideMediumStorageTierUpperBound(): Long = THREE_MEGABYTES
+
+ @Provides
+ @LowMemoryTierUpperBound
+ fun provideLowMemoryTierUpperBound(): Long = TWO_GIGABYTES
+
+ @Provides
+ @MediumMemoryTierUpperBound
+ fun provideMediumMemoryTierUpperBound(): Long = THREE_GIGABYTES
+ }
+
+ // TODO(#89): Move this to a common test application component.
+ @Singleton
+ @Component(
+ modules = [
+ TestModule::class, TestLogReportingModule::class,
+ TestDispatcherModule::class, RobolectricModule::class, FakeOppiaClockModule::class,
+ NetworkConnectionUtilDebugModule::class, LocaleProdModule::class,
+ TestPlatformParameterModule::class, SyncStatusModule::class,
+ TestPerformanceMetricsAssessorModule::class
+ ]
+ )
+ interface TestApplicationComponent : DataProvidersInjector {
+ @Component.Builder
+ interface Builder {
+ @BindsInstance
+ fun setApplication(application: Application): Builder
+ fun build(): TestApplicationComponent
+ }
+
+ fun inject(performanceMetricsUtilsTest: PerformanceMetricsAssessorImplTest)
+ }
+
+ class TestApplication : Application(), DataProvidersInjectorProvider {
+ private val component: TestApplicationComponent by lazy {
+ DaggerPerformanceMetricsAssessorImplTest_TestApplicationComponent.builder()
+ .setApplication(this)
+ .build()
+ }
+
+ fun inject(performanceMetricsUtilsTest: PerformanceMetricsAssessorImplTest) {
+ component.inject(performanceMetricsUtilsTest)
+ }
+
+ override fun getDataProvidersInjector(): DataProvidersInjector = component
+ }
+}
diff --git a/utility/src/test/java/org/oppia/android/util/logging/performancemetrics/PerformanceMetricsAssessorModuleTest.kt b/utility/src/test/java/org/oppia/android/util/logging/performancemetrics/PerformanceMetricsAssessorModuleTest.kt
new file mode 100644
index 00000000000..6a88d8522a2
--- /dev/null
+++ b/utility/src/test/java/org/oppia/android/util/logging/performancemetrics/PerformanceMetricsAssessorModuleTest.kt
@@ -0,0 +1,91 @@
+package org.oppia.android.util.logging.performancemetrics
+
+import android.app.Application
+import android.content.Context
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.google.common.truth.Truth.assertThat
+import dagger.Binds
+import dagger.BindsInstance
+import dagger.Component
+import dagger.Module
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.oppia.android.testing.robolectric.RobolectricModule
+import org.oppia.android.testing.threading.TestDispatcherModule
+import org.oppia.android.util.data.DataProvidersInjector
+import org.oppia.android.util.data.DataProvidersInjectorProvider
+import org.oppia.android.util.logging.LoggerModule
+import org.oppia.android.util.logging.firebase.LogReportingModule
+import org.robolectric.annotation.Config
+import org.robolectric.annotation.LooperMode
+import javax.inject.Inject
+import javax.inject.Singleton
+
+/** Tests for [PerformanceMetricsAssessorModule]. */
+// FunctionName: test names are conventionally named with underscores.
+@Suppress("FunctionName")
+@RunWith(AndroidJUnit4::class)
+@LooperMode(LooperMode.Mode.PAUSED)
+@Config(application = PerformanceMetricsAssessorModuleTest.TestApplication::class)
+class PerformanceMetricsAssessorModuleTest {
+
+ @Inject
+ lateinit var performanceMetricsAssessor: PerformanceMetricsAssessor
+
+ @Before
+ fun setUp() {
+ setUpTestApplicationComponent()
+ }
+
+ @Test
+ fun testInjectAssessor_injectsPerformanceMetricsAssessorImpl() {
+ assertThat(performanceMetricsAssessor).isInstanceOf(PerformanceMetricsAssessorImpl::class.java)
+ }
+
+ private fun setUpTestApplicationComponent() {
+ ApplicationProvider.getApplicationContext().inject(this)
+ }
+
+ // TODO(#89): Move this to a common test application component.
+ @Module
+ interface TestModule {
+ @Binds
+ fun provideContext(application: Application): Context
+ }
+
+ // TODO(#89): Move this to a common test application component.
+ @Singleton
+ @Component(
+ modules = [
+ TestModule::class, PerformanceMetricsAssessorModule::class, LoggerModule::class,
+ TestDispatcherModule::class, LogReportingModule::class, RobolectricModule::class,
+ PerformanceMetricsConfigurationsModule::class
+ ]
+ )
+ interface TestApplicationComponent : DataProvidersInjector {
+ @Component.Builder
+ interface Builder {
+ @BindsInstance
+ fun setApplication(application: Application): Builder
+ fun build(): TestApplicationComponent
+ }
+
+ fun inject(test: PerformanceMetricsAssessorModuleTest)
+ }
+
+ class TestApplication : Application(), DataProvidersInjectorProvider {
+ private val component: TestApplicationComponent by lazy {
+ DaggerPerformanceMetricsAssessorModuleTest_TestApplicationComponent.builder()
+ .setApplication(this)
+ .build()
+ }
+
+ fun inject(test: PerformanceMetricsAssessorModuleTest) {
+ component.inject(test)
+ }
+
+ override fun getDataProvidersInjector(): DataProvidersInjector = component
+ }
+}
diff --git a/utility/src/test/java/org/oppia/android/util/logging/performancemetrics/PerformanceMetricsConfigurationsModuleTest.kt b/utility/src/test/java/org/oppia/android/util/logging/performancemetrics/PerformanceMetricsConfigurationsModuleTest.kt
new file mode 100644
index 00000000000..dde7045ad67
--- /dev/null
+++ b/utility/src/test/java/org/oppia/android/util/logging/performancemetrics/PerformanceMetricsConfigurationsModuleTest.kt
@@ -0,0 +1,121 @@
+package org.oppia.android.util.logging.performancemetrics
+
+import android.app.Application
+import android.content.Context
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.google.common.truth.Truth.assertThat
+import dagger.Binds
+import dagger.BindsInstance
+import dagger.Component
+import dagger.Module
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.oppia.android.testing.robolectric.RobolectricModule
+import org.oppia.android.testing.threading.TestDispatcherModule
+import org.oppia.android.util.data.DataProvidersInjector
+import org.oppia.android.util.data.DataProvidersInjectorProvider
+import org.oppia.android.util.logging.LoggerModule
+import org.oppia.android.util.logging.firebase.LogReportingModule
+import org.robolectric.annotation.Config
+import org.robolectric.annotation.LooperMode
+import javax.inject.Inject
+import javax.inject.Singleton
+
+private const val ONE_GIGABYTE = 1024L * 1024L * 1024L
+
+/** Tests for [PerformanceMetricsConfigurationsModule]. */
+// FunctionName: test names are conventionally named with underscores.
+@Suppress("FunctionName")
+@RunWith(AndroidJUnit4::class)
+@LooperMode(LooperMode.Mode.PAUSED)
+@Config(application = PerformanceMetricsConfigurationsModuleTest.TestApplication::class)
+class PerformanceMetricsConfigurationsModuleTest {
+
+ @JvmField
+ @field:[Inject MediumMemoryTierUpperBound]
+ var mediumMemoryTierUpperBound: Long = 0L
+
+ @JvmField
+ @field:[Inject LowMemoryTierUpperBound]
+ var lowMemoryTierUpperBound: Long = 0L
+
+ @JvmField
+ @field:[Inject LowStorageTierUpperBound]
+ var lowStorageTierUpperBound: Long = 0L
+
+ @JvmField
+ @field:[Inject MediumStorageTierUpperBound]
+ var mediumStorageTierUpperBound: Long = 0L
+
+ @Before
+ fun setUp() {
+ setUpTestApplicationComponent()
+ }
+
+ @Test
+ fun testLowStorageTierUpperBound_isThirtyTwoGigabytes() {
+ assertThat(lowStorageTierUpperBound).isEqualTo(ONE_GIGABYTE * 32L)
+ }
+
+ @Test
+ fun testMediumStorageTierUpperBound_isSixtyFourGigabytes() {
+ assertThat(mediumStorageTierUpperBound).isEqualTo(ONE_GIGABYTE * 64L)
+ }
+
+ @Test
+ fun testLowMemoryTierUpperBound_isTwoGigabytes() {
+ assertThat(lowMemoryTierUpperBound).isEqualTo(ONE_GIGABYTE * 2L)
+ }
+
+ @Test
+ fun testLowMemoryTierUpperBound_isThreeGigabytes() {
+ assertThat(mediumMemoryTierUpperBound).isEqualTo(ONE_GIGABYTE * 3L)
+ }
+
+ private fun setUpTestApplicationComponent() {
+ ApplicationProvider.getApplicationContext().inject(this)
+ }
+
+ // TODO(#89): Move this to a common test application component.
+ @Module
+ interface TestModule {
+ @Binds
+ fun provideContext(application: Application): Context
+ }
+
+ // TODO(#89): Move this to a common test application component.
+ @Singleton
+ @Component(
+ modules = [
+ TestModule::class, PerformanceMetricsAssessorModule::class, LoggerModule::class,
+ TestDispatcherModule::class, LogReportingModule::class, RobolectricModule::class,
+ PerformanceMetricsConfigurationsModule::class
+ ]
+ )
+ interface TestApplicationComponent : DataProvidersInjector {
+ @Component.Builder
+ interface Builder {
+ @BindsInstance
+ fun setApplication(application: Application): Builder
+ fun build(): TestApplicationComponent
+ }
+
+ fun inject(test: PerformanceMetricsConfigurationsModuleTest)
+ }
+
+ class TestApplication : Application(), DataProvidersInjectorProvider {
+ private val component: TestApplicationComponent by lazy {
+ DaggerPerformanceMetricsConfigurationsModuleTest_TestApplicationComponent.builder()
+ .setApplication(this)
+ .build()
+ }
+
+ fun inject(test: PerformanceMetricsConfigurationsModuleTest) {
+ component.inject(test)
+ }
+
+ override fun getDataProvidersInjector(): DataProvidersInjector = component
+ }
+}
From a7a8c33f06026ecac3595df08aeade5f322d2ccb Mon Sep 17 00:00:00 2001
From: Veena
Date: Mon, 5 Sep 2022 15:22:24 +0530
Subject: [PATCH 29/57] Fix #4546: ListItemLeadingMarginSpanTest moved to
shared test (#4552)
* Update selection_interaction_item.xml
* Update selection_interaction_item.xml
* Update return_to_topic_button_item.xml
* Update return_to_topic_button_item.xml
* Update image_region_selection_interaction_item.xml
* Update image_region_selection_interaction_item.xml
* Update ListItemLeadingMarginSpanTest.kt
---
.../org/oppia/android/app/parser/ListItemLeadingMarginSpanTest.kt | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename app/src/{sharedTest => test}/java/org/oppia/android/app/parser/ListItemLeadingMarginSpanTest.kt (100%)
diff --git a/app/src/sharedTest/java/org/oppia/android/app/parser/ListItemLeadingMarginSpanTest.kt b/app/src/test/java/org/oppia/android/app/parser/ListItemLeadingMarginSpanTest.kt
similarity index 100%
rename from app/src/sharedTest/java/org/oppia/android/app/parser/ListItemLeadingMarginSpanTest.kt
rename to app/src/test/java/org/oppia/android/app/parser/ListItemLeadingMarginSpanTest.kt
From 383984657ad4979a26ebc11d957fc8cc6ab445d4 Mon Sep 17 00:00:00 2001
From: Sarthak Agarwal
Date: Mon, 5 Sep 2022 21:35:42 +0530
Subject: [PATCH 30/57] Fixes #4335: Addition of support for uploading
performance metric logs (#4399)
* qualifiers and constants for metric record and upload times
* comments
* dagger provides for flags
* rename to enablePerformanceMetricCollection
* initial proto
* nit fixes
* nit fixes
* comments.
* nits
* nit
* updates.
* updates.
* nits.
* metric log inclusion.
* base setup.
* name correction.
* nits.
* nits.
* storage comment
* pss comment
* network usage comment.
* network usage comment - part 2.
* metric addition in proto definitions.
* metricLog --> loggableMetric
* proto definitions in oppiaLogger
* wording update for transmission
* dependency/api updates.
* nits.
* metric controller and oppiaLogger
* nits
* logger-controller pattern, single utils
* nits
* comments
* log uploading support
* nits
* nits
* performance metric event logger nits.
* nits.
* logger reinstated.
* nits
* deleting unused interfaces.
* log generator to metric log scheduler
* nits
* nits -- kdoc, code placing, readability
* nits -- kdoc, code placing, readability
* worker functions to schedule logging, renaming
* nits.
* clearing up build errors.
* nits.
* fixing build errors.
* removal of dependency from oppiaLogger and basing the entire implementation on Logger-Controller
* performanceMetricController tests + fakeLogger
* fakeLogger tests
* nits
* tests for the new logger.
* tests for the worker + renaming of package to logScheduler
* tests for work manager initializer
* initial base setup for utils test
* nits
* nits
* nit
* worker and initializer tests
* event bundle creator tests
* module tests
* nits
* performanceMetricsUtils tests
* nits
* renamed logUpload to logReport + nits
* nits
* nits
* review updates.
* nit
* review updates - 2
* isAppInForeground revamp
* isAppInForeground revamp
* nits
* domain tests repair
* app tests repair
* nits.
* nits.
* nits.
* nits.
* nit
* test update.
* test update.
* nit
* todo issue number update -- static check
* comments.
* nits.
* utils test + nits
* utils test + nits
* nits
* test rearrangement
* nits
* test fixes.
* nits
* nits
* nits
* memory and storage tier updates
* memory and storage tier updates
* updates.
* nits
* test file exemptions refactor due to file renaming.
* additional tests, nit fixes.
* activity manager shadow and assessor test
* nit
* nit
* shadow traffic stats + assessor test fix.
* custom shadow tests
* module deps
* tests
* nits
* metricLogScheduler refactor and test
* exemption removal
* nits
* updates.
* variable nits + parameterized test exemption
* app component dependencies.
* nits
* logging module bazel build, config module creation
* testing robolectric bazel module update
* domain bazel build fixes
* working oppia bazel build
* nits.
* nits.
* nit for bazel building
* addition of test file for module
* bazel tests fixes
* more fixes.
* reformatting
* nits
* nits
* dep fix
* deps fix
* deps fix
* nit
* nits
* nits
* gradle test fix.
* bazel oppia build
* test fixes -- renaming.
* deps addition
* previous merge correction
* nits
* updates.
* nits
* bazel update.
* nit
* nits.
---
.../oppialogger/loguploader/BUILD.bazel | 2 +
.../LogReportWorkManagerInitializer.kt | 23 ++
.../loguploader/LogUploadWorker.kt | 25 ++
.../loguploader/FakeLogUploader.kt | 11 +
.../LogReportWorkManagerInitializerTest.kt | 19 +
.../loguploader/LogUploadWorkerTest.kt | 70 +++-
.../oppia/android/util/logging/BUILD.bazel | 1 +
.../util/logging/EventBundleCreator.kt | 178 +++++++++
.../oppia/android/util/logging/LogUploader.kt | 6 +
.../logging/firebase/FirebaseEventLogger.kt | 13 +-
.../logging/firebase/FirebaseLogUploader.kt | 12 +
.../util/logging/EventBundleCreatorTest.kt | 363 ++++++++++++++++++
.../firebase/LogReportingModuleTest.kt | 150 ++++++++
13 files changed, 871 insertions(+), 2 deletions(-)
create mode 100644 utility/src/test/java/org/oppia/android/util/logging/firebase/LogReportingModuleTest.kt
diff --git a/domain/src/main/java/org/oppia/android/domain/oppialogger/loguploader/BUILD.bazel b/domain/src/main/java/org/oppia/android/domain/oppialogger/loguploader/BUILD.bazel
index 5b8f53e4f17..01287999145 100644
--- a/domain/src/main/java/org/oppia/android/domain/oppialogger/loguploader/BUILD.bazel
+++ b/domain/src/main/java/org/oppia/android/domain/oppialogger/loguploader/BUILD.bazel
@@ -27,12 +27,14 @@ kt_android_library(
],
deps = [
"//domain/src/main/java/org/oppia/android/domain/oppialogger/analytics:controller",
+ "//domain/src/main/java/org/oppia/android/domain/oppialogger/analytics:performance_metrics_controller",
"//domain/src/main/java/org/oppia/android/domain/oppialogger/exceptions:controller",
"//domain/src/main/java/org/oppia/android/domain/util:extensions",
"//third_party:androidx_work_work-runtime-ktx",
"//utility/src/main/java/org/oppia/android/util/logging:console_logger",
"//utility/src/main/java/org/oppia/android/util/logging:event_logger",
"//utility/src/main/java/org/oppia/android/util/logging:exception_logger",
+ "//utility/src/main/java/org/oppia/android/util/logging/performancemetrics:performance_metrics_event_logger",
"//utility/src/main/java/org/oppia/android/util/threading:annotations",
],
)
diff --git a/domain/src/main/java/org/oppia/android/domain/oppialogger/loguploader/LogReportWorkManagerInitializer.kt b/domain/src/main/java/org/oppia/android/domain/oppialogger/loguploader/LogReportWorkManagerInitializer.kt
index 3bab2316a2b..e5830fddaa5 100644
--- a/domain/src/main/java/org/oppia/android/domain/oppialogger/loguploader/LogReportWorkManagerInitializer.kt
+++ b/domain/src/main/java/org/oppia/android/domain/oppialogger/loguploader/LogReportWorkManagerInitializer.kt
@@ -50,6 +50,13 @@ class LogReportWorkManagerInitializer @Inject constructor(
)
.build()
+ private val workerCaseForUploadingPerformanceMetrics: Data = Data.Builder()
+ .putString(
+ LogUploadWorker.WORKER_CASE_KEY,
+ LogUploadWorker.PERFORMANCE_METRICS_WORKER
+ )
+ .build()
+
private val workerCaseForSchedulingPeriodicBackgroundMetricLogs: Data = Data.Builder()
.putString(
MetricLogSchedulingWorker.WORKER_CASE_KEY,
@@ -83,6 +90,12 @@ class LogReportWorkManagerInitializer @Inject constructor(
.setConstraints(logReportWorkerConstraints)
.build()
+ private val workRequestForUploadingPerformanceMetrics: PeriodicWorkRequest = PeriodicWorkRequest
+ .Builder(LogUploadWorker::class.java, 6, TimeUnit.HOURS)
+ .setInputData(workerCaseForUploadingPerformanceMetrics)
+ .setConstraints(logReportWorkerConstraints)
+ .build()
+
private val workRequestForSchedulingPeriodicBackgroundMetricLogs: PeriodicWorkRequest =
PeriodicWorkRequest.Builder(
MetricLogSchedulingWorker::class.java,
@@ -117,6 +130,10 @@ class LogReportWorkManagerInitializer @Inject constructor(
val workManager = WorkManager.getInstance(context)
logUploader.enqueueWorkRequestForEvents(workManager, workRequestForUploadingEvents)
logUploader.enqueueWorkRequestForExceptions(workManager, workRequestForUploadingExceptions)
+ logUploader.enqueueWorkRequestForPerformanceMetrics(
+ workManager,
+ workRequestForUploadingPerformanceMetrics
+ )
metricLogScheduler.enqueueWorkRequestForPeriodicBackgroundMetrics(
workManager,
workRequestForSchedulingPeriodicBackgroundMetricLogs
@@ -140,6 +157,9 @@ class LogReportWorkManagerInitializer @Inject constructor(
/** Returns the [UUID] of the work request that is enqueued for uploading exception logs. */
fun getWorkRequestForExceptionsId(): UUID = workRequestForUploadingExceptions.id
+ /** Returns the [UUID] of the work request that is enqueued for uploading performance metrics logs. */
+ fun getWorkRequestForPerformanceMetricsId(): UUID = workRequestForUploadingPerformanceMetrics.id
+
/**
* Returns the [UUID] of the work request that is enqueued for scheduling memory usage
* performance metrics collection.
@@ -172,6 +192,9 @@ class LogReportWorkManagerInitializer @Inject constructor(
*/
fun getWorkRequestDataForExceptions(): Data = workerCaseForUploadingExceptions
+ /** Returns the [Data] that goes into the work request that is enqueued for uploading performance metric logs. */
+ fun getWorkRequestDataForPerformanceMetrics(): Data = workerCaseForUploadingPerformanceMetrics
+
/**
* Returns the [Data] that goes into the work request that is enqueued for scheduling storage
* usage performance metrics collection.
diff --git a/domain/src/main/java/org/oppia/android/domain/oppialogger/loguploader/LogUploadWorker.kt b/domain/src/main/java/org/oppia/android/domain/oppialogger/loguploader/LogUploadWorker.kt
index 44b59243406..ad7ffe8e878 100644
--- a/domain/src/main/java/org/oppia/android/domain/oppialogger/loguploader/LogUploadWorker.kt
+++ b/domain/src/main/java/org/oppia/android/domain/oppialogger/loguploader/LogUploadWorker.kt
@@ -10,6 +10,7 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.async
import org.oppia.android.domain.oppialogger.analytics.AnalyticsController
+import org.oppia.android.domain.oppialogger.analytics.PerformanceMetricsController
import org.oppia.android.domain.oppialogger.exceptions.ExceptionsController
import org.oppia.android.domain.oppialogger.exceptions.toException
import org.oppia.android.domain.util.getStringFromData
@@ -17,6 +18,7 @@ import org.oppia.android.util.logging.ConsoleLogger
import org.oppia.android.util.logging.EventLogger
import org.oppia.android.util.logging.ExceptionLogger
import org.oppia.android.util.logging.SyncStatusManager
+import org.oppia.android.util.logging.performancemetrics.PerformanceMetricsEventLogger
import org.oppia.android.util.threading.BackgroundDispatcher
import javax.inject.Inject
@@ -26,8 +28,10 @@ class LogUploadWorker private constructor(
params: WorkerParameters,
private val analyticsController: AnalyticsController,
private val exceptionsController: ExceptionsController,
+ private val performanceMetricsController: PerformanceMetricsController,
private val exceptionLogger: ExceptionLogger,
private val eventLogger: EventLogger,
+ private val performanceMetricsEventLogger: PerformanceMetricsEventLogger,
private val consoleLogger: ConsoleLogger,
private val syncStatusManager: SyncStatusManager,
@BackgroundDispatcher private val backgroundDispatcher: CoroutineDispatcher
@@ -38,6 +42,7 @@ class LogUploadWorker private constructor(
const val TAG = "LogUploadWorker.tag"
const val EVENT_WORKER = "event_worker"
const val EXCEPTION_WORKER = "exception_worker"
+ const val PERFORMANCE_METRICS_WORKER = "performance_metrics_worker"
}
@ExperimentalCoroutinesApi
@@ -47,6 +52,7 @@ class LogUploadWorker private constructor(
when (inputData.getStringFromData(WORKER_CASE_KEY)) {
EVENT_WORKER -> uploadEvents()
EXCEPTION_WORKER -> uploadExceptions()
+ PERFORMANCE_METRICS_WORKER -> uploadPerformanceMetrics()
else -> Result.failure()
}
}
@@ -97,12 +103,29 @@ class LogUploadWorker private constructor(
}
}
+ /** Extracts performance metric logs from the cache store and logs them to the remote service. */
+ private suspend fun uploadPerformanceMetrics(): Result {
+ return try {
+ val performanceMetricsLogs = performanceMetricsController.getMetricLogStoreList()
+ performanceMetricsLogs.forEach { performanceMetricsLog ->
+ performanceMetricsEventLogger.logPerformanceMetric(performanceMetricsLog)
+ performanceMetricsController.removeFirstMetricLogFromStore()
+ }
+ Result.success()
+ } catch (e: Exception) {
+ consoleLogger.e(TAG, e.toString(), e)
+ Result.failure()
+ }
+ }
+
/** Creates an instance of [LogUploadWorker] by properly injecting dependencies. */
class Factory @Inject constructor(
private val analyticsController: AnalyticsController,
private val exceptionsController: ExceptionsController,
+ private val performanceMetricsController: PerformanceMetricsController,
private val exceptionLogger: ExceptionLogger,
private val eventLogger: EventLogger,
+ private val performanceMetricsEventLogger: PerformanceMetricsEventLogger,
private val consoleLogger: ConsoleLogger,
private val syncStatusManager: SyncStatusManager,
@BackgroundDispatcher private val backgroundDispatcher: CoroutineDispatcher
@@ -114,8 +137,10 @@ class LogUploadWorker private constructor(
params,
analyticsController,
exceptionsController,
+ performanceMetricsController,
exceptionLogger,
eventLogger,
+ performanceMetricsEventLogger,
consoleLogger,
syncStatusManager,
backgroundDispatcher
diff --git a/domain/src/main/java/org/oppia/android/domain/testing/oppialogger/loguploader/FakeLogUploader.kt b/domain/src/main/java/org/oppia/android/domain/testing/oppialogger/loguploader/FakeLogUploader.kt
index b2a02324827..48783b794d5 100644
--- a/domain/src/main/java/org/oppia/android/domain/testing/oppialogger/loguploader/FakeLogUploader.kt
+++ b/domain/src/main/java/org/oppia/android/domain/testing/oppialogger/loguploader/FakeLogUploader.kt
@@ -12,6 +12,7 @@ import javax.inject.Singleton
class FakeLogUploader @Inject constructor() : LogUploader {
private val eventRequestIdList = mutableListOf()
private val exceptionRequestIdList = mutableListOf()
+ private val performanceMetricsRequestIdList = mutableListOf()
override fun enqueueWorkRequestForEvents(
workManager: WorkManager,
@@ -27,9 +28,19 @@ class FakeLogUploader @Inject constructor() : LogUploader {
exceptionRequestIdList.add(workRequest.id)
}
+ override fun enqueueWorkRequestForPerformanceMetrics(
+ workManager: WorkManager,
+ workRequest: PeriodicWorkRequest
+ ) {
+ performanceMetricsRequestIdList.add(workRequest.id)
+ }
+
/** Returns the most recent work request id that's stored in the [eventRequestIdList]. */
fun getMostRecentEventRequestId() = eventRequestIdList.last()
/** Returns the most recent work request id that's stored in the [exceptionRequestIdList]. */
fun getMostRecentExceptionRequestId() = exceptionRequestIdList.last()
+
+ /** Returns the most recent work request id that's stored in the [performanceMetricsRequestIdList]. */
+ fun getMostRecentPerformanceMetricsRequestId() = performanceMetricsRequestIdList.last()
}
diff --git a/domain/src/test/java/org/oppia/android/domain/oppialogger/loguploader/LogReportWorkManagerInitializerTest.kt b/domain/src/test/java/org/oppia/android/domain/oppialogger/loguploader/LogReportWorkManagerInitializerTest.kt
index 50b92a0573e..cb31d65425e 100644
--- a/domain/src/test/java/org/oppia/android/domain/oppialogger/loguploader/LogReportWorkManagerInitializerTest.kt
+++ b/domain/src/test/java/org/oppia/android/domain/oppialogger/loguploader/LogReportWorkManagerInitializerTest.kt
@@ -122,6 +122,8 @@ class LogReportWorkManagerInitializerTest {
val enqueuedEventWorkRequestId = logReportWorkManagerInitializer.getWorkRequestForEventsId()
val enqueuedExceptionWorkRequestId =
logReportWorkManagerInitializer.getWorkRequestForExceptionsId()
+ val enqueuedPerformanceMetricsWorkRequestId =
+ logReportWorkManagerInitializer.getWorkRequestForPerformanceMetricsId()
val enqueuedSchedulingStorageUsageMetricWorkRequestId =
logReportWorkManagerInitializer.getWorkRequestForSchedulingStorageUsageMetricLogsId()
val enqueuedSchedulingPeriodicUiMetricWorkRequestId =
@@ -134,6 +136,9 @@ class LogReportWorkManagerInitializerTest {
assertThat(fakeLogUploader.getMostRecentExceptionRequestId()).isEqualTo(
enqueuedExceptionWorkRequestId
)
+ assertThat(fakeLogUploader.getMostRecentPerformanceMetricsRequestId()).isEqualTo(
+ enqueuedPerformanceMetricsWorkRequestId
+ )
assertThat(fakeLogScheduler.getMostRecentStorageUsageMetricLoggingRequestId()).isEqualTo(
enqueuedSchedulingStorageUsageMetricWorkRequestId
)
@@ -186,6 +191,20 @@ class LogReportWorkManagerInitializerTest {
).isEqualTo(workerCaseForUploadingExceptions)
}
+ @Test
+ fun testWorkRequest_verifyWorkRequestDataForPerformanceMetrics() {
+ val workerCaseForUploadingPerformanceMetrics: Data = Data.Builder()
+ .putString(
+ LogUploadWorker.WORKER_CASE_KEY,
+ LogUploadWorker.PERFORMANCE_METRICS_WORKER
+ )
+ .build()
+
+ assertThat(logReportWorkManagerInitializer.getWorkRequestDataForPerformanceMetrics()).isEqualTo(
+ workerCaseForUploadingPerformanceMetrics
+ )
+ }
+
@Test
fun testWorkRequest_verifyWorkRequestData_forSchedulingStorageUsageMetricLogs() {
val workerCaseForSchedulingStorageUsageMetricLogs: Data = Data.Builder()
diff --git a/domain/src/test/java/org/oppia/android/domain/oppialogger/loguploader/LogUploadWorkerTest.kt b/domain/src/test/java/org/oppia/android/domain/oppialogger/loguploader/LogUploadWorkerTest.kt
index 3e7881b4525..51ffe407e95 100644
--- a/domain/src/test/java/org/oppia/android/domain/oppialogger/loguploader/LogUploadWorkerTest.kt
+++ b/domain/src/test/java/org/oppia/android/domain/oppialogger/loguploader/LogUploadWorkerTest.kt
@@ -26,18 +26,22 @@ import org.mockito.Mockito.`when`
import org.mockito.Mockito.mock
import org.mockito.Mockito.reset
import org.oppia.android.app.model.EventLog
+import org.oppia.android.app.model.OppiaMetricLog
import org.oppia.android.domain.oppialogger.EventLogStorageCacheSize
import org.oppia.android.domain.oppialogger.ExceptionLogStorageCacheSize
import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
import org.oppia.android.domain.oppialogger.OppiaLogger
+import org.oppia.android.domain.oppialogger.PerformanceMetricsLogStorageCacheSize
import org.oppia.android.domain.oppialogger.analytics.AnalyticsController
import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
+import org.oppia.android.domain.oppialogger.analytics.PerformanceMetricsController
import org.oppia.android.domain.oppialogger.exceptions.ExceptionsController
import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.domain.testing.oppialogger.loguploader.FakeLogUploader
import org.oppia.android.testing.FakeEventLogger
import org.oppia.android.testing.FakeExceptionLogger
+import org.oppia.android.testing.FakePerformanceMetricsEventLogger
import org.oppia.android.testing.logging.FakeSyncStatusManager
import org.oppia.android.testing.logging.SyncStatusTestModule
import org.oppia.android.testing.mockito.anyOrNull
@@ -58,6 +62,9 @@ import org.oppia.android.util.logging.SyncStatusManager.SyncStatus.DATA_UPLOADED
import org.oppia.android.util.logging.SyncStatusManager.SyncStatus.DATA_UPLOADING
import org.oppia.android.util.logging.SyncStatusManager.SyncStatus.NETWORK_ERROR
import org.oppia.android.util.logging.SyncStatusManager.SyncStatus.NO_CONNECTIVITY
+import org.oppia.android.util.logging.performancemetrics.PerformanceMetricsAssessorModule
+import org.oppia.android.util.logging.performancemetrics.PerformanceMetricsConfigurationsModule
+import org.oppia.android.util.logging.performancemetrics.PerformanceMetricsEventLogger
import org.oppia.android.util.networking.NetworkConnectionDebugUtil
import org.oppia.android.util.networking.NetworkConnectionUtil.ProdConnectionStatus.NONE
import org.oppia.android.util.networking.NetworkConnectionUtilDebugModule
@@ -69,6 +76,7 @@ import javax.inject.Singleton
private const val TEST_TIMESTAMP = 1556094120000
private const val TEST_TOPIC_ID = "test_topicId"
+private const val TEST_APK_SIZE = Long.MAX_VALUE
/** Tests for [LogUploadWorker]. */
// FunctionName: test names are conventionally named with underscores.
@@ -80,9 +88,11 @@ class LogUploadWorkerTest {
@Inject lateinit var networkConnectionUtil: NetworkConnectionDebugUtil
@Inject lateinit var fakeEventLogger: FakeEventLogger
@Inject lateinit var fakeExceptionLogger: FakeExceptionLogger
+ @Inject lateinit var fakePerformanceMetricsEventLogger: FakePerformanceMetricsEventLogger
@Inject lateinit var oppiaLogger: OppiaLogger
@Inject lateinit var analyticsController: AnalyticsController
@Inject lateinit var exceptionsController: ExceptionsController
+ @Inject lateinit var performanceMetricsController: PerformanceMetricsController
@Inject lateinit var logUploadWorkerFactory: LogUploadWorkerFactory
@Inject lateinit var dataProviders: DataProviders
@Inject lateinit var testCoroutineDispatchers: TestCoroutineDispatchers
@@ -105,6 +115,13 @@ class LogUploadWorkerTest {
.setTimestamp(TEST_TIMESTAMP)
.build()
+ private val apkSizeTestLoggableMetric = OppiaMetricLog.LoggableMetric.newBuilder()
+ .setApkSizeMetric(
+ OppiaMetricLog.ApkSizeMetric.newBuilder()
+ .setApkSizeBytes(TEST_APK_SIZE)
+ .build()
+ ).build()
+
private val exception = Exception("TEST")
@Before
@@ -203,6 +220,46 @@ class LogUploadWorkerTest {
assertThat(loggedExceptionStackTraceElems).isEqualTo(expectedExceptionStackTraceElems)
}
+ @Test
+ fun testWorker_logPerformanceMetric_withoutNetwork_enqueueRequest_verifySuccess() {
+ networkConnectionUtil.setCurrentConnectionStatus(NONE)
+ performanceMetricsController.logPerformanceMetricsEvent(
+ TEST_TIMESTAMP,
+ OppiaMetricLog.CurrentScreen.SCREEN_UNSPECIFIED,
+ apkSizeTestLoggableMetric,
+ OppiaMetricLog.Priority.LOW_PRIORITY
+ )
+
+ val workManager = WorkManager.getInstance(ApplicationProvider.getApplicationContext())
+
+ val inputData = Data.Builder().putString(
+ LogUploadWorker.WORKER_CASE_KEY,
+ LogUploadWorker.PERFORMANCE_METRICS_WORKER
+ ).build()
+
+ val request: OneTimeWorkRequest = OneTimeWorkRequestBuilder()
+ .setInputData(inputData)
+ .build()
+ workManager.enqueue(request)
+ testCoroutineDispatchers.runCurrent()
+
+ val workInfo = workManager.getWorkInfoById(request.id)
+ val loggedPerformanceMetric =
+ fakePerformanceMetricsEventLogger.getMostRecentPerformanceMetricsEvent()
+ assertThat(workInfo.get().state).isEqualTo(WorkInfo.State.SUCCEEDED)
+ assertThat(loggedPerformanceMetric.loggableMetric.loggableMetricTypeCase).isEqualTo(
+ OppiaMetricLog.LoggableMetric.LoggableMetricTypeCase.APK_SIZE_METRIC
+ )
+ assertThat(loggedPerformanceMetric.currentScreen).isEqualTo(
+ OppiaMetricLog.CurrentScreen.SCREEN_UNSPECIFIED
+ )
+ assertThat(loggedPerformanceMetric.priority).isEqualTo(OppiaMetricLog.Priority.LOW_PRIORITY)
+ assertThat(loggedPerformanceMetric.timestampMillis).isEqualTo(TEST_TIMESTAMP)
+ assertThat(loggedPerformanceMetric.loggableMetric.apkSizeMetric.apkSizeBytes).isEqualTo(
+ TEST_APK_SIZE
+ )
+ }
+
@Test
fun testWorker_logEvent_withoutNetwork_enqueueRequest_verifyCorrectSyncStatusSequence() {
networkConnectionUtil.setCurrentConnectionStatus(NONE)
@@ -310,6 +367,11 @@ class LogUploadWorkerTest {
@Provides
fun bindFakeExceptionLogger(fakeLogger: FakeExceptionLogger): ExceptionLogger = fakeLogger
+
+ @Provides
+ fun bindFakePerformanceMetricsLogger(
+ fakePerformanceMetricsEventLogger: FakePerformanceMetricsEventLogger
+ ): PerformanceMetricsEventLogger = fakePerformanceMetricsEventLogger
}
@Module
@@ -322,6 +384,10 @@ class LogUploadWorkerTest {
@Provides
@ExceptionLogStorageCacheSize
fun provideExceptionLogStorageSize(): Int = 2
+
+ @Provides
+ @PerformanceMetricsLogStorageCacheSize
+ fun providePerformanceMetricsLogStorageCacheSize(): Int = 2
}
@Module
@@ -340,7 +406,9 @@ class LogUploadWorkerTest {
TestFirebaseLogUploaderModule::class, FakeOppiaClockModule::class,
NetworkConnectionUtilDebugModule::class, LocaleProdModule::class, LoggerModule::class,
AssetModule::class, PlatformParameterModule::class, PlatformParameterSingletonModule::class,
- LoggingIdentifierModule::class, SyncStatusTestModule::class, ApplicationLifecycleModule::class
+ LoggingIdentifierModule::class, SyncStatusTestModule::class,
+ PerformanceMetricsAssessorModule::class, ApplicationLifecycleModule::class,
+ PerformanceMetricsConfigurationsModule::class
]
)
interface TestApplicationComponent : DataProvidersInjector {
diff --git a/utility/src/main/java/org/oppia/android/util/logging/BUILD.bazel b/utility/src/main/java/org/oppia/android/util/logging/BUILD.bazel
index a96279e3f68..77c82bb3bf7 100644
--- a/utility/src/main/java/org/oppia/android/util/logging/BUILD.bazel
+++ b/utility/src/main/java/org/oppia/android/util/logging/BUILD.bazel
@@ -66,6 +66,7 @@ kt_android_library(
visibility = ["//:oppia_api_visibility"],
deps = [
"//model/src/main/proto:event_logger_java_proto_lite",
+ "//model/src/main/proto:performance_metrics_event_logger_java_proto_lite",
"//third_party:javax_inject_javax_inject",
"//utility",
],
diff --git a/utility/src/main/java/org/oppia/android/util/logging/EventBundleCreator.kt b/utility/src/main/java/org/oppia/android/util/logging/EventBundleCreator.kt
index 376f5fedb39..3c2747e9ec9 100644
--- a/utility/src/main/java/org/oppia/android/util/logging/EventBundleCreator.kt
+++ b/utility/src/main/java/org/oppia/android/util/logging/EventBundleCreator.kt
@@ -30,6 +30,15 @@ import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.SOLUTION
import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.START_CARD_CONTEXT
import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.START_OVER_EXPLORATION_CONTEXT
import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.SUBMIT_ANSWER_CONTEXT
+import org.oppia.android.app.model.OppiaMetricLog
+import org.oppia.android.app.model.OppiaMetricLog.LoggableMetric.LoggableMetricTypeCase
+import org.oppia.android.app.model.OppiaMetricLog.LoggableMetric.LoggableMetricTypeCase.APK_SIZE_METRIC
+import org.oppia.android.app.model.OppiaMetricLog.LoggableMetric.LoggableMetricTypeCase.CPU_USAGE_METRIC
+import org.oppia.android.app.model.OppiaMetricLog.LoggableMetric.LoggableMetricTypeCase.LOGGABLEMETRICTYPE_NOT_SET
+import org.oppia.android.app.model.OppiaMetricLog.LoggableMetric.LoggableMetricTypeCase.MEMORY_USAGE_METRIC
+import org.oppia.android.app.model.OppiaMetricLog.LoggableMetric.LoggableMetricTypeCase.NETWORK_USAGE_METRIC
+import org.oppia.android.app.model.OppiaMetricLog.LoggableMetric.LoggableMetricTypeCase.STARTUP_LATENCY_METRIC
+import org.oppia.android.app.model.OppiaMetricLog.LoggableMetric.LoggableMetricTypeCase.STORAGE_USAGE_METRIC
import org.oppia.android.util.logging.EventBundleCreator.EventActivityContext.CardContext
import org.oppia.android.util.logging.EventBundleCreator.EventActivityContext.ConceptCardContext
import org.oppia.android.util.logging.EventBundleCreator.EventActivityContext.EmptyContext
@@ -43,6 +52,12 @@ import org.oppia.android.util.logging.EventBundleCreator.EventActivityContext.Se
import org.oppia.android.util.logging.EventBundleCreator.EventActivityContext.StoryContext
import org.oppia.android.util.logging.EventBundleCreator.EventActivityContext.SubmitAnswerContext
import org.oppia.android.util.logging.EventBundleCreator.EventActivityContext.TopicContext
+import org.oppia.android.util.logging.EventBundleCreator.PerformanceMetricsLoggableMetricType.ApkSizeLoggableMetric
+import org.oppia.android.util.logging.EventBundleCreator.PerformanceMetricsLoggableMetricType.CpuUsageLoggableMetric
+import org.oppia.android.util.logging.EventBundleCreator.PerformanceMetricsLoggableMetricType.MemoryUsageLoggableMetric
+import org.oppia.android.util.logging.EventBundleCreator.PerformanceMetricsLoggableMetricType.NetworkUsageLoggableMetric
+import org.oppia.android.util.logging.EventBundleCreator.PerformanceMetricsLoggableMetricType.StartupLatencyLoggableMetric
+import org.oppia.android.util.logging.EventBundleCreator.PerformanceMetricsLoggableMetricType.StorageUsageLoggableMetric
import org.oppia.android.util.platformparameter.LearnerStudyAnalytics
import org.oppia.android.util.platformparameter.PlatformParameterValue
import javax.inject.Inject
@@ -57,6 +72,12 @@ import org.oppia.android.app.model.EventLog.RevisionCardContext as RevisionCardE
import org.oppia.android.app.model.EventLog.StoryContext as StoryEventContext
import org.oppia.android.app.model.EventLog.SubmitAnswerContext as SubmitAnswerEventContext
import org.oppia.android.app.model.EventLog.TopicContext as TopicEventContext
+import org.oppia.android.app.model.OppiaMetricLog.ApkSizeMetric as ApkSizePerformanceLoggableMetric
+import org.oppia.android.app.model.OppiaMetricLog.CpuUsageMetric as CpuUsagePerformanceLoggableMetric
+import org.oppia.android.app.model.OppiaMetricLog.MemoryUsageMetric as MemoryUsagePerformanceLoggableMetric
+import org.oppia.android.app.model.OppiaMetricLog.NetworkUsageMetric as NetworkUsagePerformanceLoggableMetric
+import org.oppia.android.app.model.OppiaMetricLog.StartupLatencyMetric as StartupLatencyPerformanceLoggableMetric
+import org.oppia.android.app.model.OppiaMetricLog.StorageUsageMetric as StorageUsagePerformanceLoggableMetric
// See https://firebase.google.com/docs/reference/cpp/group/parameter-names for context.
private const val MAX_CHARACTERS_IN_PARAMETER_NAME = 40
@@ -84,6 +105,25 @@ class EventBundleCreator @Inject constructor(
}?.activityName ?: "unknown_activity_context"
}
+ /**
+ * Fills the specified [bundle] with a logging-ready representation of [oppiaMetricLog] and
+ * returns a string representation of the high-level type of event logged (per
+ * [OppiaMetricLog.LoggableMetric.getLoggableMetricTypeCase]).
+ */
+ fun fillPerformanceMetricsEventBundle(oppiaMetricLog: OppiaMetricLog, bundle: Bundle): String {
+ bundle.putLong("timestamp", oppiaMetricLog.timestampMillis)
+ bundle.putString("priority", oppiaMetricLog.priority.toAnalyticsName())
+ bundle.putString("is_app_in_foreground", oppiaMetricLog.isAppInForeground.toString())
+ bundle.putString("memory_tier", oppiaMetricLog.memoryTier.toAnalyticsName())
+ bundle.putString("storage_tier", oppiaMetricLog.storageTier.toAnalyticsName())
+ bundle.putString("network_type", oppiaMetricLog.networkType.toAnalyticsName())
+ bundle.putString("current_screen", oppiaMetricLog.currentScreen.toAnalyticsName())
+ return oppiaMetricLog.loggableMetric.convertToLoggableMetricType()?.also { loggableMetric ->
+ // No performance metrics need to be tied to user IDs.
+ loggableMetric.storeValue(PropertyStore(bundle, allowUserIds = false))
+ }?.metricName ?: "unknown_loggable_metric"
+ }
+
private fun EventLog.Context.convertToActivityContext(): EventActivityContext<*>? {
return when (activityContextCase) {
OPEN_EXPLORATION_ACTIVITY ->
@@ -129,6 +169,28 @@ class EventBundleCreator @Inject constructor(
}
}
+ private fun OppiaMetricLog.LoggableMetric.convertToLoggableMetricType():
+ PerformanceMetricsLoggableMetricType<*>? {
+ return when (loggableMetricTypeCase) {
+ APK_SIZE_METRIC -> ApkSizeLoggableMetric("apk_size_metric", apkSizeMetric)
+ STORAGE_USAGE_METRIC -> StorageUsageLoggableMetric(
+ "storage_usage_metric",
+ storageUsageMetric
+ )
+ STARTUP_LATENCY_METRIC -> StartupLatencyLoggableMetric(
+ "startup_latency_metric",
+ startupLatencyMetric
+ )
+ MEMORY_USAGE_METRIC -> MemoryUsageLoggableMetric("memory_usage_metric", memoryUsageMetric)
+ NETWORK_USAGE_METRIC -> NetworkUsageLoggableMetric(
+ "network_usage_metric",
+ networkUsageMetric
+ )
+ CPU_USAGE_METRIC -> CpuUsageLoggableMetric("cpu_usage_metric", cpuUsageMetric)
+ LOGGABLEMETRICTYPE_NOT_SET, null -> null // No context to create here.
+ }
+ }
+
/**
* Utility for storing properties within a [Bundle] (indicated by [bundle]), omitting those which
* contain sensitive information (if they should be per [allowUserIds].
@@ -374,10 +436,126 @@ class EventBundleCreator @Inject constructor(
}
}
+ /*** Represents an [OppiaMetricLog] loggable metric (denoted by [LoggableMetricTypeCase]).*/
+ private sealed class PerformanceMetricsLoggableMetricType(
+ val metricName: String,
+ private val value: T
+ ) {
+ /**
+ * Stores the value of this context (i.e. its constituent properties which may correspond to
+ * other [LoggableMetricTypeCase]s).
+ */
+ fun storeValue(store: PropertyStore) = value.storeValue(store)
+
+ /** Method that should be overridden by base classes to satisfy the contract of [storeValue]. */
+ protected abstract fun T.storeValue(store: PropertyStore)
+
+ /** The [LoggableMetricTypeCase] corresponding to [ApkSizePerformanceLoggableMetric]. */
+ class ApkSizeLoggableMetric(
+ metricName: String,
+ value: OppiaMetricLog.ApkSizeMetric
+ ) : PerformanceMetricsLoggableMetricType(metricName, value) {
+ override fun OppiaMetricLog.ApkSizeMetric.storeValue(store: PropertyStore) {
+ store.putNonSensitiveValue("apk_size_bytes", apkSizeBytes)
+ }
+ }
+
+ /** The [LoggableMetricTypeCase] corresponding to [StorageUsagePerformanceLoggableMetric]. */
+ class StorageUsageLoggableMetric(
+ metricName: String,
+ value: OppiaMetricLog.StorageUsageMetric
+ ) : PerformanceMetricsLoggableMetricType(metricName, value) {
+ override fun OppiaMetricLog.StorageUsageMetric.storeValue(store: PropertyStore) {
+ store.putNonSensitiveValue("storage_usage_bytes", storageUsageBytes)
+ }
+ }
+
+ /** The [LoggableMetricTypeCase] corresponding to [StartupLatencyPerformanceLoggableMetric]. */
+ class StartupLatencyLoggableMetric(
+ metricName: String,
+ value: OppiaMetricLog.StartupLatencyMetric
+ ) :
+ PerformanceMetricsLoggableMetricType(metricName, value) {
+ override fun OppiaMetricLog.StartupLatencyMetric.storeValue(store: PropertyStore) {
+ store.putNonSensitiveValue("startup_latency_millis", startupLatencyMillis)
+ }
+ }
+
+ /** The [LoggableMetricTypeCase] corresponding to [MemoryUsagePerformanceLoggableMetric]. */
+ class MemoryUsageLoggableMetric(
+ metricName: String,
+ value: OppiaMetricLog.MemoryUsageMetric
+ ) : PerformanceMetricsLoggableMetricType(metricName, value) {
+ override fun OppiaMetricLog.MemoryUsageMetric.storeValue(store: PropertyStore) {
+ store.putNonSensitiveValue("total_pss_bytes", totalPssBytes)
+ }
+ }
+
+ /** The [LoggableMetricTypeCase] corresponding to [NetworkUsagePerformanceLoggableMetric]. */
+ class NetworkUsageLoggableMetric(
+ metricName: String,
+ value: OppiaMetricLog.NetworkUsageMetric
+ ) : PerformanceMetricsLoggableMetricType(metricName, value) {
+ override fun OppiaMetricLog.NetworkUsageMetric.storeValue(store: PropertyStore) {
+ store.putNonSensitiveValue("bytes_received", bytesReceived)
+ store.putNonSensitiveValue("bytes_sent", bytesSent)
+ }
+ }
+
+ /** The [LoggableMetricTypeCase] corresponding to [CpuUsagePerformanceLoggableMetric]. */
+ class CpuUsageLoggableMetric(
+ metricName: String,
+ value: OppiaMetricLog.CpuUsageMetric
+ ) : PerformanceMetricsLoggableMetricType(metricName, value) {
+ override fun OppiaMetricLog.CpuUsageMetric.storeValue(store: PropertyStore) {
+ store.putNonSensitiveValue("cpu_usage", cpuUsageMetric)
+ }
+ }
+ }
+
private fun EventLog.Priority.toAnalyticsName() = when (this) {
EventLog.Priority.PRIORITY_UNSPECIFIED -> "unspecified_priority"
EventLog.Priority.ESSENTIAL -> "essential"
EventLog.Priority.OPTIONAL -> "optional"
EventLog.Priority.UNRECOGNIZED -> "unknown_priority"
}
+
+ private fun OppiaMetricLog.Priority.toAnalyticsName() = when (this) {
+ OppiaMetricLog.Priority.PRIORITY_UNSPECIFIED -> "unspecified_priority"
+ OppiaMetricLog.Priority.LOW_PRIORITY -> "low_priority"
+ OppiaMetricLog.Priority.MEDIUM_PRIORITY -> "medium_priority"
+ OppiaMetricLog.Priority.HIGH_PRIORITY -> "high_priority"
+ OppiaMetricLog.Priority.UNRECOGNIZED -> "unknown_priority"
+ }
+
+ private fun OppiaMetricLog.MemoryTier.toAnalyticsName() = when (this) {
+ OppiaMetricLog.MemoryTier.MEMORY_TIER_UNSPECIFIED -> "unspecified_memory_tier"
+ OppiaMetricLog.MemoryTier.LOW_MEMORY_TIER -> "low_memory"
+ OppiaMetricLog.MemoryTier.MEDIUM_MEMORY_TIER -> "medium_memory"
+ OppiaMetricLog.MemoryTier.HIGH_MEMORY_TIER -> "high_memory"
+ OppiaMetricLog.MemoryTier.UNRECOGNIZED -> "unknown_memory_tier"
+ }
+
+ private fun OppiaMetricLog.StorageTier.toAnalyticsName() = when (this) {
+ OppiaMetricLog.StorageTier.STORAGE_TIER_UNSPECIFIED -> "unspecified_storage_tier"
+ OppiaMetricLog.StorageTier.LOW_STORAGE -> "low_storage"
+ OppiaMetricLog.StorageTier.MEDIUM_STORAGE -> "medium_storage"
+ OppiaMetricLog.StorageTier.HIGH_STORAGE -> "high_storage"
+ OppiaMetricLog.StorageTier.UNRECOGNIZED -> "unknown_storage_tier"
+ }
+
+ private fun OppiaMetricLog.NetworkType.toAnalyticsName() = when (this) {
+ OppiaMetricLog.NetworkType.NETWORK_UNSPECIFIED -> "unspecified_network_type"
+ OppiaMetricLog.NetworkType.WIFI -> "wifi"
+ OppiaMetricLog.NetworkType.CELLULAR -> "cellular"
+ OppiaMetricLog.NetworkType.NONE -> "none"
+ OppiaMetricLog.NetworkType.UNRECOGNIZED -> "unknown_network_type"
+ }
+
+ private fun OppiaMetricLog.CurrentScreen.toAnalyticsName() = when (this) {
+ OppiaMetricLog.CurrentScreen.SCREEN_UNSPECIFIED -> "unspecified_current_screen"
+ OppiaMetricLog.CurrentScreen.HOME_SCREEN -> "home_screen"
+ OppiaMetricLog.CurrentScreen.UNRECOGNIZED -> "unknown_screen_name"
+ // TODO(#4340): Add support for all screens which are going to be used for metric logging.
+ }
}
diff --git a/utility/src/main/java/org/oppia/android/util/logging/LogUploader.kt b/utility/src/main/java/org/oppia/android/util/logging/LogUploader.kt
index fdfa943b5ad..9104e66a24f 100644
--- a/utility/src/main/java/org/oppia/android/util/logging/LogUploader.kt
+++ b/utility/src/main/java/org/oppia/android/util/logging/LogUploader.kt
@@ -11,4 +11,10 @@ interface LogUploader {
/** Enqueues a [workRequest] using the [workManager] for uploading exception logs that are stored in the cache store. */
fun enqueueWorkRequestForExceptions(workManager: WorkManager, workRequest: PeriodicWorkRequest)
+
+ /** Enqueues a [workRequest] using the [workManager] for uploading performance metrics logs that are stored in the cache store. */
+ fun enqueueWorkRequestForPerformanceMetrics(
+ workManager: WorkManager,
+ workRequest: PeriodicWorkRequest
+ )
}
diff --git a/utility/src/main/java/org/oppia/android/util/logging/firebase/FirebaseEventLogger.kt b/utility/src/main/java/org/oppia/android/util/logging/firebase/FirebaseEventLogger.kt
index b2a1f71d4ef..eb285ed8864 100644
--- a/utility/src/main/java/org/oppia/android/util/logging/firebase/FirebaseEventLogger.kt
+++ b/utility/src/main/java/org/oppia/android/util/logging/firebase/FirebaseEventLogger.kt
@@ -38,7 +38,18 @@ class FirebaseEventLogger private constructor(
* Logs a performance metric to Firebase Analytics with [NETWORK_USER_PROPERTY] and [COUNTRY_USER_PROPERTY].
*/
override fun logPerformanceMetric(oppiaMetricLog: OppiaMetricLog) {
- // TODO(#4335): Add implementation to upload performance metrics logs to firebase.
+ Bundle().let {
+ firebaseAnalytics.logEvent(
+ eventBundleCreator.fillPerformanceMetricsEventBundle(
+ oppiaMetricLog,
+ it
+ ),
+ it
+ )
+ }
+ // TODO(#3792): Remove this usage of Locale.
+ firebaseAnalytics.setUserProperty(COUNTRY_USER_PROPERTY, Locale.getDefault().displayCountry)
+ firebaseAnalytics.setUserProperty(NETWORK_USER_PROPERTY, getNetworkStatus())
}
private fun getNetworkStatus(): String {
diff --git a/utility/src/main/java/org/oppia/android/util/logging/firebase/FirebaseLogUploader.kt b/utility/src/main/java/org/oppia/android/util/logging/firebase/FirebaseLogUploader.kt
index fbe0b7c4f57..067c7c4c815 100644
--- a/utility/src/main/java/org/oppia/android/util/logging/firebase/FirebaseLogUploader.kt
+++ b/utility/src/main/java/org/oppia/android/util/logging/firebase/FirebaseLogUploader.kt
@@ -8,6 +8,7 @@ import javax.inject.Inject
private const val OPPIA_EVENT_WORK = "OPPIA_EVENT_WORK_REQUEST"
private const val OPPIA_EXCEPTION_WORK = "OPPIA_EXCEPTION_WORK_REQUEST"
+private const val OPPIA_PERFORMANCE_METRICS_WORK = "OPPIA_PERFORMANCE_METRICS_WORK"
/** Enqueues work requests for uploading stored event/exception logs to the remote service. */
class FirebaseLogUploader @Inject constructor() :
@@ -34,4 +35,15 @@ class FirebaseLogUploader @Inject constructor() :
workRequest
)
}
+
+ override fun enqueueWorkRequestForPerformanceMetrics(
+ workManager: WorkManager,
+ workRequest: PeriodicWorkRequest
+ ) {
+ workManager.enqueueUniquePeriodicWork(
+ OPPIA_PERFORMANCE_METRICS_WORK,
+ ExistingPeriodicWorkPolicy.KEEP,
+ workRequest
+ )
+ }
}
diff --git a/utility/src/test/java/org/oppia/android/util/logging/EventBundleCreatorTest.kt b/utility/src/test/java/org/oppia/android/util/logging/EventBundleCreatorTest.kt
index 268b08e8a86..f9067c27f4c 100644
--- a/utility/src/test/java/org/oppia/android/util/logging/EventBundleCreatorTest.kt
+++ b/utility/src/test/java/org/oppia/android/util/logging/EventBundleCreatorTest.kt
@@ -28,6 +28,23 @@ import org.oppia.android.app.model.EventLog.RevisionCardContext
import org.oppia.android.app.model.EventLog.StoryContext
import org.oppia.android.app.model.EventLog.SubmitAnswerContext
import org.oppia.android.app.model.EventLog.TopicContext
+import org.oppia.android.app.model.OppiaMetricLog
+import org.oppia.android.app.model.OppiaMetricLog.CurrentScreen
+import org.oppia.android.app.model.OppiaMetricLog.CurrentScreen.HOME_SCREEN
+import org.oppia.android.app.model.OppiaMetricLog.CurrentScreen.SCREEN_UNSPECIFIED
+import org.oppia.android.app.model.OppiaMetricLog.LoggableMetric
+import org.oppia.android.app.model.OppiaMetricLog.MemoryTier
+import org.oppia.android.app.model.OppiaMetricLog.MemoryTier.HIGH_MEMORY_TIER
+import org.oppia.android.app.model.OppiaMetricLog.MemoryTier.MEDIUM_MEMORY_TIER
+import org.oppia.android.app.model.OppiaMetricLog.NetworkType
+import org.oppia.android.app.model.OppiaMetricLog.NetworkType.CELLULAR
+import org.oppia.android.app.model.OppiaMetricLog.NetworkType.WIFI
+import org.oppia.android.app.model.OppiaMetricLog.Priority
+import org.oppia.android.app.model.OppiaMetricLog.Priority.HIGH_PRIORITY
+import org.oppia.android.app.model.OppiaMetricLog.Priority.MEDIUM_PRIORITY
+import org.oppia.android.app.model.OppiaMetricLog.StorageTier
+import org.oppia.android.app.model.OppiaMetricLog.StorageTier.HIGH_STORAGE
+import org.oppia.android.app.model.OppiaMetricLog.StorageTier.MEDIUM_STORAGE
import org.oppia.android.util.platformparameter.LEARNER_STUDY_ANALYTICS_DEFAULT_VALUE
import org.oppia.android.util.platformparameter.LearnerStudyAnalytics
import org.oppia.android.util.platformparameter.PlatformParameterValue
@@ -74,6 +91,12 @@ class EventBundleCreatorTest {
private const val TEST_IS_ANSWER_CORRECT = true
private const val TEST_IS_ANSWER_CORRECT_STR = "true"
private const val TEST_CONTENT_ID = "test_content_id"
+ private const val TEST_CPU_USAGE = Long.MAX_VALUE
+ private const val TEST_APK_SIZE = Long.MAX_VALUE
+ private const val TEST_STORAGE_USAGE = Long.MAX_VALUE
+ private const val TEST_STARTUP_LATENCY = Long.MAX_VALUE
+ private const val TEST_NETWORK_USAGE = Long.MAX_VALUE
+ private const val TEST_MEMORY_USAGE = Long.MAX_VALUE
}
@Inject
@@ -97,6 +120,26 @@ class EventBundleCreatorTest {
assertThat(bundle).string("priority").isEqualTo("unspecified_priority")
}
+ @Test
+ fun testFillPerformanceMetricsBundle_defaultEvent_defaultsBundleAndRetsUnknownActivityContext() {
+ setUpTestApplicationComponent()
+ val bundle = Bundle()
+
+ val typeName = eventBundleCreator.fillPerformanceMetricsEventBundle(
+ OppiaMetricLog.getDefaultInstance(), bundle
+ )
+
+ assertThat(typeName).isEqualTo("unknown_loggable_metric")
+ assertThat(bundle).hasSize(7)
+ assertThat(bundle).longInt("timestamp").isEqualTo(0)
+ assertThat(bundle).string("priority").isEqualTo("unspecified_priority")
+ assertThat(bundle).string("is_app_in_foreground").isEqualTo("false")
+ assertThat(bundle).string("memory_tier").isEqualTo("unspecified_memory_tier")
+ assertThat(bundle).string("storage_tier").isEqualTo("unspecified_storage_tier")
+ assertThat(bundle).string("network_type").isEqualTo("unspecified_network_type")
+ assertThat(bundle).string("current_screen").isEqualTo("unspecified_current_screen")
+ }
+
@Test
fun testFillEventBundle_eventWithDefaultedContext_fillsPriorityAndTimeAndRetsUnknownContext() {
setUpTestApplicationComponent()
@@ -133,6 +176,118 @@ class EventBundleCreatorTest {
assertThat(bundle).string("priority").isEqualTo("optional")
}
+ @Test
+ fun testFillMetricsBundle_eventWithDefaultLoggableMetric_fillsDetailsAndRetsUnknownLog() {
+ setUpTestApplicationComponent()
+ val bundle = Bundle()
+ val performanceMetricLog = createPerformanceMetricLog(
+ timestamp = TEST_TIMESTAMP_1,
+ priority = HIGH_PRIORITY,
+ currentScreen = HOME_SCREEN,
+ memoryTier = HIGH_MEMORY_TIER,
+ storageTier = HIGH_STORAGE,
+ networkType = WIFI,
+ isAppInForeground = true
+ )
+
+ val typeName = eventBundleCreator.fillPerformanceMetricsEventBundle(
+ performanceMetricLog,
+ bundle
+ )
+
+ assertThat(typeName).isEqualTo("unknown_loggable_metric")
+ assertThat(bundle).hasSize(7)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("high_priority")
+ assertThat(bundle).string("is_app_in_foreground").isEqualTo("true")
+ assertThat(bundle).string("memory_tier").isEqualTo("high_memory")
+ assertThat(bundle).string("storage_tier").isEqualTo("high_storage")
+ assertThat(bundle).string("network_type").isEqualTo("wifi")
+ assertThat(bundle).string("current_screen").isEqualTo("home_screen")
+ }
+
+ @Test
+ fun testFillPerformanceMetricBundle_eventWithDiffTimestamp_savesDifferentTimestampInBundle() {
+ setUpTestApplicationComponent()
+ val bundle = Bundle()
+ val performanceMetricLog = createPerformanceMetricLog(timestamp = TEST_TIMESTAMP_2)
+
+ eventBundleCreator.fillPerformanceMetricsEventBundle(performanceMetricLog, bundle)
+
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_2)
+ }
+
+ @Test
+ fun testFillPerformanceMetricBundle_eventWithDifferentPriority_savesDifferentPriorityInBundle() {
+ setUpTestApplicationComponent()
+ val bundle = Bundle()
+ val performanceMetricLog =
+ createPerformanceMetricLog(priority = MEDIUM_PRIORITY)
+
+ eventBundleCreator.fillPerformanceMetricsEventBundle(performanceMetricLog, bundle)
+
+ assertThat(bundle).string("priority").isEqualTo("medium_priority")
+ }
+
+ @Test
+ fun testFillPerformanceMetricBundle_eventWithDiffMemoryTier_savesDiffMemoryTierInBundle() {
+ setUpTestApplicationComponent()
+ val bundle = Bundle()
+ val performanceMetricLog =
+ createPerformanceMetricLog(memoryTier = MEDIUM_MEMORY_TIER)
+
+ eventBundleCreator.fillPerformanceMetricsEventBundle(performanceMetricLog, bundle)
+
+ assertThat(bundle).string("memory_tier").isEqualTo("medium_memory")
+ }
+
+ @Test
+ fun testFillPerformanceMetricBundle_eventWithDiffStorageTier_savesDiffStorageTierInBundle() {
+ setUpTestApplicationComponent()
+ val bundle = Bundle()
+ val performanceMetricLog =
+ createPerformanceMetricLog(storageTier = MEDIUM_STORAGE)
+
+ eventBundleCreator.fillPerformanceMetricsEventBundle(performanceMetricLog, bundle)
+
+ assertThat(bundle).string("storage_tier").isEqualTo("medium_storage")
+ }
+
+ @Test
+ fun testFillPerformanceMetricBundle_eventWithDiffCurrentScreen_savesDiffCurrentScreenInBundle() {
+ setUpTestApplicationComponent()
+ val bundle = Bundle()
+ val performanceMetricLog =
+ createPerformanceMetricLog(currentScreen = SCREEN_UNSPECIFIED)
+
+ eventBundleCreator.fillPerformanceMetricsEventBundle(performanceMetricLog, bundle)
+
+ assertThat(bundle).string("current_screen").isEqualTo("unspecified_current_screen")
+ }
+
+ @Test
+ fun testFillPerformanceMetricBundle_eventWithDiffNetworkType_savesDiffNetworkTypeInBundle() {
+ setUpTestApplicationComponent()
+ val bundle = Bundle()
+ val performanceMetricLog =
+ createPerformanceMetricLog(networkType = CELLULAR)
+
+ eventBundleCreator.fillPerformanceMetricsEventBundle(performanceMetricLog, bundle)
+
+ assertThat(bundle).string("network_type").isEqualTo("cellular")
+ }
+
+ @Test
+ fun testFillPerformanceMetricBundle_eventWithDiffAppInForeground_savesDiffValueInBundle() {
+ setUpTestApplicationComponent()
+ val bundle = Bundle()
+ val performanceMetricLog = createPerformanceMetricLog(isAppInForeground = false)
+
+ eventBundleCreator.fillPerformanceMetricsEventBundle(performanceMetricLog, bundle)
+
+ assertThat(bundle).string("is_app_in_foreground").isEqualTo("false")
+ }
+
@Test
fun testFillEventBundle_openExpActivityEvent_studyOff_fillsOnlyNonSensitiveFieldsAndRetsName() {
setUpTestApplicationComponentWithoutLearnerAnalyticsStudy()
@@ -205,6 +360,151 @@ class EventBundleCreatorTest {
assertThat(bundle).string("topic_id").isEqualTo(TEST_TOPIC_ID)
}
+ @Test
+ fun testFillPerformanceMetricBundle_createApkSizeLoggableMetric_bundlesAllDetailsCorrectly() {
+ setUpTestApplicationComponent()
+ val bundle = Bundle()
+
+ val performanceMetric = createPerformanceMetricLog(
+ loggableMetric = createApkSizeLoggableMetric()
+ )
+ val typeName = eventBundleCreator.fillPerformanceMetricsEventBundle(
+ performanceMetric, bundle
+ )
+
+ assertThat(typeName).isEqualTo("apk_size_metric")
+ assertThat(bundle).hasSize(8)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("high_priority")
+ assertThat(bundle).string("is_app_in_foreground").isEqualTo("true")
+ assertThat(bundle).string("memory_tier").isEqualTo("high_memory")
+ assertThat(bundle).string("storage_tier").isEqualTo("high_storage")
+ assertThat(bundle).string("network_type").isEqualTo("wifi")
+ assertThat(bundle).string("current_screen").isEqualTo("home_screen")
+ assertThat(bundle).longInt("apk_size_bytes").isEqualTo(TEST_APK_SIZE)
+ }
+
+ @Test
+ fun testFillPerformanceMetricBundle_createStorageUsageLogMetric_bundlesAllDetailsCorrectly() {
+ setUpTestApplicationComponent()
+ val bundle = Bundle()
+
+ val performanceMetric = createPerformanceMetricLog(
+ loggableMetric = createStorageUsageLoggableMetric()
+ )
+ val typeName = eventBundleCreator.fillPerformanceMetricsEventBundle(
+ performanceMetric, bundle
+ )
+
+ assertThat(typeName).isEqualTo("storage_usage_metric")
+ assertThat(bundle).hasSize(8)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("high_priority")
+ assertThat(bundle).string("is_app_in_foreground").isEqualTo("true")
+ assertThat(bundle).string("memory_tier").isEqualTo("high_memory")
+ assertThat(bundle).string("storage_tier").isEqualTo("high_storage")
+ assertThat(bundle).string("network_type").isEqualTo("wifi")
+ assertThat(bundle).string("current_screen").isEqualTo("home_screen")
+ assertThat(bundle).longInt("storage_usage_bytes").isEqualTo(TEST_STORAGE_USAGE)
+ }
+
+ @Test
+ fun testFillPerformanceMetricBundle_createStartupLatencyMetric_bundlesAllDetailsCorrectly() {
+ setUpTestApplicationComponent()
+ val bundle = Bundle()
+
+ val performanceMetric = createPerformanceMetricLog(
+ loggableMetric = createStartupLatencyLoggableMetric()
+ )
+ val typeName = eventBundleCreator.fillPerformanceMetricsEventBundle(
+ performanceMetric, bundle
+ )
+
+ assertThat(typeName).isEqualTo("startup_latency_metric")
+ assertThat(bundle).hasSize(8)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("high_priority")
+ assertThat(bundle).string("is_app_in_foreground").isEqualTo("true")
+ assertThat(bundle).string("memory_tier").isEqualTo("high_memory")
+ assertThat(bundle).string("storage_tier").isEqualTo("high_storage")
+ assertThat(bundle).string("network_type").isEqualTo("wifi")
+ assertThat(bundle).string("current_screen").isEqualTo("home_screen")
+ assertThat(bundle).longInt("startup_latency_millis").isEqualTo(TEST_STARTUP_LATENCY)
+ }
+
+ @Test
+ fun testFillPerformanceMetricBundle_createMemoryUsageMetric_fillsAllDetailsInBundleCorrectly() {
+ setUpTestApplicationComponent()
+ val bundle = Bundle()
+
+ val performanceMetric = createPerformanceMetricLog(
+ loggableMetric = createMemoryUsageLoggableMetric()
+ )
+ val typeName = eventBundleCreator.fillPerformanceMetricsEventBundle(
+ performanceMetric, bundle
+ )
+
+ assertThat(typeName).isEqualTo("memory_usage_metric")
+ assertThat(bundle).hasSize(8)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("high_priority")
+ assertThat(bundle).string("is_app_in_foreground").isEqualTo("true")
+ assertThat(bundle).string("memory_tier").isEqualTo("high_memory")
+ assertThat(bundle).string("storage_tier").isEqualTo("high_storage")
+ assertThat(bundle).string("network_type").isEqualTo("wifi")
+ assertThat(bundle).string("current_screen").isEqualTo("home_screen")
+ assertThat(bundle).longInt("total_pss_bytes").isEqualTo(TEST_MEMORY_USAGE)
+ }
+
+ @Test
+ fun testFillPerformanceMetricBundle_createNetworkUsageMetric_fillsAllDetailsInBundleCorrectly() {
+ setUpTestApplicationComponent()
+ val bundle = Bundle()
+
+ val performanceMetric = createPerformanceMetricLog(
+ loggableMetric = createNetworkUsageTestLoggableMetric()
+ )
+ val typeName = eventBundleCreator.fillPerformanceMetricsEventBundle(
+ performanceMetric, bundle
+ )
+
+ assertThat(typeName).isEqualTo("network_usage_metric")
+ assertThat(bundle).hasSize(9)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("high_priority")
+ assertThat(bundle).string("is_app_in_foreground").isEqualTo("true")
+ assertThat(bundle).string("memory_tier").isEqualTo("high_memory")
+ assertThat(bundle).string("storage_tier").isEqualTo("high_storage")
+ assertThat(bundle).string("network_type").isEqualTo("wifi")
+ assertThat(bundle).string("current_screen").isEqualTo("home_screen")
+ assertThat(bundle).longInt("bytes_received").isEqualTo(TEST_NETWORK_USAGE)
+ assertThat(bundle).longInt("bytes_sent").isEqualTo(TEST_NETWORK_USAGE)
+ }
+
+ @Test
+ fun testFillPerformanceMetricBundle_createCpuUsageLogMetric_fillsAllDetailsInBundleCorrectly() {
+ setUpTestApplicationComponent()
+ val bundle = Bundle()
+
+ val performanceMetric = createPerformanceMetricLog(
+ loggableMetric = createCpuUsageLoggableMetric()
+ )
+ val typeName = eventBundleCreator.fillPerformanceMetricsEventBundle(
+ performanceMetric, bundle
+ )
+
+ assertThat(typeName).isEqualTo("cpu_usage_metric")
+ assertThat(bundle).hasSize(8)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("high_priority")
+ assertThat(bundle).string("is_app_in_foreground").isEqualTo("true")
+ assertThat(bundle).string("memory_tier").isEqualTo("high_memory")
+ assertThat(bundle).string("storage_tier").isEqualTo("high_storage")
+ assertThat(bundle).string("network_type").isEqualTo("wifi")
+ assertThat(bundle).string("current_screen").isEqualTo("home_screen")
+ assertThat(bundle).longInt("cpu_usage").isEqualTo(TEST_CPU_USAGE)
+ }
+
@Test
fun testFillEventBundle_openPracticeTabContextEvent_fillsAllFieldsInBundleAndReturnsName() {
setUpTestApplicationComponent()
@@ -949,6 +1249,26 @@ class EventBundleCreatorTest {
this.context = context
}.build()
+ private fun createPerformanceMetricLog(
+ timestamp: Long = TEST_TIMESTAMP_1,
+ priority: Priority = HIGH_PRIORITY,
+ currentScreen: CurrentScreen = HOME_SCREEN,
+ memoryTier: MemoryTier = HIGH_MEMORY_TIER,
+ storageTier: StorageTier = HIGH_STORAGE,
+ isAppInForeground: Boolean = true,
+ networkType: NetworkType = WIFI,
+ loggableMetric: LoggableMetric = LoggableMetric.getDefaultInstance()
+ ) = OppiaMetricLog.newBuilder().apply {
+ this.timestampMillis = timestamp
+ this.priority = priority
+ this.currentScreen = currentScreen
+ this.memoryTier = memoryTier
+ this.storageTier = storageTier
+ this.isAppInForeground = isAppInForeground
+ this.networkType = networkType
+ this.loggableMetric = loggableMetric
+ }.build()
+
private fun createOpenExplorationActivity(
explorationContext: ExplorationContext = createExplorationContext()
) = createEventContext(explorationContext, EventContextBuilder::setOpenExplorationActivity)
@@ -1138,6 +1458,49 @@ class EventBundleCreatorTest {
this.contentId = contentId
}.build()
+ private fun createApkSizeLoggableMetric() = OppiaMetricLog.LoggableMetric.newBuilder()
+ .setApkSizeMetric(
+ OppiaMetricLog.ApkSizeMetric.newBuilder()
+ .setApkSizeBytes(TEST_APK_SIZE)
+ .build()
+ ).build()
+
+ private fun createStorageUsageLoggableMetric() = LoggableMetric.newBuilder()
+ .setStorageUsageMetric(
+ OppiaMetricLog.StorageUsageMetric.newBuilder()
+ .setStorageUsageBytes(TEST_STORAGE_USAGE)
+ .build()
+ ).build()
+
+ private fun createStartupLatencyLoggableMetric() = LoggableMetric.newBuilder()
+ .setStartupLatencyMetric(
+ OppiaMetricLog.StartupLatencyMetric.newBuilder()
+ .setStartupLatencyMillis(TEST_STARTUP_LATENCY)
+ .build()
+ ).build()
+
+ private fun createCpuUsageLoggableMetric() = LoggableMetric.newBuilder()
+ .setCpuUsageMetric(
+ OppiaMetricLog.CpuUsageMetric.newBuilder()
+ .setCpuUsageMetric(TEST_CPU_USAGE)
+ .build()
+ ).build()
+
+ private fun createNetworkUsageTestLoggableMetric() = LoggableMetric.newBuilder()
+ .setNetworkUsageMetric(
+ OppiaMetricLog.NetworkUsageMetric.newBuilder()
+ .setBytesReceived(TEST_NETWORK_USAGE)
+ .setBytesSent(TEST_NETWORK_USAGE)
+ .build()
+ ).build()
+
+ private fun createMemoryUsageLoggableMetric() = LoggableMetric.newBuilder()
+ .setMemoryUsageMetric(
+ OppiaMetricLog.MemoryUsageMetric.newBuilder()
+ .setTotalPssBytes(TEST_MEMORY_USAGE)
+ .build()
+ ).build()
+
private fun setUpTestApplicationComponentWithoutLearnerAnalyticsStudy() {
setUpTestApplicationComponent()
}
diff --git a/utility/src/test/java/org/oppia/android/util/logging/firebase/LogReportingModuleTest.kt b/utility/src/test/java/org/oppia/android/util/logging/firebase/LogReportingModuleTest.kt
new file mode 100644
index 00000000000..83f50f95c21
--- /dev/null
+++ b/utility/src/test/java/org/oppia/android/util/logging/firebase/LogReportingModuleTest.kt
@@ -0,0 +1,150 @@
+package org.oppia.android.util.logging.firebase
+
+import android.app.Application
+import android.content.Context
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.google.common.truth.Truth.assertThat
+import dagger.Binds
+import dagger.BindsInstance
+import dagger.Component
+import dagger.Module
+import dagger.Provides
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.oppia.android.testing.robolectric.RobolectricModule
+import org.oppia.android.testing.threading.TestDispatcherModule
+import org.oppia.android.testing.time.FakeOppiaClockModule
+import org.oppia.android.util.data.DataProvidersInjector
+import org.oppia.android.util.data.DataProvidersInjectorProvider
+import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLogger
+import org.oppia.android.util.logging.LoggerModule
+import org.oppia.android.util.logging.SyncStatusModule
+import org.oppia.android.util.logging.performancemetrics.PerformanceMetricsEventLogger
+import org.oppia.android.util.networking.NetworkConnectionUtilDebugModule
+import org.oppia.android.util.platformparameter.ENABLE_LANGUAGE_SELECTION_UI_DEFAULT_VALUE
+import org.oppia.android.util.platformparameter.EnableLanguageSelectionUi
+import org.oppia.android.util.platformparameter.LearnerStudyAnalytics
+import org.oppia.android.util.platformparameter.PlatformParameterValue
+import org.oppia.android.util.platformparameter.SPLASH_SCREEN_WELCOME_MSG_DEFAULT_VALUE
+import org.oppia.android.util.platformparameter.SYNC_UP_WORKER_TIME_PERIOD_IN_HOURS_DEFAULT_VALUE
+import org.oppia.android.util.platformparameter.SplashScreenWelcomeMsg
+import org.oppia.android.util.platformparameter.SyncUpWorkerTimePeriodHours
+import org.robolectric.annotation.Config
+import org.robolectric.annotation.LooperMode
+import javax.inject.Inject
+import javax.inject.Singleton
+
+/** Tests for [LogReportingModule]. */
+// FunctionName: test names are conventionally named with underscores.
+@Suppress("FunctionName")
+@RunWith(AndroidJUnit4::class)
+@LooperMode(LooperMode.Mode.PAUSED)
+@Config(application = LogReportingModuleTest.TestApplication::class)
+class LogReportingModuleTest {
+
+ @Inject
+ lateinit var performanceMetricsEventLogger: PerformanceMetricsEventLogger
+
+ @Inject
+ lateinit var eventLogger: EventLogger
+
+ @Before
+ fun setUp() {
+ setUpTestApplicationComponent()
+ }
+
+ @Test
+ fun testModule_injectsProductionImplementationOfEventLogger() {
+ assertThat(eventLogger).isInstanceOf(FirebaseEventLogger::class.java)
+ }
+
+ @Test
+ fun testModule_injectsProductionImplementationOfPerformanceMetricsEventLogger() {
+ assertThat(performanceMetricsEventLogger).isInstanceOf(FirebaseEventLogger::class.java)
+ }
+
+ private fun setUpTestApplicationComponent() {
+ ApplicationProvider.getApplicationContext().inject(this)
+ }
+
+ // TODO(#89): Move this to a common test application component.
+ @Module
+ interface TestModule {
+ @Binds
+ fun provideContext(application: Application): Context
+ }
+
+ @Module
+ class TestPlatformParameterModule {
+
+ companion object {
+ var forceLearnerAnalyticsStudy: Boolean = false
+ }
+
+ @Provides
+ @SplashScreenWelcomeMsg
+ fun provideSplashScreenWelcomeMsgParam(): PlatformParameterValue {
+ return PlatformParameterValue.createDefaultParameter(SPLASH_SCREEN_WELCOME_MSG_DEFAULT_VALUE)
+ }
+
+ @Provides
+ @SyncUpWorkerTimePeriodHours
+ fun provideSyncUpWorkerTimePeriod(): PlatformParameterValue {
+ return PlatformParameterValue.createDefaultParameter(
+ SYNC_UP_WORKER_TIME_PERIOD_IN_HOURS_DEFAULT_VALUE
+ )
+ }
+
+ @Provides
+ @EnableLanguageSelectionUi
+ fun provideEnableLanguageSelectionUi(): PlatformParameterValue {
+ return PlatformParameterValue.createDefaultParameter(
+ ENABLE_LANGUAGE_SELECTION_UI_DEFAULT_VALUE
+ )
+ }
+
+ @Provides
+ @LearnerStudyAnalytics
+ fun provideLearnerStudyAnalytics(): PlatformParameterValue {
+ return PlatformParameterValue.createDefaultParameter(forceLearnerAnalyticsStudy)
+ }
+ }
+
+ // TODO(#89): Move this to a common test application component.
+ @Singleton
+ @Component(
+ modules = [
+ TestModule::class, LogReportingModule::class, TestDispatcherModule::class,
+ RobolectricModule::class, FakeOppiaClockModule::class,
+ NetworkConnectionUtilDebugModule::class, LocaleProdModule::class,
+ TestPlatformParameterModule::class, LoggerModule::class, SyncStatusModule::class
+ ]
+ )
+ interface TestApplicationComponent : DataProvidersInjector {
+ @Component.Builder
+ interface Builder {
+ @BindsInstance
+ fun setApplication(application: Application): Builder
+ fun build(): TestApplicationComponent
+ }
+
+ fun inject(logReportingModuleTest: LogReportingModuleTest)
+ }
+
+ class TestApplication : Application(), DataProvidersInjectorProvider {
+ private val component: TestApplicationComponent by lazy {
+ DaggerLogReportingModuleTest_TestApplicationComponent.builder()
+ .setApplication(this)
+ .build()
+ }
+
+ fun inject(test: LogReportingModuleTest) {
+ component.inject(test)
+ }
+
+ override fun getDataProvidersInjector(): DataProvidersInjector = component
+ }
+}
From b1784f0b8d65a921c426b4a5fe3ce8e336c74bba Mon Sep 17 00:00:00 2001
From: Ben Henning
Date: Wed, 7 Sep 2022 04:45:23 -0700
Subject: [PATCH 31/57] Add strings for #4417. (#4566)
## Explanation
Fix part of #4300.
This PR introduces the strings needed in #4417 in isolation so that they can be translated via Translatewiki sooner than #4417 will be merged.
## Essential Checklist
- [x] The PR title and explanation each start with "Fix #bugnum: " (If this PR fixes part of an issue, prefix the title with "Fix part of #bugnum: ...".)
- [x] Any changes to [scripts/assets](https://github.com/oppia/oppia-android/tree/develop/scripts/assets) files have their rationale included in the PR explanation.
- [x] The PR follows the [style guide](https://github.com/oppia/oppia-android/wiki/Coding-style-guide).
- [x] The PR does not contain any unnecessary code changes from Android Studio ([reference](https://github.com/oppia/oppia-android/wiki/Guidance-on-submitting-a-PR#undo-unnecessary-changes)).
- [x] The PR is made from a branch that's **not** called "develop" and is up-to-date with "develop".
- [x] The PR is **assigned** to the appropriate reviewers ([reference](https://github.com/oppia/oppia-android/wiki/Guidance-on-submitting-a-PR#clarification-regarding-assignees-and-reviewers-section)).
## For UI-specific PRs only
This PR only introduces strings and otherwise doesn't affect the UI.
---
app/src/main/res/values/strings.xml | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index dbb8d131dbb..78eb62fc67f 100755
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -484,6 +484,17 @@
Close app
+ Developer Build
+ Alpha
+ Beta
+ Beta Notice
+ Hello! Your app is now being updated to the Beta version. If you experience problems while using the app, or have questions, please contact us at android-feedback@oppia.org.
+ Don\'t show this message again
+ OK
+ General Availability Notice
+ Hello! Your app is now being updated to the General Availability version. If you experience problems while using the app, or have questions, please contact us at android-feedback@oppia.org.
+ Don\'t show this message again
+ OK
\u0020to\u0020
From c639763a6b3915bde1b631a265e0619b98fb6afc Mon Sep 17 00:00:00 2001
From: MOHIT GUPTA <76530270+MohitGupta121@users.noreply.github.com>
Date: Wed, 7 Sep 2022 17:24:58 +0530
Subject: [PATCH 32/57] Fixes part of #4177: Dark mode Topic Activity Part 1
(#4550)
* fixed text cut off
* fix text cutoff in all layouts
* add proper naming
* develop updated
* minor changes
* dark_mode:Toolbar + Tabs in first PR
---
app/src/main/res/layout/topic_fragment.xml | 4 ++--
app/src/main/res/values/component_colors.xml | 3 +++
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/app/src/main/res/layout/topic_fragment.xml b/app/src/main/res/layout/topic_fragment.xml
index 76cf7c1940b..be08c19acdf 100644
--- a/app/src/main/res/layout/topic_fragment.xml
+++ b/app/src/main/res/layout/topic_fragment.xml
@@ -27,7 +27,7 @@
android:id="@+id/topic_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
- android:background="?attr/colorPrimary"
+ android:background="@color/component_color_topic_fragment_primary_toolbar_color"
android:fontFamily="sans-serif"
android:minHeight="?attr/actionBarSize"
android:theme="@style/Widget.AppCompat.ActionBar"
@@ -52,7 +52,7 @@
android:layout_marginEnd="@dimen/topic_fragment_tab_layout_margin_end"
android:textSize="14sp"
app:layout_constraintTop_toTopOf="parent"
- app:tabBackground="@color/oppia_primary"
+ app:tabBackground="@color/component_color_topic_fragment_primary_tab_color"
app:tabGravity="fill"
app:tabIconTint="@color/tab_icon_color_selector"
app:tabIndicatorColor="@android:color/white"
diff --git a/app/src/main/res/values/component_colors.xml b/app/src/main/res/values/component_colors.xml
index c0f7bc573a6..64569c005a3 100644
--- a/app/src/main/res/values/component_colors.xml
+++ b/app/src/main/res/values/component_colors.xml
@@ -239,5 +239,8 @@
@color/color_palette_dark_text_color@color/color_palette_dark_text_color
+
+ @color/color_palette_toolbar_color
+ @color/color_palette_secondary_toolbar_color
From ca2660f0c2ea3c754d2fc88ac68fa516f3d99bdd Mon Sep 17 00:00:00 2001
From: Ben Henning
Date: Wed, 7 Sep 2022 05:45:31 -0700
Subject: [PATCH 33/57] Fix #4366, #3611, #4323: Add app data reset flow to
facilitate being able to reset the admin pin (#4418)
## Explanation
Fixes #4366
Fixes #3611
Fixes #4323
This PR introduces a data reset flow for cases when the user fails to remember their administrator pin. Since there's no remote profile support currently, the only option is to clear all profiles on the device. This is done using a two-step dialog since the action is permanent (at least for now--in the future we could consider making a local backup that could be restored, but that could become pretty complicated).
While this isn't a great solution, it's better than not having an option at all since users can currently get permanently stuck (see #3611). While this doesn't directly fix #3611, it mitigates it by providing a proper in-app means of resetting app data.
#4323 seems unrelated, but resetting the app required routing back to SplashActivity which means this PR needed to introduce a robustness mechanism to not set the app locale unless it wasn't already initialized (which bypasses the bug mentioned by that issue).
Mechanically, the deletion process involves:
- Deleting all profiles on the device
- Updating the in-memory cache (which causes a few UI glitches)
- "Restarting" the app by ending the activity and routing back to SplashActivity
This replaces the existing "forgot PIN" flow for admins, and it technically does not reset non-profile data (such as the device installation ID, onboarding status, analytics/crash events, and some device-wide preferences).
## Essential Checklist
- [x] The PR title and explanation each start with "Fix #bugnum: " (If this PR fixes part of an issue, prefix the title with "Fix part of #bugnum: ...".)
- [x] Any changes to [scripts/assets](https://github.com/oppia/oppia-android/tree/develop/scripts/assets) files have their rationale included in the PR explanation.
- [x] The PR follows the [style guide](https://github.com/oppia/oppia-android/wiki/Coding-style-guide).
- [x] The PR does not contain any unnecessary code changes from Android Studio ([reference](https://github.com/oppia/oppia-android/wiki/Guidance-on-submitting-a-PR#undo-unnecessary-changes)).
- [x] The PR is made from a branch that's **not** called "develop" and is up-to-date with "develop".
- [x] The PR is **assigned** to the appropriate reviewers ([reference](https://github.com/oppia/oppia-android/wiki/Guidance-on-submitting-a-PR#clarification-regarding-assignees-and-reviewers-section)).
## For UI-specific PRs only
This PR is using the app's existing alert dialog theme, so it's not particularly interesting to show landscape/tablet screenshots as the UI isn't fundamentally different. The same is the case for special internationalization or accessibility concerns.
In terms of a demonstration of the new flow, see the following video:
https://user-images.githubusercontent.com/12983742/186572278-d0238e62-d013-419a-9c49-afe97cd10a5d.mp4
#4567 is tracking introducing tests, and the PR addressing it for these changes will include demonstrations of changed Espresso tests.
Commits:
* Add app data reset flow for resetting admin pin.
* Fix broken test.
* Update text & fix data reset issue.
---
.../app/profile/PinPasswordActivity.kt | 2 +-
.../profile/PinPasswordActivityPresenter.kt | 73 +++++++++++++------
.../app/profile/ProfileChooserViewModel.kt | 2 +-
.../app/splash/SplashActivityPresenter.kt | 7 +-
app/src/main/res/values/strings.xml | 10 ++-
.../app/profile/PinPasswordActivityTest.kt | 2 +-
.../profile/ProfileManagementController.kt | 30 +++++++-
7 files changed, 91 insertions(+), 35 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/profile/PinPasswordActivity.kt b/app/src/main/java/org/oppia/android/app/profile/PinPasswordActivity.kt
index 54a57da71c7..2930f74c828 100644
--- a/app/src/main/java/org/oppia/android/app/profile/PinPasswordActivity.kt
+++ b/app/src/main/java/org/oppia/android/app/profile/PinPasswordActivity.kt
@@ -44,6 +44,6 @@ class PinPasswordActivity : InjectableAppCompatActivity(), ProfileRouteDialogInt
override fun onDestroy() {
super.onDestroy()
- pinPasswordActivityPresenter.dismissAlertDialog()
+ pinPasswordActivityPresenter.handleOnDestroy()
}
}
diff --git a/app/src/main/java/org/oppia/android/app/profile/PinPasswordActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/profile/PinPasswordActivityPresenter.kt
index 1a7ba8e23dc..b9592c2a5c3 100644
--- a/app/src/main/java/org/oppia/android/app/profile/PinPasswordActivityPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/profile/PinPasswordActivityPresenter.kt
@@ -1,8 +1,5 @@
package org.oppia.android.app.profile
-import android.content.ActivityNotFoundException
-import android.content.Intent
-import android.net.Uri
import android.text.method.PasswordTransformationMethod
import android.view.animation.AnimationUtils
import androidx.appcompat.app.AlertDialog
@@ -21,6 +18,7 @@ import org.oppia.android.domain.profile.ProfileManagementController
import org.oppia.android.util.data.AsyncResult
import org.oppia.android.util.data.DataProviders.Companion.toLiveData
import javax.inject.Inject
+import kotlin.system.exitProcess
private const val TAG_ADMIN_SETTINGS_DIALOG = "ADMIN_SETTINGS_DIALOG"
private const val TAG_RESET_PIN_DIALOG = "RESET_PIN_DIALOG"
@@ -38,6 +36,7 @@ class PinPasswordActivityPresenter @Inject constructor(
}
private var profileId = -1
private lateinit var alertDialog: AlertDialog
+ private var confirmedDeletion = false
fun handleOnCreate() {
val adminPin = activity.intent.getStringExtra(PIN_PASSWORD_ADMIN_PIN_EXTRA_KEY)
@@ -166,43 +165,71 @@ class PinPasswordActivityPresenter @Inject constructor(
private fun showAdminForgotPin() {
val appName = resourceHandler.getStringInLocale(R.string.app_name)
pinViewModel.showAdminPinForgotPasswordPopUp.set(true)
+ val resetDataButtonText =
+ resourceHandler.getStringInLocaleWithWrapping(
+ R.string.admin_forgot_pin_reset_app_data_button_text, appName
+ )
alertDialog = AlertDialog.Builder(activity, R.style.OppiaAlertDialogTheme)
.setTitle(R.string.pin_password_forgot_title)
.setMessage(
- resourceHandler.getStringInLocaleWithWrapping(R.string.pin_password_forgot_message, appName)
+ resourceHandler.getStringInLocaleWithWrapping(R.string.admin_forgot_pin_message, appName)
)
.setNegativeButton(R.string.admin_settings_cancel) { dialog, _ ->
pinViewModel.showAdminPinForgotPasswordPopUp.set(false)
dialog.dismiss()
}
- .setPositiveButton(R.string.pin_password_play_store) { dialog, _ ->
+ .setPositiveButton(resetDataButtonText) { dialog, _ ->
+ // Show a confirmation dialog since this is a permanent action.
+ dialog.dismiss()
+ showConfirmAppResetDialog()
+ }.create()
+ alertDialog.setCanceledOnTouchOutside(false)
+ alertDialog.show()
+ }
+
+ private fun showConfirmAppResetDialog() {
+ val appName = resourceHandler.getStringInLocale(R.string.app_name)
+ alertDialog = AlertDialog.Builder(activity, R.style.OppiaAlertDialogTheme)
+ .setTitle(
+ resourceHandler.getStringInLocaleWithWrapping(
+ R.string.admin_confirm_app_wipe_title, appName
+ )
+ )
+ .setMessage(
+ resourceHandler.getStringInLocaleWithWrapping(
+ R.string.admin_confirm_app_wipe_message, appName
+ )
+ )
+ .setNegativeButton(R.string.admin_confirm_app_wipe_negative_button_text) { dialog, _ ->
pinViewModel.showAdminPinForgotPasswordPopUp.set(false)
- try {
- activity.startActivity(
- Intent(
- Intent.ACTION_VIEW,
- Uri.parse("market://details?id=" + activity.packageName)
- )
- )
- } catch (e: ActivityNotFoundException) {
- activity.startActivity(
- Intent(
- Intent.ACTION_VIEW,
- Uri.parse(
- "https://play.google.com/store/apps/details?id=" + activity.packageName
- )
- )
- )
- }
dialog.dismiss()
+ }
+ .setPositiveButton(R.string.admin_confirm_app_wipe_positive_button_text) { dialog, _ ->
+ profileManagementController.deleteAllProfiles().toLiveData().observe(
+ activity,
+ {
+ // Regardless of the result of the operation, always restart the app.
+ confirmedDeletion = true
+ activity.finishAffinity()
+ }
+ )
}.create()
+ alertDialog.setCanceledOnTouchOutside(false)
alertDialog.show()
}
- fun dismissAlertDialog() {
+ fun handleOnDestroy() {
if (::alertDialog.isInitialized && alertDialog.isShowing) {
alertDialog.dismiss()
}
+
+ if (confirmedDeletion) {
+ confirmedDeletion = false
+
+ // End the process forcibly since the app is not designed to recover from major on-disk state
+ // changes that happen from underneath it (like deleting all profiles).
+ exitProcess(0)
+ }
}
private fun showSuccessDialog() {
diff --git a/app/src/main/java/org/oppia/android/app/profile/ProfileChooserViewModel.kt b/app/src/main/java/org/oppia/android/app/profile/ProfileChooserViewModel.kt
index d78a40767e7..266ad9983c8 100644
--- a/app/src/main/java/org/oppia/android/app/profile/ProfileChooserViewModel.kt
+++ b/app/src/main/java/org/oppia/android/app/profile/ProfileChooserViewModel.kt
@@ -65,7 +65,7 @@ class ProfileChooserViewModel @Inject constructor(
machineLocale.run { it.profile.name.toMachineLowerCase() }
}.toMutableList()
- val adminProfile = sortedProfileList.find { it.profile.isAdmin }!!
+ val adminProfile = sortedProfileList.find { it.profile.isAdmin } ?: return listOf()
sortedProfileList.remove(adminProfile)
adminPin = adminProfile.profile.pin
diff --git a/app/src/main/java/org/oppia/android/app/splash/SplashActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/splash/SplashActivityPresenter.kt
index 84fe06a1197..fd02c1ea32b 100644
--- a/app/src/main/java/org/oppia/android/app/splash/SplashActivityPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/splash/SplashActivityPresenter.kt
@@ -69,8 +69,11 @@ class SplashActivityPresenter @Inject constructor(
// in the case of the deprecation dialog, blocks) the activity.
liveData.removeObserver(this)
- // First, initialize the app's initial locale.
- appLanguageLocaleHandler.initializeLocale(initState.displayLocale)
+ // First, initialize the app's initial locale. Note that since the activity can be
+ // reopened, it's possible for this to be initialized more than once.
+ if (!appLanguageLocaleHandler.isInitialized()) {
+ appLanguageLocaleHandler.initializeLocale(initState.displayLocale)
+ }
// Second, route the user to the correct destination.
when (initState.startupMode) {
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 78eb62fc67f..145c532470f 100755
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -297,15 +297,19 @@
Please enter your PIN.Administrator’s 5-Digit PIN.User’s 3-Digit PIN.
- I forgot my pin.
+ Forgot PIN?Incorrect PIN.showhideClosePIN change is successfulForgot PIN?
- To reset your PIN, please uninstall %s and then reinstall it.\n\nKeep in mind that if the device has not been online, you may lose user progress on multiple accounts.
- Go to the play store
+ To reset your PIN, you\'ll need to clear all saved data for %s.\n\nKeep in mind that this action will cause all profiles and user progress to be deleted, and it cannot be undone. Also, the app will close when this completes and will need to be reopened.
+ Reset %s Data
+ Confirm %s Data Reset
+ Are you sure that you want to delete all %s profiles on this device? This operation cannot be undone.
+ Yes
+ NoShow/Hide password iconPassword shown iconPassword hidden icon
diff --git a/app/src/sharedTest/java/org/oppia/android/app/profile/PinPasswordActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/profile/PinPasswordActivityTest.kt
index f7f5fa8fe29..e8770e57d44 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/profile/PinPasswordActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/profile/PinPasswordActivityTest.kt
@@ -1125,7 +1125,7 @@ class PinPasswordActivityTest {
private fun getAppName(): String = context.resources.getString(R.string.app_name)
private fun getPinPasswordForgotMessage(): String =
- context.resources.getString(R.string.pin_password_forgot_message, getAppName())
+ context.resources.getString(R.string.admin_forgot_pin_message, getAppName())
// TODO(#59): Figure out a way to reuse modules instead of needing to re-declare them.
@Singleton
diff --git a/domain/src/main/java/org/oppia/android/domain/profile/ProfileManagementController.kt b/domain/src/main/java/org/oppia/android/domain/profile/ProfileManagementController.kt
index 29f8ce50ac2..dac62b05666 100644
--- a/domain/src/main/java/org/oppia/android/domain/profile/ProfileManagementController.kt
+++ b/domain/src/main/java/org/oppia/android/domain/profile/ProfileManagementController.kt
@@ -132,7 +132,7 @@ class ProfileManagementController @Inject constructor(
profileDataStore.primeInMemoryCacheAsync().invokeOnCompletion {
it?.let {
oppiaLogger.e(
- "DOMAIN",
+ "ProfileManagementController",
"Failed to prime cache ahead of data retrieval for ProfileManagementController.",
it
)
@@ -664,9 +664,7 @@ class ProfileManagementController @Inject constructor(
* @return a [DataProvider] that indicates the success/failure of this delete operation.
*/
fun deleteProfile(profileId: ProfileId): DataProvider {
- val deferred = profileDataStore.storeDataWithCustomChannelAsync(
- updateInMemoryCache = true
- ) {
+ val deferred = profileDataStore.storeDataWithCustomChannelAsync(updateInMemoryCache = true) {
if (!it.profilesMap.containsKey(profileId.internalId)) {
return@storeDataWithCustomChannelAsync Pair(it, ProfileActionStatus.PROFILE_NOT_FOUND)
}
@@ -683,6 +681,30 @@ class ProfileManagementController @Inject constructor(
}
}
+ /**
+ * Deletes all profiles installed on the device (and logs out the current user).
+ *
+ * Note that this will not update the in-memory cache as the app is expected to be forcibly closed
+ * after deletion (since there's no mechanism to notify existing cache stores that they need to
+ * reload/reset from their on-disk copies).
+ *
+ * Finally, this method attempts to never fail by forcibly deleting all profiles even if some are
+ * in a bad state (and would normally failed if attempted to be deleted via [deleteProfile]).
+ */
+ fun deleteAllProfiles(): DataProvider {
+ val deferred = profileDataStore.storeDataWithCustomChannelAsync {
+ val installationId = loggingIdentifierController.fetchInstallationId()
+ it.profilesMap.forEach { (internalProfileId, profile) ->
+ directoryManagementUtil.deleteDir(internalProfileId.toString())
+ learnerAnalyticsLogger.logDeleteProfile(installationId, profile.learnerId)
+ }
+ Pair(ProfileDatabase.getDefaultInstance(), ProfileActionStatus.SUCCESS)
+ }
+ return dataProviders.createInMemoryDataProviderAsync(DELETE_PROFILE_PROVIDER_ID) {
+ getDeferredResult(profileId = null, name = null, deferred)
+ }
+ }
+
/**
* Returns the ProfileId of the current profile. The default value is -1 if currentProfileId
* hasn't been set.
From d22f502dbf01b21dd9b54002dd564b23f1c12043 Mon Sep 17 00:00:00 2001
From: Ben Henning
Date: Wed, 7 Sep 2022 22:40:40 -0700
Subject: [PATCH 34/57] Fix #4300, #2432: Introduce beta & general availability
update notices and build flavors (#4417)
## Explanation
Fixes #4300
Fixes #2432
This PR introduces support for showing notices when users change from certain flavors of the app to the beta and/or GA (general availability) flavors (both of which are newly introduced in this PR).
The user behavior is as follows:
- Changing from any flavor _to_ beta will result in the beta notice showing for the user the *first* time they open the app.
- Changing from alpha or beta flavors _to_ the GA flavor will result in the GA notice being shown.
- The user will always see the notice after the first open following one of these transitions, and in no other cases (including the first open for beta).
- The user will not see one or both notices if they select the "never show again" checkbox(es) prior to dismissing the notice(s).
- The app deprecation notice will always take logical precedence over other notices (i.e. it will always show in cases when the app is deprecated regardless of flavor transitions).
In addition to the above, text was added to the splash screen for the developer, alpha, and beta flavors of the app to make it a bit more explicit to the user. The alpha and beta splash experiences have been configured to wait 2 seconds so that the user has a moment to see the actual text before the app finishes loading.
Note also that existing alpha users will not see the beta notice after installing the first beta version (since no flavor has been recorded). While this is technically fixable, it doesn't seem worthwhile given the current small user audience that would be affected. Subsequent transitions from alpha to beta will work as expected (and lead to the beta notice being shown).
As a side note: #2432 is fixed as of this PR since the final planned build flavors are being introduced here. While more flavors may be added in the future, it seems sufficient to consider "build flavors are introduced" to be done now that there are developer, alpha, beta, and GA flavors of the app.
Technical things of note:
- The splash screen now has a contingency fallback of 5 seconds in case the startup state doesn't ever load/the app gets stuck (it will fall back to a default state).
- The transitions required a new BuildFlavor proto to be included and bound to Dagger. For tests and the e2e test application component, a new testing-specific flavor has been introduced (though it's never expected to correspond to a distributable build of the app).
- The existing 'deprecation' package under the app module has been repurposed to be the location for all notices in the app (including the two new ones). We'll likely add more here in the future, as well (such as the GA deprecation notices).
- The new beta and GA flavors of the app have been added to the build_tests CI workflow--you can see the artifacts of the workflow in this PR or on develop after the PR is merged for downloads to the corresponding built AABs.
- The Kenya-specific alpha version of the app has the same 'alpha' build flavor as the default alpha version of the app since there doesn't seem to be any reason why they should differ here.
- Some places were updated to use Application instead of Context to make things a bit tighter in expectation for *what* type of context is available to use (for cases when casting to injector providers is used). This helps to avoid a particularly challenging bug that I ran into during test development wherein the wrong context was being used after creating a new application (since that application's application context was pointing to the original application). This means that ``Application.getApplicationContext()`` may actually not return itself in instrumentation cases. The changes help avoid this leading to actual issues in tests (but they should have no impact on the app's behavior in production environments).
- PersistentCacheStore had a few significant changes to better facilitate the needs of this PR's domain changes:
- Changes in the store are only published to its in-memory cache (and subsequently notified to subscribers of the store) if the cache store actually changes.
- The store's existing two priming functions were combined into a single new one with more flexibility as it can be used to tweak both changing the on-disk cache and publishing the in-memory one. The documentation around priming has also been significantly improved in terms of detail as I now think it's a legitimate use case that we'll want to use in more places in the future.
- InMemoryBlockingCache was updated to include publishing before-and-after values to its registered observer callback to avoid over-notifying for alterations to the cache that don't logically change it (this can actually lead to subtle differences in behavior that may not always be expected, so the change should improve robustness of the cache).
Details regarding test changes & exemptions:
- SplashActivityTest and AppStartupStateControllerTest were updated to enable parameterized testing since they have to test many different cases of build flavor transitions.
- The only test exemptions were: renames (deprecation notice classes), files that can't be tested (applications, application components, and listeners), and files that are not conventionally tested (test activities and fragment presenters).
- A new BUILD file was added for PersistentCacheStoreTest (which made development a bit easier when verifying some of the changes that ended up breaking the test suite).
- One of SplashActivityTest's error case tests were removed since it now seems impossible to trigger a situation that could actually cause it. Similarly, the pending case with 5-second timeout also seems impossible to test, though it's theoretically possible to occur if something catastrophically goes wrong in a production environment with a real clock.
## Essential Checklist
- [x] The PR title and explanation each start with "Fix #bugnum: " (If this PR fixes part of an issue, prefix the title with "Fix part of #bugnum: ...".)
- [x] Any changes to [scripts/assets](https://github.com/oppia/oppia-android/tree/develop/scripts/assets) files have their rationale included in the PR explanation.
- [x] The PR follows the [style guide](https://github.com/oppia/oppia-android/wiki/Coding-style-guide).
- [x] The PR does not contain any unnecessary code changes from Android Studio ([reference](https://github.com/oppia/oppia-android/wiki/Guidance-on-submitting-a-PR#undo-unnecessary-changes)).
- [x] The PR is made from a branch that's **not** called "develop" and is up-to-date with "develop".
- [x] The PR is **assigned** to the appropriate reviewers ([reference](https://github.com/oppia/oppia-android/wiki/Guidance-on-submitting-a-PR#clarification-regarding-assignees-and-reviewers-section)).
## For UI-specific PRs only
This PR absolutely should include screenshots & a demo video, but for the sake of optimizing time this will be done post-merge.
Commits:
* Create dedicated alpha application component.
This simplifies application component management significantly and
allows individual build flavors to have their own unique module lists.
* Add beta & GA update notices.
This also introduces dedicated beta & GA build flavors which is a
necessary prerequisite.
It also introduces an extra beta, alpha, and dev mode labels for the splash
screen (the latter 2 were extra) with 2 second minimum wait timers for
beta and alpha to ensure they are seen. A 5-second safety timer was
added to ensure the splash screen can always be passed even if something
goes wrong at the domain level (since there are now quite a few moving
pieces to determine the user's current onboarding state).
* Add build tests for the new beta & GA flavors.
* Fix broken test per earlier changes.
* Fix general broken tests & builds.
Tests broken due to changes to the app startup experience haven't yet
been fixed.
* Lint fixes.
* First part of adding tests for GA notices.
There's a bunch left to do here, this is mainly needed so that I can
transfer changes to a different machine.
* Update TransformAndroidManifestTest.kt
Correct typos.
* Fix tests & static checks.
This also removes temporary debug code and TODOs, and finishes the tests
for SplashActivity.
* Post-merge fixes.
* Test fixes.
* Fix Gradle test.
* Follow-up adjustments after self-review.
---
.github/CODEOWNERS | 4 +-
.github/workflows/build_tests.yml | 260 ++++
app/BUILD.bazel | 2 +
app/src/main/AndroidManifest.xml | 8 +
.../alpha/AlphaApplicationComponent.kt | 2 +-
.../alpha/AlphaBuildFlavorModule.kt | 12 +
.../android/app/application/alpha/BUILD.bazel | 16 +
.../AlphaKenyaApplicationComponent.kt | 3 +-
.../app/application/alphakenya/BUILD.bazel | 1 +
.../android/app/application/beta/BUILD.bazel | 30 +
.../beta/BetaApplicationComponent.kt | 110 ++
.../application/beta/BetaBuildFlavorModule.kt | 12 +
.../application/beta/BetaOppiaApplication.kt | 6 +
.../android/app/application/dev/BUILD.bazel | 6 +-
.../dev/DeveloperApplicationComponent.kt | 3 +-
.../dev/DeveloperBuildFlavorModule.kt | 12 +
.../android/app/application/ga/BUILD.bazel | 30 +
.../application/ga/GaApplicationComponent.kt | 110 ++
.../app/application/ga/GaBuildFlavorModule.kt | 12 +
.../app/application/ga/GaOppiaApplication.kt | 6 +
.../app/application/testing/BUILD.bazel | 22 +
.../testing/TestingBuildFlavorModule.kt | 15 +
.../app/fragment/FragmentComponentImpl.kt | 6 +-
...maticAppDeprecationNoticeDialogFragment.kt | 2 +-
...eprecationNoticeDialogFragmentPresenter.kt | 2 +-
.../app/notice/BetaNoticeClosedListener.kt | 11 +
.../app/notice/BetaNoticeDialogFragment.kt | 30 +
.../BetaNoticeDialogFragmentPresenter.kt | 32 +
.../DeprecationNoticeExitAppListener.kt | 2 +-
...AvailabilityUpgradeNoticeClosedListener.kt | 11 +
...AvailabilityUpgradeNoticeDialogFragment.kt | 31 +
...ityUpgradeNoticeDialogFragmentPresenter.kt | 42 +
.../android/app/notice/testing/BUILD.bazel | 34 +
.../BetaNoticeDialogFragmentTestActivity.kt | 26 +
...UpgradeNoticeDialogFragmentTestActivity.kt | 28 +
.../android/app/splash/SplashActivity.kt | 21 +-
.../app/splash/SplashActivityPresenter.kt | 196 ++-
app/src/main/res/drawable/full_oppia_logo.xml | 24 +
.../res/layout/beta_notice_dialog_content.xml | 33 +
...lability_upgrade_notice_dialog_content.xml | 33 +
app/src/main/res/layout/splash_activity.xml | 59 +-
.../main/res/values/untranslated_strings.xml | 2 +
.../AdministratorControlsActivityTest.kt | 3 +-
.../AdministratorControlsFragmentTest.kt | 3 +-
.../AppVersionActivityTest.kt | 3 +-
.../learneranalytics/BUILD.bazel | 2 +
.../ProfileAndDeviceIdActivityTest.kt | 4 +-
.../ProfileAndDeviceIdFragmentTest.kt | 4 +-
.../CompletedStoryListActivityTest.kt | 3 +-
.../LessonThumbnailImageViewTest.kt | 3 +-
.../app/customview/interaction/BUILD.bazel | 1 +
.../MathExpressionInteractionsViewTest.kt | 3 +-
.../oppia/android/app/databinding/BUILD.bazel | 7 +
.../DrawableBindingAdaptersTest.kt | 3 +-
.../ImageViewBindingAdaptersTest.kt | 3 +-
.../databinding/MarginBindingAdaptersTest.kt | 3 +-
...StateAssemblerMarginBindingAdaptersTest.kt | 3 +-
...tateAssemblerPaddingBindingAdaptersTest.kt | 3 +-
.../TextViewBindingAdaptersTest.kt | 3 +-
.../databinding/ViewBindingAdaptersTest.kt | 3 +-
.../DeveloperOptionsActivityTest.kt | 3 +-
.../DeveloperOptionsFragmentTest.kt | 3 +-
.../MarkChaptersCompletedActivityTest.kt | 3 +-
.../MarkChaptersCompletedFragmentTest.kt | 3 +-
.../MarkStoriesCompletedActivityTest.kt | 3 +-
.../MarkStoriesCompletedFragmentTest.kt | 3 +-
.../MarkTopicsCompletedActivityTest.kt | 3 +-
.../MarkTopicsCompletedFragmentTest.kt | 3 +-
.../devoptions/ViewEventLogsActivityTest.kt | 4 +-
.../devoptions/ViewEventLogsFragmentTest.kt | 3 +-
.../ForceNetworkTypeActivityTest.kt | 3 +-
.../ForceNetworkTypeFragmentTest.kt | 3 +-
.../mathexpressionparser/BUILD.bazel | 2 +
.../MathExpressionParserActivityTest.kt | 3 +-
.../MathExpressionParserFragmentTest.kt | 3 +-
.../android/app/faq/FAQListFragmentTest.kt | 3 +-
.../android/app/faq/FAQSingleActivityTest.kt | 3 +-
.../android/app/faq/FaqListActivityTest.kt | 3 +-
.../android/app/help/HelpActivityTest.kt | 3 +-
.../android/app/help/HelpFragmentTest.kt | 3 +-
.../android/app/home/HomeActivityTest.kt | 3 +-
.../app/home/RecentlyPlayedFragmentTest.kt | 3 +-
.../app/home/TopicSummaryViewModelTest.kt | 3 +-
.../android/app/home/WelcomeViewModelTest.kt | 3 +-
.../PromotedStoryListViewModelTest.kt | 3 +-
.../PromotedStoryViewModelTest.kt | 3 +-
.../mydownloads/MyDownloadsActivityTest.kt | 3 +-
.../mydownloads/MyDownloadsFragmentTest.kt | 3 +-
.../org/oppia/android/app/notice/BUILD.bazel | 81 ++
.../notice/BetaNoticeDialogFragmentTest.kt | 278 ++++
...labilityUpgradeNoticeDialogFragmentTest.kt | 285 ++++
.../app/onboarding/OnboardingActivityTest.kt | 3 +-
.../app/onboarding/OnboardingFragmentTest.kt | 3 +-
.../OngoingTopicListActivityTest.kt | 3 +-
.../app/options/AppLanguageActivityTest.kt | 3 +-
.../app/options/AppLanguageFragmentTest.kt | 3 +-
.../app/options/AudioLanguageActivityTest.kt | 3 +-
.../app/options/AudioLanguageFragmentTest.kt | 3 +-
.../app/options/OptionsActivityTest.kt | 3 +-
.../app/options/OptionsFragmentTest.kt | 3 +-
.../options/ReadingTextSizeActivityTest.kt | 3 +-
.../options/ReadingTextSizeFragmentTest.kt | 3 +-
.../android/app/parser/HtmlParserTest.kt | 3 +-
.../app/player/audio/AudioFragmentTest.kt | 3 +-
.../exploration/ExplorationActivityTest.kt | 3 +-
.../android/app/player/state/BUILD.bazel | 1 +
.../app/player/state/StateFragmentTest.kt | 3 +-
.../app/policies/PoliciesActivityTest.kt | 3 +-
.../app/policies/PoliciesFragmentTest.kt | 3 +-
.../app/profile/AddProfileActivityTest.kt | 3 +-
.../app/profile/AdminAuthActivityTest.kt | 3 +-
.../app/profile/AdminPinActivityTest.kt | 3 +-
.../app/profile/PinPasswordActivityTest.kt | 3 +-
.../app/profile/ProfileChooserFragmentTest.kt | 3 +-
.../ProfilePictureActivityTest.kt | 3 +-
.../ProfileProgressActivityTest.kt | 3 +-
.../ProfileProgressFragmentTest.kt | 3 +-
.../app/recyclerview/BindableAdapterTest.kt | 3 +-
.../resumelesson/ResumeLessonActivityTest.kt | 3 +-
.../resumelesson/ResumeLessonFragmentTest.kt | 3 +-
.../profile/ProfileEditActivityTest.kt | 3 +-
.../profile/ProfileEditFragmentTest.kt | 3 +-
.../profile/ProfileListActivityTest.kt | 3 +-
.../profile/ProfileListFragmentTest.kt | 3 +-
.../profile/ProfileRenameActivityTest.kt | 3 +-
.../profile/ProfileRenameFragmentTest.kt | 3 +-
.../profile/ProfileResetPinActivityTest.kt | 3 +-
.../profile/ProfileResetPinFragmentTest.kt | 3 +-
.../org/oppia/android/app/splash/BUILD.bazel | 53 +
.../android/app/splash/SplashActivityTest.kt | 1065 +++++++++++---
.../android/app/story/StoryActivityTest.kt | 3 +-
.../android/app/story/StoryFragmentTest.kt | 3 +-
.../app/testing/DragDropTestActivityTest.kt | 3 +-
...ImageRegionSelectionInteractionViewTest.kt | 3 +-
.../InputInteractionViewTestActivityTest.kt | 3 +-
.../NavigationDrawerActivityDebugTest.kt | 3 +-
.../NavigationDrawerActivityProdTest.kt | 3 +-
...tFontScaleConfigurationUtilActivityTest.kt | 3 +-
.../testing/TopicTestActivityForStoryTest.kt | 3 +-
.../app/thirdparty/LicenseListActivityTest.kt | 3 +-
.../app/thirdparty/LicenseListFragmentTest.kt | 3 +-
.../LicenseTextViewerActivityTest.kt | 3 +-
.../LicenseTextViewerFragmentTest.kt | 3 +-
.../ThirdPartyDependencyListActivityTest.kt | 3 +-
.../ThirdPartyDependencyListFragmentTest.kt | 3 +-
.../android/app/topic/TopicActivityTest.kt | 3 +-
.../android/app/topic/TopicFragmentTest.kt | 3 +-
.../conceptcard/ConceptCardFragmentTest.kt | 3 +-
.../app/topic/info/TopicInfoFragmentTest.kt | 3 +-
.../topic/lessons/TopicLessonsFragmentTest.kt | 3 +-
.../practice/TopicPracticeFragmentTest.kt | 3 +-
.../QuestionPlayerActivityTest.kt | 3 +-
.../revision/TopicRevisionFragmentTest.kt | 3 +-
.../revisioncard/RevisionCardActivityTest.kt | 3 +-
.../revisioncard/RevisionCardFragmentTest.kt | 3 +-
.../app/utility/RatioExtensionsTest.kt | 3 +-
.../walkthrough/WalkthroughActivityTest.kt | 3 +-
.../WalkthroughFinalFragmentTest.kt | 3 +-
.../WalkthroughTopicListFragmentTest.kt | 3 +-
.../WalkthroughWelcomeFragmentTest.kt | 3 +-
.../activity/ActivityIntentFactoriesTest.kt | 3 +-
.../oppia/android/app/activity/BUILD.bazel | 1 +
.../alpha/AlphaBuildFlavorModuleTest.kt | 81 ++
.../android/app/application/alpha/BUILD.bazel | 26 +
.../android/app/application/beta/BUILD.bazel | 26 +
.../beta/BetaBuildFlavorModuleTest.kt | 81 ++
.../android/app/application/dev/BUILD.bazel | 26 +
.../dev/DeveloperBuildFlavorModuleTest.kt | 81 ++
.../android/app/application/ga/BUILD.bazel | 26 +
.../application/ga/GaBuildFlavorModuleTest.kt | 81 ++
.../app/application/testing/BUILD.bazel | 26 +
.../testing/TestingBuildFlavorModuleTest.kt | 81 ++
.../android/app/home/HomeActivityLocalTest.kt | 3 +-
.../app/parser/FractionParsingUiErrorTest.kt | 3 +-
.../parser/ListItemLeadingMarginSpanTest.kt | 3 +-
.../app/parser/StringToRatioParserTest.kt | 3 +-
.../ExplorationActivityLocalTest.kt | 3 +-
.../player/state/StateFragmentLocalTest.kt | 3 +-
.../ProfileChooserFragmentLocalTest.kt | 3 +-
.../app/story/StoryActivityLocalTest.kt | 3 +-
.../app/testing/CompletedStoryListSpanTest.kt | 3 +-
.../oppia/android/app/testing/HomeSpanTest.kt | 3 +-
.../app/testing/OngoingTopicListSpanTest.kt | 3 +-
.../PlatformParameterIntegrationTest.kt | 3 +-
.../app/testing/ProfileChooserSpanTest.kt | 3 +-
.../testing/ProfileProgressSpanCountTest.kt | 3 +-
.../app/testing/RecentlyPlayedSpanTest.kt | 3 +-
.../app/testing/TopicRevisionSpanTest.kt | 3 +-
.../android/app/testing/activity/BUILD.bazel | 1 +
.../app/testing/activity/TestActivityTest.kt | 3 +-
.../AdministratorControlsFragmentTest.kt | 3 +-
.../testing/options/OptionsFragmentTest.kt | 3 +-
.../player/split/PlayerSplitScreenTest.kt | 3 +-
.../state/StateFragmentAccessibilityTest.kt | 3 +-
.../topic/info/TopicInfoFragmentLocalTest.kt | 3 +-
.../lessons/TopicLessonsFragmentLocalTest.kt | 3 +-
.../QuestionPlayerActivityLocalTest.kt | 3 +-
.../RevisionCardActivityLocalTest.kt | 3 +-
.../AppLanguageResourceHandlerTest.kt | 3 +-
.../AppLanguageWatcherMixinTest.kt | 3 +-
.../oppia/android/app/translation/BUILD.bazel | 2 +
.../app/utility/datetime/DateTimeUtilTest.kt | 3 +-
.../android/app/utility/math/BUILD.bazel | 1 +
.../MathExpressionAccessibilityUtilTest.kt | 3 +-
build_flavors.bzl | 30 +-
data/BUILD.bazel | 6 +
.../data/persistence/PersistentCacheStore.kt | 203 ++-
.../android/data/persistence/BUILD.bazel | 32 +
.../persistence/PersistentCacheStoreTest.kt | 1278 +++++++++++++++--
domain/BUILD.bazel | 1 +
.../ExplorationCheckpointController.kt | 7 +-
.../onboarding/AppStartupStateController.kt | 130 +-
.../LoggingIdentifierController.kt | 11 +-
.../profile/ProfileManagementController.kt | 7 +-
.../topic/PrimeTopicAssetsControllerImpl.kt | 4 +-
.../domain/topic/StoryProgressController.kt | 9 +-
.../AppStartupStateControllerTest.kt | 536 ++++++-
.../android/domain/onboarding/BUILD.bazel | 39 +
.../instrumentation/application/BUILD.bazel | 1 +
.../application/TestApplicationComponent.kt | 4 +-
model/src/main/proto/BUILD.bazel | 13 +
model/src/main/proto/onboarding.proto | 38 +
model/src/main/proto/version.proto | 32 +
.../file_content_validation_checks.textproto | 2 +
.../assets/kdoc_validity_exemptions.textproto | 2 +-
scripts/assets/test_file_exemptions.textproto | 16 +-
.../oppia/android/testing/OppiaTestRunner.kt | 2 +-
.../oppia/android/testing/junit/BUILD.bazel | 3 +
...alizeDefaultLocaleRuleCustomContextTest.kt | 3 +-
...InitializeDefaultLocaleRuleOmissionTest.kt | 3 +-
.../junit/InitializeDefaultLocaleRuleTest.kt | 3 +-
.../oppia/android/util/data/DataProvider.kt | 5 +-
.../oppia/android/util/data/DataProviders.kt | 28 +-
.../util/data/InMemoryBlockingCache.kt | 10 +-
.../logging/firebase/FirebaseEventLogger.kt | 8 +-
.../parser/image/RepositoryGlideModule.kt | 5 +-
.../util/parser/math/MathBitmapModelLoader.kt | 20 +-
.../android/util/data/DataProvidersTest.kt | 18 +-
version.bzl | 2 +
239 files changed, 5845 insertions(+), 705 deletions(-)
create mode 100644 app/src/main/java/org/oppia/android/app/application/alpha/AlphaBuildFlavorModule.kt
create mode 100644 app/src/main/java/org/oppia/android/app/application/beta/BUILD.bazel
create mode 100644 app/src/main/java/org/oppia/android/app/application/beta/BetaApplicationComponent.kt
create mode 100644 app/src/main/java/org/oppia/android/app/application/beta/BetaBuildFlavorModule.kt
create mode 100644 app/src/main/java/org/oppia/android/app/application/beta/BetaOppiaApplication.kt
create mode 100644 app/src/main/java/org/oppia/android/app/application/dev/DeveloperBuildFlavorModule.kt
create mode 100644 app/src/main/java/org/oppia/android/app/application/ga/BUILD.bazel
create mode 100644 app/src/main/java/org/oppia/android/app/application/ga/GaApplicationComponent.kt
create mode 100644 app/src/main/java/org/oppia/android/app/application/ga/GaBuildFlavorModule.kt
create mode 100644 app/src/main/java/org/oppia/android/app/application/ga/GaOppiaApplication.kt
create mode 100644 app/src/main/java/org/oppia/android/app/application/testing/BUILD.bazel
create mode 100644 app/src/main/java/org/oppia/android/app/application/testing/TestingBuildFlavorModule.kt
rename app/src/main/java/org/oppia/android/app/{deprecation => notice}/AutomaticAppDeprecationNoticeDialogFragment.kt (97%)
rename app/src/main/java/org/oppia/android/app/{deprecation => notice}/AutomaticAppDeprecationNoticeDialogFragmentPresenter.kt (96%)
create mode 100644 app/src/main/java/org/oppia/android/app/notice/BetaNoticeClosedListener.kt
create mode 100644 app/src/main/java/org/oppia/android/app/notice/BetaNoticeDialogFragment.kt
create mode 100644 app/src/main/java/org/oppia/android/app/notice/BetaNoticeDialogFragmentPresenter.kt
rename app/src/main/java/org/oppia/android/app/{deprecation => notice}/DeprecationNoticeExitAppListener.kt (82%)
create mode 100644 app/src/main/java/org/oppia/android/app/notice/GeneralAvailabilityUpgradeNoticeClosedListener.kt
create mode 100644 app/src/main/java/org/oppia/android/app/notice/GeneralAvailabilityUpgradeNoticeDialogFragment.kt
create mode 100644 app/src/main/java/org/oppia/android/app/notice/GeneralAvailabilityUpgradeNoticeDialogFragmentPresenter.kt
create mode 100644 app/src/main/java/org/oppia/android/app/notice/testing/BUILD.bazel
create mode 100644 app/src/main/java/org/oppia/android/app/notice/testing/BetaNoticeDialogFragmentTestActivity.kt
create mode 100644 app/src/main/java/org/oppia/android/app/notice/testing/GeneralAvailabilityUpgradeNoticeDialogFragmentTestActivity.kt
create mode 100644 app/src/main/res/drawable/full_oppia_logo.xml
create mode 100755 app/src/main/res/layout/beta_notice_dialog_content.xml
create mode 100755 app/src/main/res/layout/general_availability_upgrade_notice_dialog_content.xml
create mode 100644 app/src/sharedTest/java/org/oppia/android/app/notice/BUILD.bazel
create mode 100644 app/src/sharedTest/java/org/oppia/android/app/notice/BetaNoticeDialogFragmentTest.kt
create mode 100644 app/src/sharedTest/java/org/oppia/android/app/notice/GeneralAvailabilityUpgradeNoticeDialogFragmentTest.kt
create mode 100644 app/src/sharedTest/java/org/oppia/android/app/splash/BUILD.bazel
create mode 100644 app/src/test/java/org/oppia/android/app/application/alpha/AlphaBuildFlavorModuleTest.kt
create mode 100644 app/src/test/java/org/oppia/android/app/application/alpha/BUILD.bazel
create mode 100644 app/src/test/java/org/oppia/android/app/application/beta/BUILD.bazel
create mode 100644 app/src/test/java/org/oppia/android/app/application/beta/BetaBuildFlavorModuleTest.kt
create mode 100644 app/src/test/java/org/oppia/android/app/application/dev/BUILD.bazel
create mode 100644 app/src/test/java/org/oppia/android/app/application/dev/DeveloperBuildFlavorModuleTest.kt
create mode 100644 app/src/test/java/org/oppia/android/app/application/ga/BUILD.bazel
create mode 100644 app/src/test/java/org/oppia/android/app/application/ga/GaBuildFlavorModuleTest.kt
create mode 100644 app/src/test/java/org/oppia/android/app/application/testing/BUILD.bazel
create mode 100644 app/src/test/java/org/oppia/android/app/application/testing/TestingBuildFlavorModuleTest.kt
create mode 100644 data/src/test/java/org/oppia/android/data/persistence/BUILD.bazel
create mode 100644 domain/src/test/java/org/oppia/android/domain/onboarding/BUILD.bazel
create mode 100644 model/src/main/proto/version.proto
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 0c77e9bcc31..a59584e77f2 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -125,8 +125,8 @@ config/kitkat_main_dex_class_list.txt @BenHenning
# Databinding adapters.
/app/src/main/java/org/oppia/android/app/databinding/ @BenHenning
-# App deprecation functionality.
-/app/src/*/java/org/oppia/android/app/deprecation/ @BenHenning
+# App notices functionality (such as for deprecations).
+/app/src/*/java/org/oppia/android/app/notice/ @BenHenning
# Parsing functionality needed for interactions.
/app/src/*/java/org/oppia/android/app/parser/ @BenHenning
diff --git a/.github/workflows/build_tests.yml b/.github/workflows/build_tests.yml
index b95d906cbc3..fdaebd4af7b 100644
--- a/.github/workflows/build_tests.yml
+++ b/.github/workflows/build_tests.yml
@@ -476,3 +476,263 @@ jobs:
with:
name: oppia_alpha_kenya.aab
path: /home/runner/work/oppia-android/oppia-android/oppia_alpha_kenya.aab
+
+ build_oppia_beta_aab:
+ name: Build Oppia AAB (beta flavor)
+ runs-on: ${{ matrix.os }}
+ strategy:
+ matrix:
+ os: [ubuntu-18.04]
+ env:
+ ENABLE_CACHING: false
+ CACHE_DIRECTORY: ~/.bazel_cache
+ steps:
+ - uses: actions/checkout@v2
+ with:
+ fetch-depth: 0
+
+ - name: Set up JDK 9
+ uses: actions/setup-java@v1
+ with:
+ java-version: 9
+
+ - name: Set up Bazel
+ uses: abhinavsingh/setup-bazel@v3
+ with:
+ version: 4.0.0
+
+ - name: Set up build environment
+ uses: ./.github/actions/set-up-android-bazel-build-environment
+
+ # For reference on this & the later cache actions, see:
+ # https://github.com/actions/cache/issues/239#issuecomment-606950711 &
+ # https://github.com/actions/cache/issues/109#issuecomment-558771281. Note that these work
+ # with Bazel since Bazel can share the most recent cache from an unrelated build and still
+ # benefit from incremental build performance (assuming that actions/cache aggressively removes
+ # older caches due to the 5GB cache limit size & Bazel's large cache size).
+ - uses: actions/cache@v2
+ id: cache
+ with:
+ path: ${{ env.CACHE_DIRECTORY }}
+ key: ${{ runner.os }}-${{ env.CACHE_DIRECTORY }}-bazel-binary-${{ github.sha }}
+ restore-keys: |
+ ${{ runner.os }}-${{ env.CACHE_DIRECTORY }}-bazel-binary-
+ ${{ runner.os }}-${{ env.CACHE_DIRECTORY }}-bazel-tests-
+ ${{ runner.os }}-${{ env.CACHE_DIRECTORY }}-bazel-
+
+ # This check is needed to ensure that Bazel's unbounded cache growth doesn't result in a
+ # situation where the cache never updates (e.g. due to exceeding GitHub's cache size limit)
+ # thereby only ever using the last successful cache version. This solution will result in a
+ # few slower CI actions around the time cache is detected to be too large, but it should
+ # incrementally improve thereafter.
+ - name: Ensure cache size
+ env:
+ BAZEL_CACHE_DIR: ${{ env.CACHE_DIRECTORY }}
+ run: |
+ # See https://stackoverflow.com/a/27485157 for reference.
+ EXPANDED_BAZEL_CACHE_PATH="${BAZEL_CACHE_DIR/#\~/$HOME}"
+ CACHE_SIZE_MB=$(du -smc $EXPANDED_BAZEL_CACHE_PATH | grep total | cut -f1)
+ echo "Total size of Bazel cache (rounded up to MBs): $CACHE_SIZE_MB"
+ # Use a 4.5GB threshold since actions/cache compresses the results, and Bazel caches seem
+ # to only increase by a few hundred megabytes across changes for unrelated branches. This
+ # is also a reasonable upper-bound (local tests as of 2021-03-31 suggest that a full build
+ # of the codebase (e.g. //...) from scratch only requires a ~2.1GB uncompressed/~900MB
+ # compressed cache).
+ if [[ "$CACHE_SIZE_MB" -gt 4500 ]]; then
+ echo "Cache exceeds cut-off; resetting it (will result in a slow build)"
+ rm -rf $EXPANDED_BAZEL_CACHE_PATH
+ fi
+
+ - name: Configure Bazel to use a local cache
+ env:
+ BAZEL_CACHE_DIR: ${{ env.CACHE_DIRECTORY }}
+ run: |
+ EXPANDED_BAZEL_CACHE_PATH="${BAZEL_CACHE_DIR/#\~/$HOME}"
+ echo "Using $EXPANDED_BAZEL_CACHE_PATH as Bazel's cache path"
+ echo "build --disk_cache=$EXPANDED_BAZEL_CACHE_PATH" >> $HOME/.bazelrc
+ shell: bash
+
+ - name: Check Bazel environment
+ run: bazel info
+
+ # See https://git-secret.io/installation for details on installing git-secret. Note that the
+ # apt-get method isn't used since it's much slower to update & upgrade apt before installation
+ # versus just directly cloning & installing the project. Further, the specific version
+ # shouldn't matter since git-secret relies on a future-proof storage mechanism for secrets.
+ # This also uses a different directory to install git-secret to avoid requiring root access
+ # when running the git secret command.
+ - name: Install git-secret (non-fork only)
+ if: ${{ env.ENABLE_CACHING == 'true' && github.event.pull_request.head.repo.full_name == 'oppia/oppia-android' }}
+ shell: bash
+ run: |
+ cd $HOME
+ mkdir -p $HOME/gitsecret
+ git clone https://github.com/sobolevn/git-secret.git git-secret
+ cd git-secret && make build
+ PREFIX="$HOME/gitsecret" make install
+ echo "$HOME/gitsecret" >> $GITHUB_PATH
+ echo "$HOME/gitsecret/bin" >> $GITHUB_PATH
+
+ - name: Decrypt secrets (non-fork only)
+ if: ${{ env.ENABLE_CACHING == 'true' && github.event.pull_request.head.repo.full_name == 'oppia/oppia-android' }}
+ env:
+ GIT_SECRET_GPG_PRIVATE_KEY: ${{ secrets.GIT_SECRET_GPG_PRIVATE_KEY }}
+ run: |
+ cd $HOME
+ # NOTE TO DEVELOPERS: Make sure to never print this key directly to stdout!
+ echo $GIT_SECRET_GPG_PRIVATE_KEY | base64 --decode > ./git_secret_private_key.gpg
+ gpg --import ./git_secret_private_key.gpg
+ cd $GITHUB_WORKSPACE
+ git secret reveal
+
+ # Note that caching only works on non-forks.
+ - name: Build Oppia beta AAB (with caching, non-fork only)
+ if: ${{ env.ENABLE_CACHING == 'true' && github.event.pull_request.head.repo.full_name == 'oppia/oppia-android' }}
+ env:
+ BAZEL_REMOTE_CACHE_URL: ${{ secrets.BAZEL_REMOTE_CACHE_URL }}
+ run: |
+ bazel build --compilation_mode=opt --remote_http_cache=$BAZEL_REMOTE_CACHE_URL --google_credentials=./config/oppia-dev-workflow-remote-cache-credentials.json -- //:oppia_beta
+
+ - name: Build Oppia beta AAB (without caching, or on a fork)
+ if: ${{ env.ENABLE_CACHING == 'false' || github.event.pull_request.head.repo.full_name != 'oppia/oppia-android' }}
+ run: |
+ bazel build --compilation_mode=opt -- //:oppia_beta
+
+ - name: Copy Oppia beta AAB for uploading
+ run: |
+ cp $GITHUB_WORKSPACE/bazel-bin/oppia_beta.aab /home/runner/work/oppia-android/oppia-android/
+
+ - uses: actions/upload-artifact@v2
+ with:
+ name: oppia_beta.aab
+ path: /home/runner/work/oppia-android/oppia-android/oppia_beta.aab
+
+ build_oppia_ga_aab:
+ name: Build Oppia AAB (GA flavor)
+ runs-on: ${{ matrix.os }}
+ strategy:
+ matrix:
+ os: [ubuntu-18.04]
+ env:
+ ENABLE_CACHING: false
+ CACHE_DIRECTORY: ~/.bazel_cache
+ steps:
+ - uses: actions/checkout@v2
+ with:
+ fetch-depth: 0
+
+ - name: Set up JDK 9
+ uses: actions/setup-java@v1
+ with:
+ java-version: 9
+
+ - name: Set up Bazel
+ uses: abhinavsingh/setup-bazel@v3
+ with:
+ version: 4.0.0
+
+ - name: Set up build environment
+ uses: ./.github/actions/set-up-android-bazel-build-environment
+
+ # For reference on this & the later cache actions, see:
+ # https://github.com/actions/cache/issues/239#issuecomment-606950711 &
+ # https://github.com/actions/cache/issues/109#issuecomment-558771281. Note that these work
+ # with Bazel since Bazel can share the most recent cache from an unrelated build and still
+ # benefit from incremental build performance (assuming that actions/cache aggressively removes
+ # older caches due to the 5GB cache limit size & Bazel's large cache size).
+ - uses: actions/cache@v2
+ id: cache
+ with:
+ path: ${{ env.CACHE_DIRECTORY }}
+ key: ${{ runner.os }}-${{ env.CACHE_DIRECTORY }}-bazel-binary-${{ github.sha }}
+ restore-keys: |
+ ${{ runner.os }}-${{ env.CACHE_DIRECTORY }}-bazel-binary-
+ ${{ runner.os }}-${{ env.CACHE_DIRECTORY }}-bazel-tests-
+ ${{ runner.os }}-${{ env.CACHE_DIRECTORY }}-bazel-
+
+ # This check is needed to ensure that Bazel's unbounded cache growth doesn't result in a
+ # situation where the cache never updates (e.g. due to exceeding GitHub's cache size limit)
+ # thereby only ever using the last successful cache version. This solution will result in a
+ # few slower CI actions around the time cache is detected to be too large, but it should
+ # incrementally improve thereafter.
+ - name: Ensure cache size
+ env:
+ BAZEL_CACHE_DIR: ${{ env.CACHE_DIRECTORY }}
+ run: |
+ # See https://stackoverflow.com/a/27485157 for reference.
+ EXPANDED_BAZEL_CACHE_PATH="${BAZEL_CACHE_DIR/#\~/$HOME}"
+ CACHE_SIZE_MB=$(du -smc $EXPANDED_BAZEL_CACHE_PATH | grep total | cut -f1)
+ echo "Total size of Bazel cache (rounded up to MBs): $CACHE_SIZE_MB"
+ # Use a 4.5GB threshold since actions/cache compresses the results, and Bazel caches seem
+ # to only increase by a few hundred megabytes across changes for unrelated branches. This
+ # is also a reasonable upper-bound (local tests as of 2021-03-31 suggest that a full build
+ # of the codebase (e.g. //...) from scratch only requires a ~2.1GB uncompressed/~900MB
+ # compressed cache).
+ if [[ "$CACHE_SIZE_MB" -gt 4500 ]]; then
+ echo "Cache exceeds cut-off; resetting it (will result in a slow build)"
+ rm -rf $EXPANDED_BAZEL_CACHE_PATH
+ fi
+
+ - name: Configure Bazel to use a local cache
+ env:
+ BAZEL_CACHE_DIR: ${{ env.CACHE_DIRECTORY }}
+ run: |
+ EXPANDED_BAZEL_CACHE_PATH="${BAZEL_CACHE_DIR/#\~/$HOME}"
+ echo "Using $EXPANDED_BAZEL_CACHE_PATH as Bazel's cache path"
+ echo "build --disk_cache=$EXPANDED_BAZEL_CACHE_PATH" >> $HOME/.bazelrc
+ shell: bash
+
+ - name: Check Bazel environment
+ run: bazel info
+
+ # See https://git-secret.io/installation for details on installing git-secret. Note that the
+ # apt-get method isn't used since it's much slower to update & upgrade apt before installation
+ # versus just directly cloning & installing the project. Further, the specific version
+ # shouldn't matter since git-secret relies on a future-proof storage mechanism for secrets.
+ # This also uses a different directory to install git-secret to avoid requiring root access
+ # when running the git secret command.
+ - name: Install git-secret (non-fork only)
+ if: ${{ env.ENABLE_CACHING == 'true' && github.event.pull_request.head.repo.full_name == 'oppia/oppia-android' }}
+ shell: bash
+ run: |
+ cd $HOME
+ mkdir -p $HOME/gitsecret
+ git clone https://github.com/sobolevn/git-secret.git git-secret
+ cd git-secret && make build
+ PREFIX="$HOME/gitsecret" make install
+ echo "$HOME/gitsecret" >> $GITHUB_PATH
+ echo "$HOME/gitsecret/bin" >> $GITHUB_PATH
+
+ - name: Decrypt secrets (non-fork only)
+ if: ${{ env.ENABLE_CACHING == 'true' && github.event.pull_request.head.repo.full_name == 'oppia/oppia-android' }}
+ env:
+ GIT_SECRET_GPG_PRIVATE_KEY: ${{ secrets.GIT_SECRET_GPG_PRIVATE_KEY }}
+ run: |
+ cd $HOME
+ # NOTE TO DEVELOPERS: Make sure to never print this key directly to stdout!
+ echo $GIT_SECRET_GPG_PRIVATE_KEY | base64 --decode > ./git_secret_private_key.gpg
+ gpg --import ./git_secret_private_key.gpg
+ cd $GITHUB_WORKSPACE
+ git secret reveal
+
+ # Note that caching only works on non-forks.
+ - name: Build Oppia GA AAB (with caching, non-fork only)
+ if: ${{ env.ENABLE_CACHING == 'true' && github.event.pull_request.head.repo.full_name == 'oppia/oppia-android' }}
+ env:
+ BAZEL_REMOTE_CACHE_URL: ${{ secrets.BAZEL_REMOTE_CACHE_URL }}
+ run: |
+ bazel build --compilation_mode=opt --remote_http_cache=$BAZEL_REMOTE_CACHE_URL --google_credentials=./config/oppia-dev-workflow-remote-cache-credentials.json -- //:oppia_ga
+
+ - name: Build Oppia GA AAB (without caching, or on a fork)
+ if: ${{ env.ENABLE_CACHING == 'false' || github.event.pull_request.head.repo.full_name != 'oppia/oppia-android' }}
+ run: |
+ bazel build --compilation_mode=opt -- //:oppia_ga
+
+ - name: Copy Oppia GA AAB for uploading
+ run: |
+ cp $GITHUB_WORKSPACE/bazel-bin/oppia_ga.aab /home/runner/work/oppia-android/oppia-android/
+
+ - uses: actions/upload-artifact@v2
+ with:
+ name: oppia_ga.aab
+ path: /home/runner/work/oppia-android/oppia-android/oppia_ga.aab
diff --git a/app/BUILD.bazel b/app/BUILD.bazel
index 749d0b4e908..d20fc5793ea 100644
--- a/app/BUILD.bazel
+++ b/app/BUILD.bazel
@@ -575,6 +575,7 @@ android_library(
"//app/src/main/java/org/oppia/android/app/translation:app_language_resource_handler",
"//model/src/main/proto:interaction_object_java_proto_lite",
"//model/src/main/proto:thumbnail_java_proto_lite",
+ "//model/src/main/proto:version_java_proto_lite",
"//third_party:androidx_annotation_annotation",
"//third_party:androidx_constraintlayout_constraintlayout",
"//third_party:androidx_core_core",
@@ -824,6 +825,7 @@ TEST_DEPS = [
"//app/src/main/java/org/oppia/android/app/application:application_injector",
"//app/src/main/java/org/oppia/android/app/application:application_injector_provider",
"//app/src/main/java/org/oppia/android/app/application:common_application_modules",
+ "//app/src/main/java/org/oppia/android/app/application/testing:testing_build_flavor_module",
"//app/src/main/java/org/oppia/android/app/testing/activity:test_activity",
"//app/src/main/java/org/oppia/android/app/translation/testing:test_module",
"//app/src/main/java/org/oppia/android/app/utility/math:math_expression_accessibility_util",
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 186e5830ae5..233b4595399 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -85,6 +85,14 @@
android:label="@string/my_downloads_activity_title"
android:screenOrientation="portrait"
android:theme="@style/OppiaThemeWithoutActionBar" />
+
+ (R.id.beta_notice_dialog_preference_checkbox)
+ return AlertDialog.Builder(activity)
+ .setTitle(R.string.beta_notice_dialog_title)
+ .setView(contentView)
+ .setPositiveButton(R.string.beta_notice_dialog_close_button_text) { _, _ ->
+ betaNoticeClosedListener.onBetaNoticeOkayButtonClicked(preferenceCheckbox.isChecked)
+ }
+ .setCancelable(false)
+ .create()
+ .also { it.setCanceledOnTouchOutside(false) }
+ }
+}
diff --git a/app/src/main/java/org/oppia/android/app/deprecation/DeprecationNoticeExitAppListener.kt b/app/src/main/java/org/oppia/android/app/notice/DeprecationNoticeExitAppListener.kt
similarity index 82%
rename from app/src/main/java/org/oppia/android/app/deprecation/DeprecationNoticeExitAppListener.kt
rename to app/src/main/java/org/oppia/android/app/notice/DeprecationNoticeExitAppListener.kt
index 020ac27ef8e..ff3d7dd1671 100644
--- a/app/src/main/java/org/oppia/android/app/deprecation/DeprecationNoticeExitAppListener.kt
+++ b/app/src/main/java/org/oppia/android/app/notice/DeprecationNoticeExitAppListener.kt
@@ -1,4 +1,4 @@
-package org.oppia.android.app.deprecation
+package org.oppia.android.app.notice
/** Listener for when the app deprecation dialog is closed. */
interface DeprecationNoticeExitAppListener {
diff --git a/app/src/main/java/org/oppia/android/app/notice/GeneralAvailabilityUpgradeNoticeClosedListener.kt b/app/src/main/java/org/oppia/android/app/notice/GeneralAvailabilityUpgradeNoticeClosedListener.kt
new file mode 100644
index 00000000000..715b7d06e6a
--- /dev/null
+++ b/app/src/main/java/org/oppia/android/app/notice/GeneralAvailabilityUpgradeNoticeClosedListener.kt
@@ -0,0 +1,11 @@
+package org.oppia.android.app.notice
+
+/** Listener for when the general availability update dialog is closed. */
+interface GeneralAvailabilityUpgradeNoticeClosedListener {
+ /**
+ * Called when the notice dialog was closed.
+ *
+ * @param permanentlyDismiss whether the user never wants to see this notice again
+ */
+ fun onGaUpgradeNoticeOkayButtonClicked(permanentlyDismiss: Boolean)
+}
diff --git a/app/src/main/java/org/oppia/android/app/notice/GeneralAvailabilityUpgradeNoticeDialogFragment.kt b/app/src/main/java/org/oppia/android/app/notice/GeneralAvailabilityUpgradeNoticeDialogFragment.kt
new file mode 100644
index 00000000000..30ca45e7d1c
--- /dev/null
+++ b/app/src/main/java/org/oppia/android/app/notice/GeneralAvailabilityUpgradeNoticeDialogFragment.kt
@@ -0,0 +1,31 @@
+package org.oppia.android.app.notice
+
+import android.app.Dialog
+import android.content.Context
+import android.os.Bundle
+import org.oppia.android.app.fragment.FragmentComponentImpl
+import org.oppia.android.app.fragment.InjectableDialogFragment
+import javax.inject.Inject
+
+/**
+ * Dialog fragment to be shown when the user may be unaware that they've updated from a pre-release
+ * version of the app to general availability.
+ */
+class GeneralAvailabilityUpgradeNoticeDialogFragment : InjectableDialogFragment() {
+ companion object {
+ /** Returns a new instance of [GeneralAvailabilityUpgradeNoticeDialogFragment]. */
+ fun newInstance(): GeneralAvailabilityUpgradeNoticeDialogFragment =
+ GeneralAvailabilityUpgradeNoticeDialogFragment()
+ }
+
+ @Inject lateinit var presenter: GeneralAvailabilityUpgradeNoticeDialogFragmentPresenter
+
+ override fun onAttach(context: Context) {
+ super.onAttach(context)
+ (fragmentComponent as FragmentComponentImpl).inject(this)
+ }
+
+ override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
+ return presenter.handleOnCreateDialog()
+ }
+}
diff --git a/app/src/main/java/org/oppia/android/app/notice/GeneralAvailabilityUpgradeNoticeDialogFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/notice/GeneralAvailabilityUpgradeNoticeDialogFragmentPresenter.kt
new file mode 100644
index 00000000000..74cdca94c9d
--- /dev/null
+++ b/app/src/main/java/org/oppia/android/app/notice/GeneralAvailabilityUpgradeNoticeDialogFragmentPresenter.kt
@@ -0,0 +1,42 @@
+package org.oppia.android.app.notice
+
+import android.app.Dialog
+import android.view.View
+import android.widget.CheckBox
+import androidx.appcompat.app.AlertDialog
+import androidx.appcompat.app.AppCompatActivity
+import org.oppia.android.R
+import javax.inject.Inject
+
+/**
+ * Presenter for the dialog that shows when the user has updated to the general availability version
+ * app is being used.
+ */
+class GeneralAvailabilityUpgradeNoticeDialogFragmentPresenter @Inject constructor(
+ private val activity: AppCompatActivity
+) {
+ private val gaUpgradeNoticeClosedListener by lazy {
+ activity as GeneralAvailabilityUpgradeNoticeClosedListener
+ }
+
+ /** Handles dialog creation for the general availability update notice. */
+ fun handleOnCreateDialog(): Dialog {
+ val contentView =
+ View.inflate(
+ activity, R.layout.general_availability_upgrade_notice_dialog_content, /* root= */ null
+ )
+ val preferenceCheckbox =
+ contentView.findViewById(R.id.ga_update_notice_dialog_preference_checkbox)
+ return AlertDialog.Builder(activity)
+ .setTitle(R.string.general_availability_notice_dialog_title)
+ .setView(contentView)
+ .setPositiveButton(R.string.general_availability_notice_dialog_close_button_text) { _, _ ->
+ gaUpgradeNoticeClosedListener.onGaUpgradeNoticeOkayButtonClicked(
+ preferenceCheckbox.isChecked
+ )
+ }
+ .setCancelable(false)
+ .create()
+ .also { it.setCanceledOnTouchOutside(false) }
+ }
+}
diff --git a/app/src/main/java/org/oppia/android/app/notice/testing/BUILD.bazel b/app/src/main/java/org/oppia/android/app/notice/testing/BUILD.bazel
new file mode 100644
index 00000000000..92f1a0ae62b
--- /dev/null
+++ b/app/src/main/java/org/oppia/android/app/notice/testing/BUILD.bazel
@@ -0,0 +1,34 @@
+"""
+Test-only utilities corresponding to app notices.
+"""
+
+load("@dagger//:workspace_defs.bzl", "dagger_rules")
+load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_android_library")
+
+kt_android_library(
+ name = "beta_notice_dialog_frgment_test_activity",
+ testonly = True,
+ srcs = [
+ "BetaNoticeDialogFragmentTestActivity.kt",
+ ],
+ visibility = ["//app:app_testing_visibility"],
+ deps = [
+ "//app",
+ "//app/src/main/java/org/oppia/android/app/testing/activity:test_activity",
+ ],
+)
+
+kt_android_library(
+ name = "general_availability_upgrade_notice_dialog_fragment_test_activity",
+ testonly = True,
+ srcs = [
+ "GeneralAvailabilityUpgradeNoticeDialogFragmentTestActivity.kt",
+ ],
+ visibility = ["//app:app_testing_visibility"],
+ deps = [
+ "//app",
+ "//app/src/main/java/org/oppia/android/app/testing/activity:test_activity",
+ ],
+)
+
+dagger_rules()
diff --git a/app/src/main/java/org/oppia/android/app/notice/testing/BetaNoticeDialogFragmentTestActivity.kt b/app/src/main/java/org/oppia/android/app/notice/testing/BetaNoticeDialogFragmentTestActivity.kt
new file mode 100644
index 00000000000..7d0e612bb26
--- /dev/null
+++ b/app/src/main/java/org/oppia/android/app/notice/testing/BetaNoticeDialogFragmentTestActivity.kt
@@ -0,0 +1,26 @@
+package org.oppia.android.app.notice.testing
+
+import android.os.Bundle
+import org.oppia.android.app.notice.BetaNoticeClosedListener
+import org.oppia.android.app.notice.BetaNoticeDialogFragment
+import org.oppia.android.app.testing.activity.TestActivity
+
+/** [TestActivity] for setting up a test environment for testing the beta notice dialog. */
+class BetaNoticeDialogFragmentTestActivity : TestActivity(), BetaNoticeClosedListener {
+ /**
+ * [BetaNoticeClosedListener] that must be initialized by the test, and is presumed to be a
+ * Mockito mock (though this is not, strictly speaking, required).
+ *
+ * This listener will be used as the callback for the dialog in response to UI operations.
+ */
+ lateinit var mockCallbackListener: BetaNoticeClosedListener
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ BetaNoticeDialogFragment.newInstance().showNow(supportFragmentManager, "beta_notice_dialog")
+ }
+
+ override fun onBetaNoticeOkayButtonClicked(permanentlyDismiss: Boolean) {
+ mockCallbackListener.onBetaNoticeOkayButtonClicked(permanentlyDismiss)
+ }
+}
diff --git a/app/src/main/java/org/oppia/android/app/notice/testing/GeneralAvailabilityUpgradeNoticeDialogFragmentTestActivity.kt b/app/src/main/java/org/oppia/android/app/notice/testing/GeneralAvailabilityUpgradeNoticeDialogFragmentTestActivity.kt
new file mode 100644
index 00000000000..b378a876e41
--- /dev/null
+++ b/app/src/main/java/org/oppia/android/app/notice/testing/GeneralAvailabilityUpgradeNoticeDialogFragmentTestActivity.kt
@@ -0,0 +1,28 @@
+package org.oppia.android.app.notice.testing
+
+import android.os.Bundle
+import org.oppia.android.app.notice.GeneralAvailabilityUpgradeNoticeClosedListener
+import org.oppia.android.app.notice.GeneralAvailabilityUpgradeNoticeDialogFragment
+import org.oppia.android.app.testing.activity.TestActivity
+
+/** [TestActivity] for setting up a test environment for testing the GA upgrade notice dialog. */
+class GeneralAvailabilityUpgradeNoticeDialogFragmentTestActivity :
+ TestActivity(), GeneralAvailabilityUpgradeNoticeClosedListener {
+ /**
+ * [GeneralAvailabilityUpgradeNoticeClosedListener] that must be initialized by the test, and is
+ * presumed to be a Mockito mock (though this is not, strictly speaking, required).
+ *
+ * This listener will be used as the callback for the dialog in response to UI operations.
+ */
+ lateinit var mockCallbackListener: GeneralAvailabilityUpgradeNoticeClosedListener
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ GeneralAvailabilityUpgradeNoticeDialogFragment.newInstance()
+ .showNow(supportFragmentManager, "ga_upgrade_notice_dialog")
+ }
+
+ override fun onGaUpgradeNoticeOkayButtonClicked(permanentlyDismiss: Boolean) {
+ mockCallbackListener.onGaUpgradeNoticeOkayButtonClicked(permanentlyDismiss)
+ }
+}
diff --git a/app/src/main/java/org/oppia/android/app/splash/SplashActivity.kt b/app/src/main/java/org/oppia/android/app/splash/SplashActivity.kt
index 83859936edf..e0840ebdf83 100644
--- a/app/src/main/java/org/oppia/android/app/splash/SplashActivity.kt
+++ b/app/src/main/java/org/oppia/android/app/splash/SplashActivity.kt
@@ -6,10 +6,12 @@ import androidx.fragment.app.Fragment
import org.oppia.android.app.activity.ActivityComponent
import org.oppia.android.app.activity.ActivityComponentFactory
import org.oppia.android.app.activity.ActivityComponentImpl
-import org.oppia.android.app.deprecation.DeprecationNoticeExitAppListener
import org.oppia.android.app.fragment.FragmentComponent
import org.oppia.android.app.fragment.FragmentComponentBuilderInjector
import org.oppia.android.app.fragment.FragmentComponentFactory
+import org.oppia.android.app.notice.BetaNoticeClosedListener
+import org.oppia.android.app.notice.DeprecationNoticeExitAppListener
+import org.oppia.android.app.notice.GeneralAvailabilityUpgradeNoticeClosedListener
import javax.inject.Inject
/**
@@ -21,7 +23,12 @@ import javax.inject.Inject
* through their intents).
*/
class SplashActivity :
- AppCompatActivity(), FragmentComponentFactory, DeprecationNoticeExitAppListener {
+ AppCompatActivity(),
+ FragmentComponentFactory,
+ DeprecationNoticeExitAppListener,
+ BetaNoticeClosedListener,
+ GeneralAvailabilityUpgradeNoticeClosedListener {
+
private lateinit var activityComponent: ActivityComponent
@Inject
@@ -35,10 +42,16 @@ class SplashActivity :
splashActivityPresenter.handleOnCreate()
}
- override fun onCloseAppButtonClicked() = splashActivityPresenter.handleOnCloseAppButtonClicked()
-
override fun createFragmentComponent(fragment: Fragment): FragmentComponent {
val builderInjector = activityComponent as FragmentComponentBuilderInjector
return builderInjector.getFragmentComponentBuilderProvider().get().setFragment(fragment).build()
}
+
+ override fun onCloseAppButtonClicked() = splashActivityPresenter.handleOnCloseAppButtonClicked()
+
+ override fun onBetaNoticeOkayButtonClicked(permanentlyDismiss: Boolean) =
+ splashActivityPresenter.handleOnBetaNoticeOkayButtonClicked(permanentlyDismiss)
+
+ override fun onGaUpgradeNoticeOkayButtonClicked(permanentlyDismiss: Boolean) =
+ splashActivityPresenter.handleOnGaUpgradeNoticeOkayButtonClicked(permanentlyDismiss)
}
diff --git a/app/src/main/java/org/oppia/android/app/splash/SplashActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/splash/SplashActivityPresenter.kt
index fd02c1ea32b..5cbbc7df08c 100644
--- a/app/src/main/java/org/oppia/android/app/splash/SplashActivityPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/splash/SplashActivityPresenter.kt
@@ -1,18 +1,23 @@
package org.oppia.android.app.splash
-import android.view.WindowManager
import androidx.appcompat.app.AppCompatActivity
-import androidx.lifecycle.LiveData
+import androidx.databinding.DataBindingUtil
+import androidx.fragment.app.DialogFragment
import androidx.lifecycle.Observer
-import androidx.lifecycle.Transformations
import org.oppia.android.R
import org.oppia.android.app.activity.ActivityScope
-import org.oppia.android.app.deprecation.AutomaticAppDeprecationNoticeDialogFragment
import org.oppia.android.app.model.AppStartupState
+import org.oppia.android.app.model.AppStartupState.BuildFlavorNoticeMode
import org.oppia.android.app.model.AppStartupState.StartupMode
+import org.oppia.android.app.model.BuildFlavor
+import org.oppia.android.app.notice.AutomaticAppDeprecationNoticeDialogFragment
+import org.oppia.android.app.notice.BetaNoticeDialogFragment
+import org.oppia.android.app.notice.GeneralAvailabilityUpgradeNoticeDialogFragment
import org.oppia.android.app.onboarding.OnboardingActivity
import org.oppia.android.app.profile.ProfileChooserActivity
import org.oppia.android.app.translation.AppLanguageLocaleHandler
+import org.oppia.android.app.utility.LifecycleSafeTimerFactory
+import org.oppia.android.databinding.SplashActivityBinding
import org.oppia.android.domain.locale.LocaleController
import org.oppia.android.domain.onboarding.AppStartupStateController
import org.oppia.android.domain.oppialogger.OppiaLogger
@@ -26,6 +31,8 @@ import org.oppia.android.util.locale.OppiaLocale
import javax.inject.Inject
private const val AUTO_DEPRECATION_NOTICE_DIALOG_FRAGMENT_TAG = "auto_deprecation_notice_dialog"
+private const val BETA_NOTICE_DIALOG_FRAGMENT_TAG = "beta_notice_dialog"
+private const val GA_UPDATE_NOTICE_DIALOG_FRAGMENT_TAG = "general_availability_update_notice_dialog"
private const val SPLASH_INIT_STATE_DATA_PROVIDER_ID = "splash_init_state_data_provider"
/** The presenter for [SplashActivity]. */
@@ -37,15 +44,21 @@ class SplashActivityPresenter @Inject constructor(
private val primeTopicAssetsController: PrimeTopicAssetsController,
private val translationController: TranslationController,
private val localeController: LocaleController,
- private val appLanguageLocaleHandler: AppLanguageLocaleHandler
+ private val appLanguageLocaleHandler: AppLanguageLocaleHandler,
+ private val lifecycleSafeTimerFactory: LifecycleSafeTimerFactory,
+ private val currentBuildFlavor: BuildFlavor
) {
+ lateinit var startupMode: StartupMode
fun handleOnCreate() {
- activity.setContentView(R.layout.splash_activity)
- activity.window.setFlags(
- WindowManager.LayoutParams.FLAG_FULLSCREEN,
- WindowManager.LayoutParams.FLAG_FULLSCREEN
- )
+ DataBindingUtil.setContentView(
+ activity, R.layout.splash_activity
+ ).apply {
+ isOnDeveloperFlavor = currentBuildFlavor == BuildFlavor.DEVELOPER
+ isOnAlphaFlavor = currentBuildFlavor == BuildFlavor.ALPHA
+ isOnBetaFlavor = currentBuildFlavor == BuildFlavor.BETA
+ }
+
// Initiate download support before any additional processing begins.
primeTopicAssetsController.downloadAssets(R.style.OppiaAlertDialogTheme)
subscribeToOnboardingFlow()
@@ -57,44 +70,49 @@ class SplashActivityPresenter @Inject constructor(
activity.finish()
}
+ /** Handles cases when the user dismisses the beta notice dialog. */
+ fun handleOnBetaNoticeOkayButtonClicked(permanentlyDismiss: Boolean) {
+ if (permanentlyDismiss) {
+ appStartupStateController.dismissBetaNoticesPermanently()
+ }
+ processStartupMode()
+ }
+
+ /** Handles cases when the user dismisses the general availability update notice dialog. */
+ fun handleOnGaUpgradeNoticeOkayButtonClicked(permanentlyDismiss: Boolean) {
+ if (permanentlyDismiss) {
+ appStartupStateController.dismissGaUpgradeNoticesPermanently()
+ }
+ processStartupMode()
+ }
+
private fun subscribeToOnboardingFlow() {
- val liveData = computeInitStateLiveData()
+ val liveData = computeInitStateDataProvider().toLiveData()
liveData.observe(
activity,
- object : Observer {
- override fun onChanged(initState: SplashInitState) {
- // It's possible for the observer to still be active & change due to the next activity
- // causing a notification to be posted. That's always invalid to process here: the splash
- // activity should never do anything after its initial state since it always finishes (or
- // in the case of the deprecation dialog, blocks) the activity.
- liveData.removeObserver(this)
-
- // First, initialize the app's initial locale. Note that since the activity can be
- // reopened, it's possible for this to be initialized more than once.
- if (!appLanguageLocaleHandler.isInitialized()) {
- appLanguageLocaleHandler.initializeLocale(initState.displayLocale)
- }
-
- // Second, route the user to the correct destination.
- when (initState.startupMode) {
- StartupMode.USER_IS_ONBOARDED -> {
- activity.startActivity(ProfileChooserActivity.createProfileChooserActivity(activity))
- activity.finish()
- }
- StartupMode.APP_IS_DEPRECATED -> {
- if (getDeprecationNoticeDialogFragment() == null) {
- activity.supportFragmentManager.beginTransaction()
- .add(
- AutomaticAppDeprecationNoticeDialogFragment.newInstance(),
- AUTO_DEPRECATION_NOTICE_DIALOG_FRAGMENT_TAG
- ).commitNow()
+ object : Observer> {
+ override fun onChanged(initStateResult: AsyncResult) {
+ when (initStateResult) {
+ is AsyncResult.Pending -> {
+ // Ensure that pending states last no longer than 5 seconds. In cases where the app
+ // enters a bad state, this ensures that the user doesn't become stuck on the splash
+ // screen.
+ lifecycleSafeTimerFactory.createTimer(timeoutMillis = 5000).observe(activity) {
+ processInitState(SplashInitState.computeDefault(localeController))
}
}
- else -> {
- // In all other cases (including errors when the startup state fails to load or is
- // defaulted), assume the user needs to be onboarded.
- activity.startActivity(OnboardingActivity.createOnboardingActivity(activity))
- activity.finish()
+ is AsyncResult.Failure -> {
+ oppiaLogger.e(
+ "SplashActivity", "Failed to compute initial state", initStateResult.error
+ )
+ }
+ is AsyncResult.Success -> {
+ // It's possible for the observer to still be active & change due to the next activity
+ // causing a notification to be posted. That's always invalid to process here: the
+ // splash activity should never do anything after its initial state since it always
+ // finishes (or in the case of the deprecation dialog, blocks) the activity.
+ liveData.removeObserver(this)
+ processInitState(initStateResult.value)
}
}
}
@@ -102,47 +120,93 @@ class SplashActivityPresenter @Inject constructor(
)
}
+ private fun processInitState(initState: SplashInitState) {
+ // First, initialize the app's initial locale. Note that since the activity can be
+ // reopened, it's possible for this to be initialized more than once.
+ if (!appLanguageLocaleHandler.isInitialized()) {
+ appLanguageLocaleHandler.initializeLocale(initState.displayLocale)
+ }
+
+ // Second, prepare to route the user to the correct destination.
+ startupMode = initState.appStartupState.startupMode
+
+ // Third, show any dismissible notices (if the app isn't deprecated).
+ if (startupMode != StartupMode.APP_IS_DEPRECATED) {
+ when (initState.appStartupState.buildFlavorNoticeMode) {
+ BuildFlavorNoticeMode.FLAVOR_NOTICE_MODE_UNSPECIFIED, BuildFlavorNoticeMode.NO_NOTICE,
+ BuildFlavorNoticeMode.UNRECOGNIZED, null -> {
+ // No notice should be shown. However, when a pre-release version of the app is active
+ // that changes the splash screen have it wait a bit longer so that the build flavor can
+ // be clearly seen. The developer build isn't part of the wait to ensure fast startup
+ // times (for development purposes).
+ when (currentBuildFlavor) {
+ BuildFlavor.BUILD_FLAVOR_UNSPECIFIED, BuildFlavor.UNRECOGNIZED,
+ BuildFlavor.TESTING, BuildFlavor.DEVELOPER, BuildFlavor.GENERAL_AVAILABILITY ->
+ processStartupMode()
+ BuildFlavor.ALPHA, BuildFlavor.BETA -> {
+ lifecycleSafeTimerFactory.createTimer(timeoutMillis = 2000).observe(activity) {
+ processStartupMode()
+ }
+ }
+ }
+ }
+ BuildFlavorNoticeMode.SHOW_BETA_NOTICE ->
+ showDialog(BETA_NOTICE_DIALOG_FRAGMENT_TAG, BetaNoticeDialogFragment::newInstance)
+ BuildFlavorNoticeMode.SHOW_UPGRADE_TO_GENERAL_AVAILABILITY_NOTICE -> {
+ showDialog(
+ GA_UPDATE_NOTICE_DIALOG_FRAGMENT_TAG,
+ GeneralAvailabilityUpgradeNoticeDialogFragment::newInstance
+ )
+ }
+ }
+ } else processStartupMode()
+ }
+
+ private fun processStartupMode() {
+ when (startupMode) {
+ StartupMode.USER_IS_ONBOARDED -> {
+ activity.startActivity(ProfileChooserActivity.createProfileChooserActivity(activity))
+ activity.finish()
+ }
+ StartupMode.APP_IS_DEPRECATED -> {
+ showDialog(
+ AUTO_DEPRECATION_NOTICE_DIALOG_FRAGMENT_TAG,
+ AutomaticAppDeprecationNoticeDialogFragment::newInstance
+ )
+ }
+ else -> {
+ // In all other cases (including errors when the startup state fails to load or is
+ // defaulted), assume the user needs to be onboarded.
+ activity.startActivity(OnboardingActivity.createOnboardingActivity(activity))
+ activity.finish()
+ }
+ }
+ }
+
private fun computeInitStateDataProvider(): DataProvider {
val startupStateDataProvider = appStartupStateController.getAppStartupState()
val systemAppLanguageLocaleDataProvider = translationController.getSystemLanguageLocale()
return startupStateDataProvider.combineWith(
systemAppLanguageLocaleDataProvider, SPLASH_INIT_STATE_DATA_PROVIDER_ID
) { startupState, systemAppLanguageLocale ->
- SplashInitState(startupState.startupMode, systemAppLanguageLocale)
+ SplashInitState(startupState, systemAppLanguageLocale)
}
}
- private fun computeInitStateLiveData(): LiveData =
- Transformations.map(computeInitStateDataProvider().toLiveData(), ::processInitState)
-
- private fun processInitState(
- initStateResult: AsyncResult
- ): SplashInitState {
- // If there's an error loading the data, assume the default.
- return when (initStateResult) {
- is AsyncResult.Failure -> {
- oppiaLogger.e("SplashActivity", "Failed to compute initial state", initStateResult.error)
- SplashInitState.computeDefault(localeController)
- }
- is AsyncResult.Pending -> SplashInitState.computeDefault(localeController)
- is AsyncResult.Success -> initStateResult.value
+ private inline fun showDialog(tag: String, createFragment: () -> T) {
+ if (activity.supportFragmentManager.findFragmentByTag(tag) as? T == null) {
+ activity.supportFragmentManager.beginTransaction().add(createFragment(), tag).commitNow()
}
}
- private fun getDeprecationNoticeDialogFragment(): AutomaticAppDeprecationNoticeDialogFragment? {
- return activity.supportFragmentManager.findFragmentByTag(
- AUTO_DEPRECATION_NOTICE_DIALOG_FRAGMENT_TAG
- ) as? AutomaticAppDeprecationNoticeDialogFragment
- }
-
private data class SplashInitState(
- val startupMode: StartupMode,
+ val appStartupState: AppStartupState,
val displayLocale: OppiaLocale.DisplayLocale
) {
companion object {
fun computeDefault(localeController: LocaleController): SplashInitState {
return SplashInitState(
- startupMode = AppStartupState.getDefaultInstance().startupMode,
+ appStartupState = AppStartupState.getDefaultInstance(),
displayLocale = localeController.reconstituteDisplayLocale(
localeController.getLikelyDefaultAppStringLocaleContext()
)
diff --git a/app/src/main/res/drawable/full_oppia_logo.xml b/app/src/main/res/drawable/full_oppia_logo.xml
new file mode 100644
index 00000000000..f99bc2df503
--- /dev/null
+++ b/app/src/main/res/drawable/full_oppia_logo.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/beta_notice_dialog_content.xml b/app/src/main/res/layout/beta_notice_dialog_content.xml
new file mode 100755
index 00000000000..b456257a2b6
--- /dev/null
+++ b/app/src/main/res/layout/beta_notice_dialog_content.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
diff --git a/app/src/main/res/layout/general_availability_upgrade_notice_dialog_content.xml b/app/src/main/res/layout/general_availability_upgrade_notice_dialog_content.xml
new file mode 100755
index 00000000000..f7ecc971fd7
--- /dev/null
+++ b/app/src/main/res/layout/general_availability_upgrade_notice_dialog_content.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
diff --git a/app/src/main/res/layout/splash_activity.xml b/app/src/main/res/layout/splash_activity.xml
index c6a3978120e..f8d6bb317d5 100644
--- a/app/src/main/res/layout/splash_activity.xml
+++ b/app/src/main/res/layout/splash_activity.xml
@@ -1,7 +1,54 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/values/untranslated_strings.xml b/app/src/main/res/values/untranslated_strings.xml
index a0482e4ba72..ca0ce552a2c 100644
--- a/app/src/main/res/values/untranslated_strings.xml
+++ b/app/src/main/res/values/untranslated_strings.xml
@@ -79,4 +79,6 @@
Please connect to a WiFi or Cellular network in order to upload profile data.%s installation ID%s\'s learner ID
+
+ Test-only activity
diff --git a/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/AdministratorControlsActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/AdministratorControlsActivityTest.kt
index 5918ad0614f..80fbbbbf0ec 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/AdministratorControlsActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/AdministratorControlsActivityTest.kt
@@ -56,6 +56,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -835,7 +836,7 @@ class AdministratorControlsActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/AdministratorControlsFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/AdministratorControlsFragmentTest.kt
index ae58e53a313..95ee91fd9ef 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/AdministratorControlsFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/AdministratorControlsFragmentTest.kt
@@ -47,6 +47,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -613,7 +614,7 @@ class AdministratorControlsFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/AppVersionActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/AppVersionActivityTest.kt
index 4d3875e7a30..ea6982c549f 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/AppVersionActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/AppVersionActivityTest.kt
@@ -37,6 +37,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -291,7 +292,7 @@ class AppVersionActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/learneranalytics/BUILD.bazel b/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/learneranalytics/BUILD.bazel
index 32688f31e7b..b64b7f60e82 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/learneranalytics/BUILD.bazel
+++ b/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/learneranalytics/BUILD.bazel
@@ -14,6 +14,7 @@ app_test(
"//app/src/main/java/org/oppia/android/app/application:application_injector",
"//app/src/main/java/org/oppia/android/app/application:application_injector_provider",
"//app/src/main/java/org/oppia/android/app/application:common_application_modules",
+ "//app/src/main/java/org/oppia/android/app/application/testing:testing_build_flavor_module",
"//app/src/main/java/org/oppia/android/app/translation/testing:test_module",
"//testing",
"//testing/src/main/java/org/oppia/android/testing/junit:initialize_default_locale_rule",
@@ -45,6 +46,7 @@ app_test(
"//app/src/main/java/org/oppia/android/app/application:application_injector",
"//app/src/main/java/org/oppia/android/app/application:application_injector_provider",
"//app/src/main/java/org/oppia/android/app/application:common_application_modules",
+ "//app/src/main/java/org/oppia/android/app/application/testing:testing_build_flavor_module",
"//app/src/main/java/org/oppia/android/app/translation/testing:test_module",
"//testing",
"//testing/src/main/java/org/oppia/android/testing/junit:initialize_default_locale_rule",
diff --git a/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/learneranalytics/ProfileAndDeviceIdActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/learneranalytics/ProfileAndDeviceIdActivityTest.kt
index e0b44a0a5fa..37fbe33d836 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/learneranalytics/ProfileAndDeviceIdActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/learneranalytics/ProfileAndDeviceIdActivityTest.kt
@@ -28,6 +28,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -199,7 +200,8 @@ class ProfileAndDeviceIdActivityTest {
AssetModule::class, LocaleProdModule::class, ActivityRecreatorTestModule::class,
SyncStatusModule::class, SplitScreenInteractionModule::class,
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
- MathEquationInputModule::class, MetricLogSchedulerModule::class
+ MathEquationInputModule::class, MetricLogSchedulerModule::class,
+ TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/learneranalytics/ProfileAndDeviceIdFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/learneranalytics/ProfileAndDeviceIdFragmentTest.kt
index 1c99c20e542..4f5b16a23e1 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/learneranalytics/ProfileAndDeviceIdFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/learneranalytics/ProfileAndDeviceIdFragmentTest.kt
@@ -42,6 +42,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -625,7 +626,8 @@ class ProfileAndDeviceIdFragmentTest {
AssetModule::class, LocaleProdModule::class, ActivityRecreatorTestModule::class,
SyncStatusModule::class, SplitScreenInteractionModule::class,
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
- MathEquationInputModule::class, MetricLogSchedulerModule::class
+ MathEquationInputModule::class, MetricLogSchedulerModule::class,
+ TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/completedstorylist/CompletedStoryListActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/completedstorylist/CompletedStoryListActivityTest.kt
index dc1c7fd5a82..f50c687c987 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/completedstorylist/CompletedStoryListActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/completedstorylist/CompletedStoryListActivityTest.kt
@@ -37,6 +37,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.model.ProfileId
@@ -514,7 +515,7 @@ class CompletedStoryListActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/customview/LessonThumbnailImageViewTest.kt b/app/src/sharedTest/java/org/oppia/android/app/customview/LessonThumbnailImageViewTest.kt
index e9fd803c1e3..c4082c8733a 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/customview/LessonThumbnailImageViewTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/customview/LessonThumbnailImageViewTest.kt
@@ -21,6 +21,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.model.LessonThumbnail
@@ -172,7 +173,7 @@ class LessonThumbnailImageViewTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/customview/interaction/BUILD.bazel b/app/src/sharedTest/java/org/oppia/android/app/customview/interaction/BUILD.bazel
index d7571e7f1ac..37a21163500 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/customview/interaction/BUILD.bazel
+++ b/app/src/sharedTest/java/org/oppia/android/app/customview/interaction/BUILD.bazel
@@ -17,6 +17,7 @@ app_test(
"//app/src/main/java/org/oppia/android/app/application:application_injector",
"//app/src/main/java/org/oppia/android/app/application:application_injector_provider",
"//app/src/main/java/org/oppia/android/app/application:common_application_modules",
+ "//app/src/main/java/org/oppia/android/app/application/testing:testing_build_flavor_module",
"//app/src/main/java/org/oppia/android/app/translation/testing:test_module",
"//testing",
"//testing/src/main/java/org/oppia/android/testing/espresso:edit_text_input_action",
diff --git a/app/src/sharedTest/java/org/oppia/android/app/customview/interaction/MathExpressionInteractionsViewTest.kt b/app/src/sharedTest/java/org/oppia/android/app/customview/interaction/MathExpressionInteractionsViewTest.kt
index 100c5a437f8..f5a54d6e7d1 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/customview/interaction/MathExpressionInteractionsViewTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/customview/interaction/MathExpressionInteractionsViewTest.kt
@@ -26,6 +26,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.model.CustomSchemaValue
@@ -1774,7 +1775,7 @@ class MathExpressionInteractionsViewTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/databinding/BUILD.bazel b/app/src/sharedTest/java/org/oppia/android/app/databinding/BUILD.bazel
index e6c820172aa..019f1ff1983 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/databinding/BUILD.bazel
+++ b/app/src/sharedTest/java/org/oppia/android/app/databinding/BUILD.bazel
@@ -77,6 +77,7 @@ oppia_android_test(
"//app/src/main/java/org/oppia/android/app/application:application_injector",
"//app/src/main/java/org/oppia/android/app/application:application_injector_provider",
"//app/src/main/java/org/oppia/android/app/application:common_application_modules",
+ "//app/src/main/java/org/oppia/android/app/application/testing:testing_build_flavor_module",
"//app/src/main/java/org/oppia/android/app/translation/testing:test_module",
"//domain",
"//testing",
@@ -113,6 +114,7 @@ oppia_android_test(
"//app/src/main/java/org/oppia/android/app/application:application_injector",
"//app/src/main/java/org/oppia/android/app/application:application_injector_provider",
"//app/src/main/java/org/oppia/android/app/application:common_application_modules",
+ "//app/src/main/java/org/oppia/android/app/application/testing:testing_build_flavor_module",
"//app/src/main/java/org/oppia/android/app/translation/testing:test_module",
"//domain",
"//testing",
@@ -149,6 +151,7 @@ oppia_android_test(
"//app/src/main/java/org/oppia/android/app/application:application_injector",
"//app/src/main/java/org/oppia/android/app/application:application_injector_provider",
"//app/src/main/java/org/oppia/android/app/application:common_application_modules",
+ "//app/src/main/java/org/oppia/android/app/application/testing:testing_build_flavor_module",
"//app/src/main/java/org/oppia/android/app/translation/testing:test_module",
"//domain",
"//testing",
@@ -185,6 +188,7 @@ oppia_android_test(
"//app/src/main/java/org/oppia/android/app/application:application_injector",
"//app/src/main/java/org/oppia/android/app/application:application_injector_provider",
"//app/src/main/java/org/oppia/android/app/application:common_application_modules",
+ "//app/src/main/java/org/oppia/android/app/application/testing:testing_build_flavor_module",
"//app/src/main/java/org/oppia/android/app/translation/testing:test_module",
"//domain",
"//testing",
@@ -221,6 +225,7 @@ oppia_android_test(
"//app/src/main/java/org/oppia/android/app/application:application_injector",
"//app/src/main/java/org/oppia/android/app/application:application_injector_provider",
"//app/src/main/java/org/oppia/android/app/application:common_application_modules",
+ "//app/src/main/java/org/oppia/android/app/application/testing:testing_build_flavor_module",
"//app/src/main/java/org/oppia/android/app/translation/testing:test_module",
"//domain",
"//testing",
@@ -257,6 +262,7 @@ oppia_android_test(
"//app/src/main/java/org/oppia/android/app/application:application_injector",
"//app/src/main/java/org/oppia/android/app/application:application_injector_provider",
"//app/src/main/java/org/oppia/android/app/application:common_application_modules",
+ "//app/src/main/java/org/oppia/android/app/application/testing:testing_build_flavor_module",
"//app/src/main/java/org/oppia/android/app/translation/testing:test_module",
"//domain",
"//testing",
@@ -293,6 +299,7 @@ oppia_android_test(
"//app/src/main/java/org/oppia/android/app/application:application_injector",
"//app/src/main/java/org/oppia/android/app/application:application_injector_provider",
"//app/src/main/java/org/oppia/android/app/application:common_application_modules",
+ "//app/src/main/java/org/oppia/android/app/application/testing:testing_build_flavor_module",
"//app/src/main/java/org/oppia/android/app/translation/testing:test_module",
"//domain",
"//testing",
diff --git a/app/src/sharedTest/java/org/oppia/android/app/databinding/DrawableBindingAdaptersTest.kt b/app/src/sharedTest/java/org/oppia/android/app/databinding/DrawableBindingAdaptersTest.kt
index 1bee02bb647..da2853a4422 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/databinding/DrawableBindingAdaptersTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/databinding/DrawableBindingAdaptersTest.kt
@@ -26,6 +26,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.databinding.DrawableBindingAdapters.setBackgroundColor
import org.oppia.android.app.databinding.DrawableBindingAdapters.setBackgroundDrawable
import org.oppia.android.app.databinding.DrawableBindingAdapters.setTopBackgroundDrawable
@@ -183,7 +184,7 @@ class DrawableBindingAdaptersTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/databinding/ImageViewBindingAdaptersTest.kt b/app/src/sharedTest/java/org/oppia/android/app/databinding/ImageViewBindingAdaptersTest.kt
index 6559b4e211b..fe003c940f8 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/databinding/ImageViewBindingAdaptersTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/databinding/ImageViewBindingAdaptersTest.kt
@@ -30,6 +30,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.databinding.ImageViewBindingAdapters.setPlayStateDrawable
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
@@ -225,7 +226,7 @@ class ImageViewBindingAdaptersTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class,
- MetricLogSchedulerModule::class
+ MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
/** Create a TestApplicationComponent. */
diff --git a/app/src/sharedTest/java/org/oppia/android/app/databinding/MarginBindingAdaptersTest.kt b/app/src/sharedTest/java/org/oppia/android/app/databinding/MarginBindingAdaptersTest.kt
index 51af7e5e519..212323d5fdb 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/databinding/MarginBindingAdaptersTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/databinding/MarginBindingAdaptersTest.kt
@@ -32,6 +32,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.databinding.MarginBindingAdapters.setLayoutMarginEnd
import org.oppia.android.app.databinding.MarginBindingAdapters.setLayoutMarginStart
import org.oppia.android.app.devoptions.DeveloperOptionsModule
@@ -313,7 +314,7 @@ class MarginBindingAdaptersTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class,
- MetricLogSchedulerModule::class
+ MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
/** Create a TestApplicationComponent. */
diff --git a/app/src/sharedTest/java/org/oppia/android/app/databinding/StateAssemblerMarginBindingAdaptersTest.kt b/app/src/sharedTest/java/org/oppia/android/app/databinding/StateAssemblerMarginBindingAdaptersTest.kt
index 8f24ad52f76..e9603c8d4c0 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/databinding/StateAssemblerMarginBindingAdaptersTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/databinding/StateAssemblerMarginBindingAdaptersTest.kt
@@ -32,6 +32,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.databinding.StateAssemblerMarginBindingAdapters.setExplorationSplitViewMargin
import org.oppia.android.app.databinding.StateAssemblerMarginBindingAdapters.setExplorationViewMargin
import org.oppia.android.app.databinding.StateAssemblerMarginBindingAdapters.setQuestionSplitViewMargin
@@ -501,7 +502,7 @@ class StateAssemblerMarginBindingAdaptersTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class,
- MetricLogSchedulerModule::class
+ MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
/** Create a TestApplicationComponent. */
diff --git a/app/src/sharedTest/java/org/oppia/android/app/databinding/StateAssemblerPaddingBindingAdaptersTest.kt b/app/src/sharedTest/java/org/oppia/android/app/databinding/StateAssemblerPaddingBindingAdaptersTest.kt
index d4c2448a4db..ce12765a684 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/databinding/StateAssemblerPaddingBindingAdaptersTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/databinding/StateAssemblerPaddingBindingAdaptersTest.kt
@@ -30,6 +30,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.databinding.StateAssemblerPaddingBindingAdapters.setExplorationSplitViewPadding
import org.oppia.android.app.databinding.StateAssemblerPaddingBindingAdapters.setExplorationViewPadding
import org.oppia.android.app.databinding.StateAssemblerPaddingBindingAdapters.setQuestionSplitViewPadding
@@ -499,7 +500,7 @@ class StateAssemblerPaddingBindingAdaptersTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class,
- MetricLogSchedulerModule::class
+ MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
diff --git a/app/src/sharedTest/java/org/oppia/android/app/databinding/TextViewBindingAdaptersTest.kt b/app/src/sharedTest/java/org/oppia/android/app/databinding/TextViewBindingAdaptersTest.kt
index ebd73e65eda..aff64f8daa1 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/databinding/TextViewBindingAdaptersTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/databinding/TextViewBindingAdaptersTest.kt
@@ -24,6 +24,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.databinding.TextViewBindingAdapters.setDrawableEndCompat
import org.oppia.android.app.databinding.TextViewBindingAdapters.setProfileDataText
import org.oppia.android.app.databinding.TextViewBindingAdapters.setProfileLastVisitedText
@@ -332,7 +333,7 @@ class TextViewBindingAdaptersTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/databinding/ViewBindingAdaptersTest.kt b/app/src/sharedTest/java/org/oppia/android/app/databinding/ViewBindingAdaptersTest.kt
index 5127d9aec73..2275048ed95 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/databinding/ViewBindingAdaptersTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/databinding/ViewBindingAdaptersTest.kt
@@ -30,6 +30,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.databinding.ViewBindingAdapters.setRotationAnimation
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
@@ -233,7 +234,7 @@ class ViewBindingAdaptersTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class,
- MetricLogSchedulerModule::class
+ MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
/** Create a TestApplicationComponent. */
diff --git a/app/src/sharedTest/java/org/oppia/android/app/devoptions/DeveloperOptionsActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/devoptions/DeveloperOptionsActivityTest.kt
index f5be1badb63..78e2f796262 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/devoptions/DeveloperOptionsActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/devoptions/DeveloperOptionsActivityTest.kt
@@ -49,6 +49,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.mathexpressionparser.MathExpressionParserActivity
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
import org.oppia.android.app.recyclerview.RecyclerViewMatcher.Companion.atPositionOnView
@@ -325,7 +326,7 @@ class DeveloperOptionsActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/devoptions/DeveloperOptionsFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/devoptions/DeveloperOptionsFragmentTest.kt
index 98130794bda..b1e1c4215b4 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/devoptions/DeveloperOptionsFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/devoptions/DeveloperOptionsFragmentTest.kt
@@ -38,6 +38,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.forcenetworktype.ForceNetworkTypeActivity
import org.oppia.android.app.devoptions.markchapterscompleted.MarkChaptersCompletedActivity
import org.oppia.android.app.devoptions.markstoriescompleted.MarkStoriesCompletedActivity
@@ -656,7 +657,7 @@ class DeveloperOptionsFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkChaptersCompletedActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkChaptersCompletedActivityTest.kt
index 1f3326161e7..932a971c13a 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkChaptersCompletedActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkChaptersCompletedActivityTest.kt
@@ -27,6 +27,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.markchapterscompleted.MarkChaptersCompletedActivity
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
import org.oppia.android.app.shim.ViewBindingShimModule
@@ -187,7 +188,7 @@ class MarkChaptersCompletedActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkChaptersCompletedFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkChaptersCompletedFragmentTest.kt
index 62272000673..b2ba91623d0 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkChaptersCompletedFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkChaptersCompletedFragmentTest.kt
@@ -34,6 +34,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.markchapterscompleted.testing.MarkChaptersCompletedTestActivity
import org.oppia.android.app.model.ProfileId
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -915,7 +916,7 @@ class MarkChaptersCompletedFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkStoriesCompletedActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkStoriesCompletedActivityTest.kt
index b4b998b9f7c..5978a29ce69 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkStoriesCompletedActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkStoriesCompletedActivityTest.kt
@@ -27,6 +27,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.markstoriescompleted.MarkStoriesCompletedActivity
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
import org.oppia.android.app.shim.ViewBindingShimModule
@@ -187,7 +188,7 @@ class MarkStoriesCompletedActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkStoriesCompletedFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkStoriesCompletedFragmentTest.kt
index 9613d6d6729..e2ab546bb6b 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkStoriesCompletedFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkStoriesCompletedFragmentTest.kt
@@ -34,6 +34,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.markstoriescompleted.testing.MarkStoriesCompletedTestActivity
import org.oppia.android.app.model.ProfileId
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -592,7 +593,7 @@ class MarkStoriesCompletedFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkTopicsCompletedActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkTopicsCompletedActivityTest.kt
index 5107bd10697..13a792f1c21 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkTopicsCompletedActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkTopicsCompletedActivityTest.kt
@@ -27,6 +27,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.marktopicscompleted.MarkTopicsCompletedActivity
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
import org.oppia.android.app.shim.ViewBindingShimModule
@@ -187,7 +188,7 @@ class MarkTopicsCompletedActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkTopicsCompletedFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkTopicsCompletedFragmentTest.kt
index 7ddd3a668ac..a13f699941d 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkTopicsCompletedFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkTopicsCompletedFragmentTest.kt
@@ -34,6 +34,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.marktopicscompleted.testing.MarkTopicsCompletedTestActivity
import org.oppia.android.app.model.ProfileId
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -562,7 +563,7 @@ class MarkTopicsCompletedFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/devoptions/ViewEventLogsActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/devoptions/ViewEventLogsActivityTest.kt
index 2104922adec..d76f14aabf0 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/devoptions/ViewEventLogsActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/devoptions/ViewEventLogsActivityTest.kt
@@ -28,6 +28,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.vieweventlogs.ViewEventLogsActivity
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
import org.oppia.android.app.shim.ViewBindingShimModule
@@ -178,7 +179,8 @@ class ViewEventLogsActivityTest {
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
SyncStatusModule::class, MetricLogSchedulerModule::class,
- PerformanceMetricsAssessorModule::class, PerformanceMetricsConfigurationsModule::class
+ PerformanceMetricsAssessorModule::class, PerformanceMetricsConfigurationsModule::class,
+ TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/devoptions/ViewEventLogsFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/devoptions/ViewEventLogsFragmentTest.kt
index e10ba410943..907042b27ac 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/devoptions/ViewEventLogsFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/devoptions/ViewEventLogsFragmentTest.kt
@@ -30,6 +30,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.vieweventlogs.testing.ViewEventLogsTestActivity
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
import org.oppia.android.app.recyclerview.RecyclerViewMatcher.Companion.atPositionOnView
@@ -578,7 +579,7 @@ class ViewEventLogsFragmentTest {
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class,
MetricLogSchedulerModule::class, PerformanceMetricsAssessorModule::class,
- PerformanceMetricsConfigurationsModule::class
+ PerformanceMetricsConfigurationsModule::class, TestingBuildFlavorModule::class
]
)
diff --git a/app/src/sharedTest/java/org/oppia/android/app/devoptions/forcenetworktype/ForceNetworkTypeActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/devoptions/forcenetworktype/ForceNetworkTypeActivityTest.kt
index 1647b6b5dee..1acc5d39820 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/devoptions/forcenetworktype/ForceNetworkTypeActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/devoptions/forcenetworktype/ForceNetworkTypeActivityTest.kt
@@ -27,6 +27,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -179,7 +180,7 @@ class ForceNetworkTypeActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class,
- MetricLogSchedulerModule::class
+ MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
/** [ApplicationComponent] for [ForceNetworkTypeActivityTest]. */
diff --git a/app/src/sharedTest/java/org/oppia/android/app/devoptions/forcenetworktype/ForceNetworkTypeFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/devoptions/forcenetworktype/ForceNetworkTypeFragmentTest.kt
index d6c30067abe..0b63f3edacb 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/devoptions/forcenetworktype/ForceNetworkTypeFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/devoptions/forcenetworktype/ForceNetworkTypeFragmentTest.kt
@@ -30,6 +30,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.devoptions.forcenetworktype.testing.ForceNetworkTypeTestActivity
@@ -395,7 +396,7 @@ class ForceNetworkTypeFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class,
- MetricLogSchedulerModule::class
+ MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
/** [ApplicationComponent] for [ForceNetworkTypeFragmentTest]. */
diff --git a/app/src/sharedTest/java/org/oppia/android/app/devoptions/mathexpressionparser/BUILD.bazel b/app/src/sharedTest/java/org/oppia/android/app/devoptions/mathexpressionparser/BUILD.bazel
index b0d8810bf89..e20913f64aa 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/devoptions/mathexpressionparser/BUILD.bazel
+++ b/app/src/sharedTest/java/org/oppia/android/app/devoptions/mathexpressionparser/BUILD.bazel
@@ -17,6 +17,7 @@ app_test(
"//app/src/main/java/org/oppia/android/app/application:application_injector",
"//app/src/main/java/org/oppia/android/app/application:application_injector_provider",
"//app/src/main/java/org/oppia/android/app/application:common_application_modules",
+ "//app/src/main/java/org/oppia/android/app/application/testing:testing_build_flavor_module",
"//app/src/main/java/org/oppia/android/app/translation/testing:test_module",
"//testing",
"//testing/src/main/java/org/oppia/android/testing/espresso:edit_text_input_action",
@@ -47,6 +48,7 @@ app_test(
"//app/src/main/java/org/oppia/android/app/application:application_injector",
"//app/src/main/java/org/oppia/android/app/application:application_injector_provider",
"//app/src/main/java/org/oppia/android/app/application:common_application_modules",
+ "//app/src/main/java/org/oppia/android/app/application/testing:testing_build_flavor_module",
"//app/src/main/java/org/oppia/android/app/testing/activity:test_activity",
"//app/src/main/java/org/oppia/android/app/translation/testing:test_module",
"//testing",
diff --git a/app/src/sharedTest/java/org/oppia/android/app/devoptions/mathexpressionparser/MathExpressionParserActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/devoptions/mathexpressionparser/MathExpressionParserActivityTest.kt
index e9a86da55ae..6a207e03bd8 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/devoptions/mathexpressionparser/MathExpressionParserActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/devoptions/mathexpressionparser/MathExpressionParserActivityTest.kt
@@ -25,6 +25,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -163,7 +164,7 @@ class MathExpressionParserActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/devoptions/mathexpressionparser/MathExpressionParserFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/devoptions/mathexpressionparser/MathExpressionParserFragmentTest.kt
index 6bf88c29bf3..4f3a4f62600 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/devoptions/mathexpressionparser/MathExpressionParserFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/devoptions/mathexpressionparser/MathExpressionParserFragmentTest.kt
@@ -34,6 +34,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -1413,7 +1414,7 @@ class MathExpressionParserFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/faq/FAQListFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/faq/FAQListFragmentTest.kt
index e6f86c7cbbf..33fd5eeddb9 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/faq/FAQListFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/faq/FAQListFragmentTest.kt
@@ -34,6 +34,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.help.faq.FAQListActivity
@@ -247,7 +248,7 @@ class FAQListFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/faq/FAQSingleActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/faq/FAQSingleActivityTest.kt
index 79c2ab467fb..1c354ef9c98 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/faq/FAQSingleActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/faq/FAQSingleActivityTest.kt
@@ -32,6 +32,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.help.faq.faqsingle.FAQSingleActivity
@@ -225,7 +226,7 @@ class FAQSingleActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/faq/FaqListActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/faq/FaqListActivityTest.kt
index 66b90ab902a..a9238755789 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/faq/FaqListActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/faq/FaqListActivityTest.kt
@@ -21,6 +21,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.help.faq.FAQListActivity
@@ -152,7 +153,7 @@ class FaqListActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/help/HelpActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/help/HelpActivityTest.kt
index 659279b6035..69c195e66e7 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/help/HelpActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/help/HelpActivityTest.kt
@@ -21,6 +21,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -154,7 +155,7 @@ class HelpActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/help/HelpFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/help/HelpFragmentTest.kt
index 085d91bda44..1c7cd066ce9 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/help/HelpFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/help/HelpFragmentTest.kt
@@ -44,6 +44,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.help.faq.FAQListActivity
@@ -1442,7 +1443,7 @@ class HelpFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt
index 99e47450a8a..b229732f377 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt
@@ -50,6 +50,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.home.recentlyplayed.RecentlyPlayedActivity
@@ -1811,7 +1812,7 @@ class HomeActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/home/RecentlyPlayedFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/home/RecentlyPlayedFragmentTest.kt
index 672069768fd..f086e9920d2 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/home/RecentlyPlayedFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/home/RecentlyPlayedFragmentTest.kt
@@ -46,6 +46,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.home.recentlyplayed.RecentlyPlayedActivity
@@ -1506,7 +1507,7 @@ class RecentlyPlayedFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/home/TopicSummaryViewModelTest.kt b/app/src/sharedTest/java/org/oppia/android/app/home/TopicSummaryViewModelTest.kt
index 7e6cedb6445..f910210e0ac 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/home/TopicSummaryViewModelTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/home/TopicSummaryViewModelTest.kt
@@ -19,6 +19,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.home.topiclist.TopicSummaryViewModel
@@ -373,7 +374,7 @@ class TopicSummaryViewModelTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/home/WelcomeViewModelTest.kt b/app/src/sharedTest/java/org/oppia/android/app/home/WelcomeViewModelTest.kt
index 7505e4d774c..95c188b9600 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/home/WelcomeViewModelTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/home/WelcomeViewModelTest.kt
@@ -20,6 +20,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -357,7 +358,7 @@ class WelcomeViewModelTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/home/promotedlist/PromotedStoryListViewModelTest.kt b/app/src/sharedTest/java/org/oppia/android/app/home/promotedlist/PromotedStoryListViewModelTest.kt
index aee3ce36441..15988155b7a 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/home/promotedlist/PromotedStoryListViewModelTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/home/promotedlist/PromotedStoryListViewModelTest.kt
@@ -19,6 +19,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.model.PromotedActivityList
@@ -369,7 +370,7 @@ class PromotedStoryListViewModelTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/home/promotedlist/PromotedStoryViewModelTest.kt b/app/src/sharedTest/java/org/oppia/android/app/home/promotedlist/PromotedStoryViewModelTest.kt
index 6208ea3fbec..0e4f82c366e 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/home/promotedlist/PromotedStoryViewModelTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/home/promotedlist/PromotedStoryViewModelTest.kt
@@ -19,6 +19,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.model.PromotedStory
@@ -379,7 +380,7 @@ class PromotedStoryViewModelTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/mydownloads/MyDownloadsActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/mydownloads/MyDownloadsActivityTest.kt
index a9b9c815a49..d1b682cbb0b 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/mydownloads/MyDownloadsActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/mydownloads/MyDownloadsActivityTest.kt
@@ -20,6 +20,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -142,7 +143,7 @@ class MyDownloadsActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/mydownloads/MyDownloadsFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/mydownloads/MyDownloadsFragmentTest.kt
index a1aa44be743..330171bab0c 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/mydownloads/MyDownloadsFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/mydownloads/MyDownloadsFragmentTest.kt
@@ -30,6 +30,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -233,7 +234,7 @@ class MyDownloadsFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/notice/BUILD.bazel b/app/src/sharedTest/java/org/oppia/android/app/notice/BUILD.bazel
new file mode 100644
index 00000000000..a58c530be9f
--- /dev/null
+++ b/app/src/sharedTest/java/org/oppia/android/app/notice/BUILD.bazel
@@ -0,0 +1,81 @@
+"""
+Tests for notices shown in the app.
+"""
+
+load("@dagger//:workspace_defs.bzl", "dagger_rules")
+load("//app:app_test.bzl", "app_test")
+load("//app:test_with_resources.bzl", "test_with_resources")
+
+app_test(
+ name = "BetaNoticeDialogFragmentTest",
+ processed_src = test_with_resources("BetaNoticeDialogFragmentTest.kt"),
+ test_class = "org.oppia.android.app.notice.BetaNoticeDialogFragmentTest",
+ deps = [
+ ":dagger",
+ "//app",
+ "//app/src/main/java/org/oppia/android/app/application:application_component",
+ "//app/src/main/java/org/oppia/android/app/application:application_injector",
+ "//app/src/main/java/org/oppia/android/app/application:application_injector_provider",
+ "//app/src/main/java/org/oppia/android/app/application:common_application_modules",
+ "//app/src/main/java/org/oppia/android/app/application/testing:testing_build_flavor_module",
+ "//app/src/main/java/org/oppia/android/app/notice/testing:beta_notice_dialog_frgment_test_activity",
+ "//app/src/main/java/org/oppia/android/app/translation/testing:test_module",
+ "//data/src/main/java/org/oppia/android/data/backends/gae:prod_module",
+ "//domain/src/main/java/org/oppia/android/domain/onboarding/testing:retriever_test_module",
+ "//testing",
+ "//testing/src/main/java/org/oppia/android/testing/junit:initialize_default_locale_rule",
+ "//testing/src/main/java/org/oppia/android/testing/robolectric:test_module",
+ "//testing/src/main/java/org/oppia/android/testing/threading:test_module",
+ "//testing/src/main/java/org/oppia/android/testing/time:test_module",
+ "//third_party:androidx_test_espresso_espresso-core",
+ "//third_party:androidx_test_ext_junit",
+ "//third_party:org_robolectric_robolectric",
+ "//third_party:robolectric_android-all",
+ "//utility/src/main/java/org/oppia/android/util/accessibility:test_module",
+ "//utility/src/main/java/org/oppia/android/util/caching:asset_prod_module",
+ "//utility/src/main/java/org/oppia/android/util/caching/testing:caching_test_module",
+ "//utility/src/main/java/org/oppia/android/util/locale/testing:test_module",
+ "//utility/src/main/java/org/oppia/android/util/logging:prod_module",
+ "//utility/src/main/java/org/oppia/android/util/logging/firebase:debug_module",
+ "//utility/src/main/java/org/oppia/android/util/networking:debug_module",
+ "//utility/src/main/java/org/oppia/android/util/networking:debug_util_module",
+ ],
+)
+
+app_test(
+ name = "GeneralAvailabilityUpgradeNoticeDialogFragmentTest",
+ processed_src = test_with_resources("GeneralAvailabilityUpgradeNoticeDialogFragmentTest.kt"),
+ test_class = "org.oppia.android.app.notice.GeneralAvailabilityUpgradeNoticeDialogFragmentTest",
+ deps = [
+ ":dagger",
+ "//app",
+ "//app/src/main/java/org/oppia/android/app/application:application_component",
+ "//app/src/main/java/org/oppia/android/app/application:application_injector",
+ "//app/src/main/java/org/oppia/android/app/application:application_injector_provider",
+ "//app/src/main/java/org/oppia/android/app/application:common_application_modules",
+ "//app/src/main/java/org/oppia/android/app/application/testing:testing_build_flavor_module",
+ "//app/src/main/java/org/oppia/android/app/notice/testing:general_availability_upgrade_notice_dialog_fragment_test_activity",
+ "//app/src/main/java/org/oppia/android/app/translation/testing:test_module",
+ "//data/src/main/java/org/oppia/android/data/backends/gae:prod_module",
+ "//domain/src/main/java/org/oppia/android/domain/onboarding/testing:retriever_test_module",
+ "//testing",
+ "//testing/src/main/java/org/oppia/android/testing/junit:initialize_default_locale_rule",
+ "//testing/src/main/java/org/oppia/android/testing/robolectric:test_module",
+ "//testing/src/main/java/org/oppia/android/testing/threading:test_module",
+ "//testing/src/main/java/org/oppia/android/testing/time:test_module",
+ "//third_party:androidx_test_espresso_espresso-core",
+ "//third_party:androidx_test_ext_junit",
+ "//third_party:org_robolectric_robolectric",
+ "//third_party:robolectric_android-all",
+ "//utility/src/main/java/org/oppia/android/util/accessibility:test_module",
+ "//utility/src/main/java/org/oppia/android/util/caching:asset_prod_module",
+ "//utility/src/main/java/org/oppia/android/util/caching/testing:caching_test_module",
+ "//utility/src/main/java/org/oppia/android/util/locale/testing:test_module",
+ "//utility/src/main/java/org/oppia/android/util/logging:prod_module",
+ "//utility/src/main/java/org/oppia/android/util/logging/firebase:debug_module",
+ "//utility/src/main/java/org/oppia/android/util/networking:debug_module",
+ "//utility/src/main/java/org/oppia/android/util/networking:debug_util_module",
+ ],
+)
+
+dagger_rules()
diff --git a/app/src/sharedTest/java/org/oppia/android/app/notice/BetaNoticeDialogFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/notice/BetaNoticeDialogFragmentTest.kt
new file mode 100644
index 00000000000..0a694c49b2b
--- /dev/null
+++ b/app/src/sharedTest/java/org/oppia/android/app/notice/BetaNoticeDialogFragmentTest.kt
@@ -0,0 +1,278 @@
+package org.oppia.android.app.notice
+
+import android.app.Application
+import android.view.View
+import androidx.appcompat.app.AppCompatActivity
+import androidx.test.core.app.ActivityScenario
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.espresso.Espresso.onView
+import androidx.test.espresso.action.ViewActions.click
+import androidx.test.espresso.assertion.PositionAssertions.isCompletelyBelow
+import androidx.test.espresso.assertion.ViewAssertions.matches
+import androidx.test.espresso.matcher.RootMatchers.isDialog
+import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
+import androidx.test.espresso.matcher.ViewMatchers.withId
+import androidx.test.espresso.matcher.ViewMatchers.withText
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import dagger.BindsInstance
+import dagger.Component
+import org.hamcrest.Matcher
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.verify
+import org.mockito.junit.MockitoJUnit
+import org.mockito.junit.MockitoRule
+import org.oppia.android.R
+import org.oppia.android.app.activity.ActivityComponent
+import org.oppia.android.app.activity.ActivityComponentFactory
+import org.oppia.android.app.application.ApplicationComponent
+import org.oppia.android.app.application.ApplicationInjector
+import org.oppia.android.app.application.ApplicationInjectorProvider
+import org.oppia.android.app.application.ApplicationModule
+import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
+import org.oppia.android.app.devoptions.DeveloperOptionsModule
+import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
+import org.oppia.android.app.notice.testing.BetaNoticeDialogFragmentTestActivity
+import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
+import org.oppia.android.app.shim.ViewBindingShimModule
+import org.oppia.android.app.topic.PracticeTabModule
+import org.oppia.android.app.translation.testing.ActivityRecreatorTestModule
+import org.oppia.android.data.backends.gae.NetworkConfigProdModule
+import org.oppia.android.data.backends.gae.NetworkModule
+import org.oppia.android.domain.classify.InteractionsModule
+import org.oppia.android.domain.classify.rules.algebraicexpressioninput.AlgebraicExpressionInputModule
+import org.oppia.android.domain.classify.rules.continueinteraction.ContinueModule
+import org.oppia.android.domain.classify.rules.dragAndDropSortInput.DragDropSortInputModule
+import org.oppia.android.domain.classify.rules.fractioninput.FractionInputModule
+import org.oppia.android.domain.classify.rules.imageClickInput.ImageClickInputModule
+import org.oppia.android.domain.classify.rules.itemselectioninput.ItemSelectionInputModule
+import org.oppia.android.domain.classify.rules.mathequationinput.MathEquationInputModule
+import org.oppia.android.domain.classify.rules.multiplechoiceinput.MultipleChoiceInputModule
+import org.oppia.android.domain.classify.rules.numberwithunits.NumberWithUnitsRuleModule
+import org.oppia.android.domain.classify.rules.numericexpressioninput.NumericExpressionInputModule
+import org.oppia.android.domain.classify.rules.numericinput.NumericInputRuleModule
+import org.oppia.android.domain.classify.rules.ratioinput.RatioInputModule
+import org.oppia.android.domain.classify.rules.textinput.TextInputRuleModule
+import org.oppia.android.domain.exploration.lightweightcheckpointing.ExplorationStorageModule
+import org.oppia.android.domain.hintsandsolution.HintsAndSolutionConfigFastShowTestModule
+import org.oppia.android.domain.hintsandsolution.HintsAndSolutionProdModule
+import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
+import org.oppia.android.domain.oppialogger.LogStorageModule
+import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
+import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
+import org.oppia.android.domain.platformparameter.PlatformParameterModule
+import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
+import org.oppia.android.domain.question.QuestionModule
+import org.oppia.android.domain.topic.PrimeTopicAssetsControllerModule
+import org.oppia.android.domain.workmanager.WorkManagerConfigurationModule
+import org.oppia.android.testing.OppiaTestRule
+import org.oppia.android.testing.TestImageLoaderModule
+import org.oppia.android.testing.TestLogReportingModule
+import org.oppia.android.testing.junit.InitializeDefaultLocaleRule
+import org.oppia.android.testing.robolectric.RobolectricModule
+import org.oppia.android.testing.threading.TestCoroutineDispatchers
+import org.oppia.android.testing.threading.TestDispatcherModule
+import org.oppia.android.testing.time.FakeOppiaClockModule
+import org.oppia.android.util.accessibility.AccessibilityTestModule
+import org.oppia.android.util.caching.AssetModule
+import org.oppia.android.util.caching.testing.CachingTestModule
+import org.oppia.android.util.gcsresource.GcsResourceModule
+import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.LoggerModule
+import org.oppia.android.util.logging.SyncStatusModule
+import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
+import org.oppia.android.util.networking.NetworkConnectionDebugUtilModule
+import org.oppia.android.util.networking.NetworkConnectionUtilDebugModule
+import org.oppia.android.util.parser.html.HtmlParserEntityTypeModule
+import org.oppia.android.util.parser.image.ImageParsingModule
+import org.robolectric.annotation.Config
+import org.robolectric.annotation.LooperMode
+import javax.inject.Inject
+import javax.inject.Singleton
+
+/** Tests for [BetaNoticeDialogFragment]. */
+// FunctionName: test names are conventionally named with underscores.
+@Suppress("FunctionName")
+@RunWith(AndroidJUnit4::class)
+@Config(
+ application = BetaNoticeDialogFragmentTest.TestApplication::class, qualifiers = "port-xxhdpi"
+)
+@LooperMode(LooperMode.Mode.PAUSED)
+class BetaNoticeDialogFragmentTest {
+ @get:Rule
+ val initializeDefaultLocaleRule = InitializeDefaultLocaleRule()
+
+ @get:Rule
+ val oppiaTestRule = OppiaTestRule()
+
+ @field:[Rule JvmField] val mockitoRule: MockitoRule = MockitoJUnit.rule()
+
+ @Inject
+ lateinit var testCoroutineDispatchers: TestCoroutineDispatchers
+
+ @Mock
+ lateinit var mockBetaNoticeClosedListener: BetaNoticeClosedListener
+
+ @Before
+ fun setUp() {
+ setUpTestApplicationComponent()
+ }
+
+ @Test
+ fun testFragment_hasExpectedTitle() {
+ launchBetaNoticeDialogFragmentTestActivity {
+ onDialogView(withText(R.string.beta_notice_dialog_title)).check(matches(isDisplayed()))
+ }
+ }
+
+ @Test
+ fun testFragment_hasExpectedContentMessageTextUnderTitle() {
+ launchBetaNoticeDialogFragmentTestActivity {
+ onDialogView(withId(R.id.beta_notice_dialog_message)).check(matches(isDisplayed()))
+ onDialogView(withId(R.id.beta_notice_dialog_message))
+ .check(matches(withText(R.string.beta_notice_dialog_message)))
+ onDialogView(withId(R.id.beta_notice_dialog_message))
+ .check(isCompletelyBelow(withText(R.string.beta_notice_dialog_title)))
+ }
+ }
+
+ @Test
+ fun testFragment_hasDoNotShowAgainCheckboxUnderContentMessage() {
+ launchBetaNoticeDialogFragmentTestActivity {
+ onDialogView(withId(R.id.beta_notice_dialog_preference_checkbox))
+ .check(matches(isDisplayed()))
+ onDialogView(withId(R.id.beta_notice_dialog_preference_checkbox))
+ .check(matches(withText(R.string.beta_notice_dialog_do_not_show_again_text)))
+ onDialogView(withId(R.id.beta_notice_dialog_preference_checkbox))
+ .check(isCompletelyBelow(withId(R.id.beta_notice_dialog_message)))
+ }
+ }
+
+ @Test
+ fun testFragment_hasExpectedAcknowledgementButtonUnderDoNotShowAgainCheckbox() {
+ launchBetaNoticeDialogFragmentTestActivity {
+ onDialogView(withText(R.string.beta_notice_dialog_close_button_text))
+ .check(matches(isDisplayed()))
+ onDialogView(withText(R.string.beta_notice_dialog_close_button_text))
+ .check(isCompletelyBelow(withId(R.id.beta_notice_dialog_preference_checkbox)))
+ }
+ }
+
+ @Test
+ fun testFragment_clickAcknowledgeButton_callsCallbackListenerWithFalse() {
+ launchBetaNoticeDialogFragmentTestActivity {
+ clickOnDialogView(withText(R.string.beta_notice_dialog_close_button_text))
+
+ verify(mockBetaNoticeClosedListener).onBetaNoticeOkayButtonClicked(false)
+ }
+ }
+
+ @Test
+ fun testFragment_clickDoNotShowCheckbox_clickAcknowledgeButton_callsCallbackListenerWithTrue() {
+ launchBetaNoticeDialogFragmentTestActivity {
+ clickOnDialogView(withId(R.id.beta_notice_dialog_preference_checkbox))
+
+ clickOnDialogView(withText(R.string.beta_notice_dialog_close_button_text))
+
+ verify(mockBetaNoticeClosedListener).onBetaNoticeOkayButtonClicked(true)
+ }
+ }
+
+ @Test
+ fun testFragment_toggleCheckbox_clickAcknowledgeButton_callsCallbackListenerWithFalse() {
+ launchBetaNoticeDialogFragmentTestActivity {
+ // Select, then deselect, the checkbox before closing the dialog.
+ clickOnDialogView(withId(R.id.beta_notice_dialog_preference_checkbox))
+ clickOnDialogView(withId(R.id.beta_notice_dialog_preference_checkbox))
+
+ clickOnDialogView(withText(R.string.beta_notice_dialog_close_button_text))
+
+ verify(mockBetaNoticeClosedListener).onBetaNoticeOkayButtonClicked(false)
+ }
+ }
+
+ private fun launchBetaNoticeDialogFragmentTestActivity(testBlock: () -> Unit) {
+ // Launch the test activity, but make sure that it's properly set up & time is given for it to
+ // initialize.
+ ActivityScenario.launch(BetaNoticeDialogFragmentTestActivity::class.java).use { scenario ->
+ scenario.onActivity { it.mockCallbackListener = mockBetaNoticeClosedListener }
+ testCoroutineDispatchers.runCurrent()
+ testBlock()
+ }
+ }
+
+ private fun clickOnDialogView(matcher: Matcher) {
+ onDialogView(matcher).perform(click())
+ testCoroutineDispatchers.runCurrent()
+ }
+
+ private fun setUpTestApplicationComponent() {
+ ApplicationProvider.getApplicationContext().inject(this)
+ }
+
+ private companion object {
+ private fun onDialogView(matcher: Matcher) = onView(matcher).inRoot(isDialog())
+ }
+
+ @Singleton
+ @Component(
+ modules = [
+ RobolectricModule::class, PlatformParameterModule::class,
+ TestDispatcherModule::class, ApplicationModule::class, LoggerModule::class,
+ ContinueModule::class, FractionInputModule::class, ItemSelectionInputModule::class,
+ MultipleChoiceInputModule::class, NumberWithUnitsRuleModule::class,
+ NumericInputRuleModule::class, TextInputRuleModule::class, DragDropSortInputModule::class,
+ ImageClickInputModule::class, InteractionsModule::class, GcsResourceModule::class,
+ TestImageLoaderModule::class, ImageParsingModule::class, HtmlParserEntityTypeModule::class,
+ QuestionModule::class, TestLogReportingModule::class, AccessibilityTestModule::class,
+ LogStorageModule::class, PrimeTopicAssetsControllerModule::class,
+ ExpirationMetaDataRetrieverModule::class, ViewBindingShimModule::class,
+ RatioInputModule::class, ApplicationStartupListenerModule::class,
+ HintsAndSolutionConfigFastShowTestModule::class, HintsAndSolutionProdModule::class,
+ WorkManagerConfigurationModule::class, LogReportWorkerModule::class,
+ FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
+ DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
+ ExplorationStorageModule::class, NetworkConnectionUtilDebugModule::class,
+ NetworkConnectionDebugUtilModule::class, NetworkModule::class, NetworkConfigProdModule::class,
+ AssetModule::class, LocaleProdModule::class, ActivityRecreatorTestModule::class,
+ PlatformParameterSingletonModule::class, NumericExpressionInputModule::class,
+ AlgebraicExpressionInputModule::class, MathEquationInputModule::class,
+ SplitScreenInteractionModule::class, LoggingIdentifierModule::class,
+ ApplicationLifecycleModule::class, SyncStatusModule::class, TestingBuildFlavorModule::class,
+ CachingTestModule::class, MetricLogSchedulerModule::class
+ ]
+ )
+ interface TestApplicationComponent : ApplicationComponent {
+ @Component.Builder
+ interface Builder {
+ @BindsInstance
+ fun setApplication(application: Application): Builder
+
+ fun build(): TestApplicationComponent
+ }
+
+ fun inject(test: BetaNoticeDialogFragmentTest)
+ }
+
+ class TestApplication : Application(), ActivityComponentFactory, ApplicationInjectorProvider {
+ private val component: TestApplicationComponent by lazy {
+ DaggerBetaNoticeDialogFragmentTest_TestApplicationComponent.builder()
+ .setApplication(this)
+ .build()
+ }
+
+ fun inject(test: BetaNoticeDialogFragmentTest) = component.inject(test)
+
+ override fun createActivityComponent(activity: AppCompatActivity): ActivityComponent {
+ return component.getActivityComponentBuilderProvider().get().setActivity(activity).build()
+ }
+
+ override fun getApplicationInjector(): ApplicationInjector = component
+ }
+}
diff --git a/app/src/sharedTest/java/org/oppia/android/app/notice/GeneralAvailabilityUpgradeNoticeDialogFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/notice/GeneralAvailabilityUpgradeNoticeDialogFragmentTest.kt
new file mode 100644
index 00000000000..4207a1d5e78
--- /dev/null
+++ b/app/src/sharedTest/java/org/oppia/android/app/notice/GeneralAvailabilityUpgradeNoticeDialogFragmentTest.kt
@@ -0,0 +1,285 @@
+package org.oppia.android.app.notice
+
+import android.app.Application
+import android.view.View
+import androidx.appcompat.app.AppCompatActivity
+import androidx.test.core.app.ActivityScenario
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.espresso.Espresso.onView
+import androidx.test.espresso.action.ViewActions.click
+import androidx.test.espresso.assertion.PositionAssertions.isCompletelyBelow
+import androidx.test.espresso.assertion.ViewAssertions.matches
+import androidx.test.espresso.matcher.RootMatchers.isDialog
+import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
+import androidx.test.espresso.matcher.ViewMatchers.withId
+import androidx.test.espresso.matcher.ViewMatchers.withText
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import dagger.BindsInstance
+import dagger.Component
+import org.hamcrest.Matcher
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.verify
+import org.mockito.junit.MockitoJUnit
+import org.mockito.junit.MockitoRule
+import org.oppia.android.R
+import org.oppia.android.app.activity.ActivityComponent
+import org.oppia.android.app.activity.ActivityComponentFactory
+import org.oppia.android.app.application.ApplicationComponent
+import org.oppia.android.app.application.ApplicationInjector
+import org.oppia.android.app.application.ApplicationInjectorProvider
+import org.oppia.android.app.application.ApplicationModule
+import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
+import org.oppia.android.app.devoptions.DeveloperOptionsModule
+import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
+import org.oppia.android.app.notice.testing.GeneralAvailabilityUpgradeNoticeDialogFragmentTestActivity
+import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
+import org.oppia.android.app.shim.ViewBindingShimModule
+import org.oppia.android.app.topic.PracticeTabModule
+import org.oppia.android.app.translation.testing.ActivityRecreatorTestModule
+import org.oppia.android.data.backends.gae.NetworkConfigProdModule
+import org.oppia.android.data.backends.gae.NetworkModule
+import org.oppia.android.domain.classify.InteractionsModule
+import org.oppia.android.domain.classify.rules.algebraicexpressioninput.AlgebraicExpressionInputModule
+import org.oppia.android.domain.classify.rules.continueinteraction.ContinueModule
+import org.oppia.android.domain.classify.rules.dragAndDropSortInput.DragDropSortInputModule
+import org.oppia.android.domain.classify.rules.fractioninput.FractionInputModule
+import org.oppia.android.domain.classify.rules.imageClickInput.ImageClickInputModule
+import org.oppia.android.domain.classify.rules.itemselectioninput.ItemSelectionInputModule
+import org.oppia.android.domain.classify.rules.mathequationinput.MathEquationInputModule
+import org.oppia.android.domain.classify.rules.multiplechoiceinput.MultipleChoiceInputModule
+import org.oppia.android.domain.classify.rules.numberwithunits.NumberWithUnitsRuleModule
+import org.oppia.android.domain.classify.rules.numericexpressioninput.NumericExpressionInputModule
+import org.oppia.android.domain.classify.rules.numericinput.NumericInputRuleModule
+import org.oppia.android.domain.classify.rules.ratioinput.RatioInputModule
+import org.oppia.android.domain.classify.rules.textinput.TextInputRuleModule
+import org.oppia.android.domain.exploration.lightweightcheckpointing.ExplorationStorageModule
+import org.oppia.android.domain.hintsandsolution.HintsAndSolutionConfigFastShowTestModule
+import org.oppia.android.domain.hintsandsolution.HintsAndSolutionProdModule
+import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule
+import org.oppia.android.domain.oppialogger.LogStorageModule
+import org.oppia.android.domain.oppialogger.LoggingIdentifierModule
+import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule
+import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule
+import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule
+import org.oppia.android.domain.platformparameter.PlatformParameterModule
+import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
+import org.oppia.android.domain.question.QuestionModule
+import org.oppia.android.domain.topic.PrimeTopicAssetsControllerModule
+import org.oppia.android.domain.workmanager.WorkManagerConfigurationModule
+import org.oppia.android.testing.OppiaTestRule
+import org.oppia.android.testing.TestImageLoaderModule
+import org.oppia.android.testing.TestLogReportingModule
+import org.oppia.android.testing.junit.InitializeDefaultLocaleRule
+import org.oppia.android.testing.robolectric.RobolectricModule
+import org.oppia.android.testing.threading.TestCoroutineDispatchers
+import org.oppia.android.testing.threading.TestDispatcherModule
+import org.oppia.android.testing.time.FakeOppiaClockModule
+import org.oppia.android.util.accessibility.AccessibilityTestModule
+import org.oppia.android.util.caching.AssetModule
+import org.oppia.android.util.caching.testing.CachingTestModule
+import org.oppia.android.util.gcsresource.GcsResourceModule
+import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.LoggerModule
+import org.oppia.android.util.logging.SyncStatusModule
+import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
+import org.oppia.android.util.networking.NetworkConnectionDebugUtilModule
+import org.oppia.android.util.networking.NetworkConnectionUtilDebugModule
+import org.oppia.android.util.parser.html.HtmlParserEntityTypeModule
+import org.oppia.android.util.parser.image.ImageParsingModule
+import org.robolectric.annotation.Config
+import org.robolectric.annotation.LooperMode
+import javax.inject.Inject
+import javax.inject.Singleton
+
+/** Tests for [GeneralAvailabilityUpgradeNoticeDialogFragment]. */
+// FunctionName: test names are conventionally named with underscores.
+@Suppress("FunctionName")
+@RunWith(AndroidJUnit4::class)
+@Config(
+ application = GeneralAvailabilityUpgradeNoticeDialogFragmentTest.TestApplication::class,
+ qualifiers = "port-xxhdpi"
+)
+@LooperMode(LooperMode.Mode.PAUSED)
+class GeneralAvailabilityUpgradeNoticeDialogFragmentTest {
+ @get:Rule
+ val initializeDefaultLocaleRule = InitializeDefaultLocaleRule()
+
+ @get:Rule
+ val oppiaTestRule = OppiaTestRule()
+
+ @field:[Rule JvmField] val mockitoRule: MockitoRule = MockitoJUnit.rule()
+
+ @Inject
+ lateinit var testCoroutineDispatchers: TestCoroutineDispatchers
+
+ @Mock
+ lateinit var mockNoticeClosedListener: GeneralAvailabilityUpgradeNoticeClosedListener
+
+ @Before
+ fun setUp() {
+ setUpTestApplicationComponent()
+ }
+
+ @Test
+ fun testFragment_hasExpectedTitle() {
+ launchGeneralAvailabilityUpgradeNoticeDialogFragmentTestActivity {
+ onDialogView(withText(R.string.general_availability_notice_dialog_title))
+ .check(matches(isDisplayed()))
+ }
+ }
+
+ @Test
+ fun testFragment_hasExpectedContentMessageTextUnderTitle() {
+ launchGeneralAvailabilityUpgradeNoticeDialogFragmentTestActivity {
+ onDialogView(withId(R.id.ga_update_notice_dialog_message)).check(matches(isDisplayed()))
+ onDialogView(withId(R.id.ga_update_notice_dialog_message))
+ .check(matches(withText(R.string.general_availability_notice_dialog_message)))
+ onDialogView(withId(R.id.ga_update_notice_dialog_message))
+ .check(isCompletelyBelow(withText(R.string.general_availability_notice_dialog_title)))
+ }
+ }
+
+ @Test
+ fun testFragment_hasDoNotShowAgainCheckboxUnderContentMessage() {
+ launchGeneralAvailabilityUpgradeNoticeDialogFragmentTestActivity {
+ onDialogView(withId(R.id.ga_update_notice_dialog_preference_checkbox))
+ .check(matches(isDisplayed()))
+ onDialogView(withId(R.id.ga_update_notice_dialog_preference_checkbox)).check(
+ matches(withText(R.string.general_availability_notice_dialog_do_not_show_again_text))
+ )
+ onDialogView(withId(R.id.ga_update_notice_dialog_preference_checkbox))
+ .check(isCompletelyBelow(withId(R.id.ga_update_notice_dialog_message)))
+ }
+ }
+
+ @Test
+ fun testFragment_hasExpectedAcknowledgementButtonUnderDoNotShowAgainCheckbox() {
+ launchGeneralAvailabilityUpgradeNoticeDialogFragmentTestActivity {
+ onDialogView(withText(R.string.general_availability_notice_dialog_close_button_text))
+ .check(matches(isDisplayed()))
+ onDialogView(withText(R.string.general_availability_notice_dialog_close_button_text))
+ .check(isCompletelyBelow(withId(R.id.ga_update_notice_dialog_preference_checkbox)))
+ }
+ }
+
+ @Test
+ fun testFragment_clickAcknowledgeButton_callsCallbackListenerWithFalse() {
+ launchGeneralAvailabilityUpgradeNoticeDialogFragmentTestActivity {
+ clickOnDialogView(withText(R.string.general_availability_notice_dialog_close_button_text))
+
+ verify(mockNoticeClosedListener).onGaUpgradeNoticeOkayButtonClicked(false)
+ }
+ }
+
+ @Test
+ fun testFragment_clickDoNotShowCheckbox_clickAcknowledgeButton_callsCallbackListenerWithTrue() {
+ launchGeneralAvailabilityUpgradeNoticeDialogFragmentTestActivity {
+ clickOnDialogView(withId(R.id.ga_update_notice_dialog_preference_checkbox))
+
+ clickOnDialogView(withText(R.string.general_availability_notice_dialog_close_button_text))
+
+ verify(mockNoticeClosedListener).onGaUpgradeNoticeOkayButtonClicked(true)
+ }
+ }
+
+ @Test
+ fun testFragment_toggleCheckbox_clickAcknowledgeButton_callsCallbackListenerWithFalse() {
+ launchGeneralAvailabilityUpgradeNoticeDialogFragmentTestActivity {
+ // Select, then deselect, the checkbox before closing the dialog.
+ clickOnDialogView(withId(R.id.ga_update_notice_dialog_preference_checkbox))
+ clickOnDialogView(withId(R.id.ga_update_notice_dialog_preference_checkbox))
+
+ clickOnDialogView(withText(R.string.general_availability_notice_dialog_close_button_text))
+
+ verify(mockNoticeClosedListener).onGaUpgradeNoticeOkayButtonClicked(false)
+ }
+ }
+
+ private fun launchGeneralAvailabilityUpgradeNoticeDialogFragmentTestActivity(
+ testBlock: () -> Unit
+ ) {
+ // Launch the test activity, but make sure that it's properly set up & time is given for it to
+ // initialize.
+ ActivityScenario.launch(
+ GeneralAvailabilityUpgradeNoticeDialogFragmentTestActivity::class.java
+ ).use { scenario ->
+ scenario.onActivity { it.mockCallbackListener = mockNoticeClosedListener }
+ testCoroutineDispatchers.runCurrent()
+ testBlock()
+ }
+ }
+
+ private fun clickOnDialogView(matcher: Matcher) {
+ onDialogView(matcher).perform(click())
+ testCoroutineDispatchers.runCurrent()
+ }
+
+ private fun setUpTestApplicationComponent() {
+ ApplicationProvider.getApplicationContext().inject(this)
+ }
+
+ private companion object {
+ private fun onDialogView(matcher: Matcher) = onView(matcher).inRoot(isDialog())
+ }
+
+ @Singleton
+ @Component(
+ modules = [
+ RobolectricModule::class, PlatformParameterModule::class,
+ TestDispatcherModule::class, ApplicationModule::class, LoggerModule::class,
+ ContinueModule::class, FractionInputModule::class, ItemSelectionInputModule::class,
+ MultipleChoiceInputModule::class, NumberWithUnitsRuleModule::class,
+ NumericInputRuleModule::class, TextInputRuleModule::class, DragDropSortInputModule::class,
+ ImageClickInputModule::class, InteractionsModule::class, GcsResourceModule::class,
+ TestImageLoaderModule::class, ImageParsingModule::class, HtmlParserEntityTypeModule::class,
+ QuestionModule::class, TestLogReportingModule::class, AccessibilityTestModule::class,
+ LogStorageModule::class, PrimeTopicAssetsControllerModule::class,
+ ExpirationMetaDataRetrieverModule::class, ViewBindingShimModule::class,
+ RatioInputModule::class, ApplicationStartupListenerModule::class,
+ HintsAndSolutionConfigFastShowTestModule::class, HintsAndSolutionProdModule::class,
+ WorkManagerConfigurationModule::class, LogReportWorkerModule::class,
+ FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class,
+ DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class,
+ ExplorationStorageModule::class, NetworkConnectionUtilDebugModule::class,
+ NetworkConnectionDebugUtilModule::class, NetworkModule::class, NetworkConfigProdModule::class,
+ AssetModule::class, LocaleProdModule::class, ActivityRecreatorTestModule::class,
+ PlatformParameterSingletonModule::class, NumericExpressionInputModule::class,
+ AlgebraicExpressionInputModule::class, MathEquationInputModule::class,
+ SplitScreenInteractionModule::class, LoggingIdentifierModule::class,
+ ApplicationLifecycleModule::class, SyncStatusModule::class, TestingBuildFlavorModule::class,
+ CachingTestModule::class, MetricLogSchedulerModule::class
+ ]
+ )
+ interface TestApplicationComponent : ApplicationComponent {
+ @Component.Builder
+ interface Builder {
+ @BindsInstance
+ fun setApplication(application: Application): Builder
+
+ fun build(): TestApplicationComponent
+ }
+
+ fun inject(test: GeneralAvailabilityUpgradeNoticeDialogFragmentTest)
+ }
+
+ class TestApplication : Application(), ActivityComponentFactory, ApplicationInjectorProvider {
+ private val component: TestApplicationComponent by lazy {
+ DaggerGeneralAvailabilityUpgradeNoticeDialogFragmentTest_TestApplicationComponent.builder()
+ .setApplication(this)
+ .build()
+ }
+
+ fun inject(test: GeneralAvailabilityUpgradeNoticeDialogFragmentTest) = component.inject(test)
+
+ override fun createActivityComponent(activity: AppCompatActivity): ActivityComponent {
+ return component.getActivityComponentBuilderProvider().get().setActivity(activity).build()
+ }
+
+ override fun getApplicationInjector(): ApplicationInjector = component
+ }
+}
diff --git a/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingActivityTest.kt
index 412a7674a49..3757c17d7cf 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingActivityTest.kt
@@ -21,6 +21,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -151,7 +152,7 @@ class OnboardingActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingFragmentTest.kt
index 5b3d03d8824..4fea9798161 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingFragmentTest.kt
@@ -46,6 +46,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -723,7 +724,7 @@ class OnboardingFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/ongoingtopiclist/OngoingTopicListActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/ongoingtopiclist/OngoingTopicListActivityTest.kt
index c9d0f8ff1d1..44948180740 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/ongoingtopiclist/OngoingTopicListActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/ongoingtopiclist/OngoingTopicListActivityTest.kt
@@ -36,6 +36,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.model.ProfileId
@@ -458,7 +459,7 @@ class OngoingTopicListActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/options/AppLanguageActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/options/AppLanguageActivityTest.kt
index 62965d09a72..1bda24c4f48 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/options/AppLanguageActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/options/AppLanguageActivityTest.kt
@@ -21,6 +21,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -161,7 +162,7 @@ class AppLanguageActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/options/AppLanguageFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/options/AppLanguageFragmentTest.kt
index 78966f2e217..3f4aa8f3a31 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/options/AppLanguageFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/options/AppLanguageFragmentTest.kt
@@ -28,6 +28,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -256,7 +257,7 @@ class AppLanguageFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/options/AudioLanguageActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/options/AudioLanguageActivityTest.kt
index eb69586b13c..2bc4922f9a4 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/options/AudioLanguageActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/options/AudioLanguageActivityTest.kt
@@ -21,6 +21,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -161,7 +162,7 @@ class AudioLanguageActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/options/AudioLanguageFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/options/AudioLanguageFragmentTest.kt
index dbb338d76e2..69bf7e01e8a 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/options/AudioLanguageFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/options/AudioLanguageFragmentTest.kt
@@ -27,6 +27,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -249,7 +250,7 @@ class AudioLanguageFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/options/OptionsActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/options/OptionsActivityTest.kt
index b90e05fd338..8839bf88eb7 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/options/OptionsActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/options/OptionsActivityTest.kt
@@ -21,6 +21,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -153,7 +154,7 @@ class OptionsActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/options/OptionsFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/options/OptionsFragmentTest.kt
index 50701da0b58..5e17d4b0877 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/options/OptionsFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/options/OptionsFragmentTest.kt
@@ -39,6 +39,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -653,7 +654,7 @@ class OptionsFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/options/ReadingTextSizeActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/options/ReadingTextSizeActivityTest.kt
index 40fd59f6fb8..2d11f2d65cc 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/options/ReadingTextSizeActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/options/ReadingTextSizeActivityTest.kt
@@ -21,6 +21,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -161,7 +162,7 @@ class ReadingTextSizeActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/options/ReadingTextSizeFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/options/ReadingTextSizeFragmentTest.kt
index 46284607705..bb3b3d23a7b 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/options/ReadingTextSizeFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/options/ReadingTextSizeFragmentTest.kt
@@ -34,6 +34,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -315,7 +316,7 @@ class ReadingTextSizeFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/parser/HtmlParserTest.kt b/app/src/sharedTest/java/org/oppia/android/app/parser/HtmlParserTest.kt
index 6cc3bbcb4a0..83640c04d2f 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/parser/HtmlParserTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/parser/HtmlParserTest.kt
@@ -54,6 +54,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.model.LanguageSupportDefinition
@@ -907,7 +908,7 @@ class HtmlParserTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/player/audio/AudioFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/player/audio/AudioFragmentTest.kt
index 30186b1cc96..ecafe75284e 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/player/audio/AudioFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/player/audio/AudioFragmentTest.kt
@@ -41,6 +41,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.model.ProfileId
@@ -478,7 +479,7 @@ class AudioFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt
index 2020e38b87b..053cddc373a 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt
@@ -65,6 +65,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.help.HelpActivity
@@ -1958,7 +1959,7 @@ class ExplorationActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class,
- MetricLogSchedulerModule::class
+ MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
diff --git a/app/src/sharedTest/java/org/oppia/android/app/player/state/BUILD.bazel b/app/src/sharedTest/java/org/oppia/android/app/player/state/BUILD.bazel
index 457225f4fe4..1430f73fa51 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/player/state/BUILD.bazel
+++ b/app/src/sharedTest/java/org/oppia/android/app/player/state/BUILD.bazel
@@ -18,6 +18,7 @@ app_test(
"//app/src/main/java/org/oppia/android/app/application:application_injector",
"//app/src/main/java/org/oppia/android/app/application:application_injector_provider",
"//app/src/main/java/org/oppia/android/app/application:common_application_modules",
+ "//app/src/main/java/org/oppia/android/app/application/testing:testing_build_flavor_module",
"//app/src/main/java/org/oppia/android/app/translation/testing:test_module",
"//data/src/main/java/org/oppia/android/data/backends/gae:prod_module",
"//domain/src/main/java/org/oppia/android/domain/onboarding/testing:retriever_test_module",
diff --git a/app/src/sharedTest/java/org/oppia/android/app/player/state/StateFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/player/state/StateFragmentTest.kt
index f1898d255d3..ed0a0125b0d 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/player/state/StateFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/player/state/StateFragmentTest.kt
@@ -70,6 +70,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.model.OppiaLanguage
@@ -4319,7 +4320,7 @@ class StateFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/policies/PoliciesActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/policies/PoliciesActivityTest.kt
index 40789301bbd..26724b47f42 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/policies/PoliciesActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/policies/PoliciesActivityTest.kt
@@ -21,6 +21,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.model.PolicyPage
@@ -184,7 +185,7 @@ class PoliciesActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/policies/PoliciesFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/policies/PoliciesFragmentTest.kt
index f2ffe23dd5c..69b5e5ddbdf 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/policies/PoliciesFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/policies/PoliciesFragmentTest.kt
@@ -43,6 +43,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.model.PolicyPage
@@ -337,7 +338,7 @@ class PoliciesFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/profile/AddProfileActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/profile/AddProfileActivityTest.kt
index 4cd82b31973..4595e72857e 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/profile/AddProfileActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/profile/AddProfileActivityTest.kt
@@ -54,6 +54,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -1732,7 +1733,7 @@ class AddProfileActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/profile/AdminAuthActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/profile/AdminAuthActivityTest.kt
index c4934f2611c..23949bf6b7e 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/profile/AdminAuthActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/profile/AdminAuthActivityTest.kt
@@ -40,6 +40,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -672,7 +673,7 @@ class AdminAuthActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/profile/AdminPinActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/profile/AdminPinActivityTest.kt
index 4f66269badb..5b92a040c25 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/profile/AdminPinActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/profile/AdminPinActivityTest.kt
@@ -49,6 +49,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -1090,7 +1091,7 @@ class AdminPinActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/profile/PinPasswordActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/profile/PinPasswordActivityTest.kt
index e8770e57d44..c4b9a510724 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/profile/PinPasswordActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/profile/PinPasswordActivityTest.kt
@@ -41,6 +41,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.home.HomeActivity
@@ -1152,7 +1153,7 @@ class PinPasswordActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/profile/ProfileChooserFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/profile/ProfileChooserFragmentTest.kt
index cdcee36d429..cbb45e201cf 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/profile/ProfileChooserFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/profile/ProfileChooserFragmentTest.kt
@@ -39,6 +39,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.drawer.NAVIGATION_PROFILE_ID_ARGUMENT_KEY
@@ -529,7 +530,7 @@ class ProfileChooserFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/profileprogress/ProfilePictureActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/profileprogress/ProfilePictureActivityTest.kt
index f1e9541bb3c..51a4440dc1f 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/profileprogress/ProfilePictureActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/profileprogress/ProfilePictureActivityTest.kt
@@ -29,6 +29,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -204,7 +205,7 @@ class ProfilePictureActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/profileprogress/ProfileProgressActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/profileprogress/ProfileProgressActivityTest.kt
index 4716612c00e..a47d30bd5a0 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/profileprogress/ProfileProgressActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/profileprogress/ProfileProgressActivityTest.kt
@@ -21,6 +21,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -155,7 +156,7 @@ class ProfileProgressActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/profileprogress/ProfileProgressFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/profileprogress/ProfileProgressFragmentTest.kt
index 3593c3a83b7..b01743cdfcb 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/profileprogress/ProfileProgressFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/profileprogress/ProfileProgressFragmentTest.kt
@@ -54,6 +54,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.completedstorylist.CompletedStoryListActivity
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
@@ -856,7 +857,7 @@ class ProfileProgressFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/recyclerview/BindableAdapterTest.kt b/app/src/sharedTest/java/org/oppia/android/app/recyclerview/BindableAdapterTest.kt
index e8a168ee1af..0a8321945bb 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/recyclerview/BindableAdapterTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/recyclerview/BindableAdapterTest.kt
@@ -37,6 +37,7 @@ import org.oppia.android.app.application.ApplicationComponent
import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.fragment.FragmentComponent
@@ -767,7 +768,7 @@ class BindableAdapterTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/resumelesson/ResumeLessonActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/resumelesson/ResumeLessonActivityTest.kt
index e76a4ac0ab6..d3a0c8073bd 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/resumelesson/ResumeLessonActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/resumelesson/ResumeLessonActivityTest.kt
@@ -34,6 +34,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.model.ExplorationCheckpoint
@@ -225,7 +226,7 @@ class ResumeLessonActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/resumelesson/ResumeLessonFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/resumelesson/ResumeLessonFragmentTest.kt
index 1bf70dde862..4760439db99 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/resumelesson/ResumeLessonFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/resumelesson/ResumeLessonFragmentTest.kt
@@ -33,6 +33,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.model.ExplorationCheckpoint
@@ -314,7 +315,7 @@ class ResumeLessonFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditActivityTest.kt
index f950c6f152c..0e0450b08a2 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditActivityTest.kt
@@ -35,6 +35,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.model.ProfileId
@@ -378,7 +379,7 @@ class ProfileEditActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditFragmentTest.kt
index 84d523c5200..dcc7285bf51 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditFragmentTest.kt
@@ -35,6 +35,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -355,7 +356,7 @@ class ProfileEditFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
diff --git a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileListActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileListActivityTest.kt
index ea0e29aaac2..fc6b3cc972e 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileListActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileListActivityTest.kt
@@ -21,6 +21,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -151,7 +152,7 @@ class ProfileListActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileListFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileListFragmentTest.kt
index 6e8ac36d94f..37feb72c90d 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileListFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileListFragmentTest.kt
@@ -33,6 +33,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -389,7 +390,7 @@ class ProfileListFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileRenameActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileRenameActivityTest.kt
index 55d6e85a511..026dede3753 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileRenameActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileRenameActivityTest.kt
@@ -22,6 +22,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -174,7 +175,7 @@ class ProfileRenameActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileRenameFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileRenameFragmentTest.kt
index 9744a3daead..7efe91a973e 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileRenameFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileRenameFragmentTest.kt
@@ -37,6 +37,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -463,7 +464,7 @@ class ProfileRenameFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileResetPinActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileResetPinActivityTest.kt
index 38c6df5615d..766f0ffc3ec 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileResetPinActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileResetPinActivityTest.kt
@@ -23,6 +23,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -185,7 +186,7 @@ class ProfileResetPinActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileResetPinFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileResetPinFragmentTest.kt
index dc210acaa36..c82448b3733 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileResetPinFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileResetPinFragmentTest.kt
@@ -38,6 +38,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -1027,7 +1028,7 @@ class ProfileResetPinFragmentTest {
AlgebraicExpressionInputModule::class, MathEquationInputModule::class,
SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/splash/BUILD.bazel b/app/src/sharedTest/java/org/oppia/android/app/splash/BUILD.bazel
new file mode 100644
index 00000000000..8a15fa58892
--- /dev/null
+++ b/app/src/sharedTest/java/org/oppia/android/app/splash/BUILD.bazel
@@ -0,0 +1,53 @@
+"""
+Tests for the splash/app UI initialization process.
+"""
+
+load("@dagger//:workspace_defs.bzl", "dagger_rules")
+load("//app:app_test.bzl", "app_test")
+load("//app:test_with_resources.bzl", "test_with_resources")
+
+app_test(
+ name = "SplashActivityTest",
+ processed_src = test_with_resources("SplashActivityTest.kt"),
+ test_class = "org.oppia.android.app.splash.SplashActivityTest",
+ deps = [
+ ":dagger",
+ "//app",
+ "//app:test_deps",
+ "//app/src/main/java/org/oppia/android/app/application:application_component",
+ "//app/src/main/java/org/oppia/android/app/application:application_injector",
+ "//app/src/main/java/org/oppia/android/app/application:application_injector_provider",
+ "//app/src/main/java/org/oppia/android/app/application:common_application_modules",
+ "//app/src/main/java/org/oppia/android/app/translation/testing:test_module",
+ "//data/src/main/java/org/oppia/android/data/backends/gae:prod_module",
+ "//domain/src/main/java/org/oppia/android/domain/onboarding/testing:retriever_test_module",
+ "//domain/src/main/java/org/oppia/android/domain/translation:translation_controller",
+ "//testing",
+ "//testing/src/main/java/org/oppia/android/testing/data:data_provider_test_monitor",
+ "//testing/src/main/java/org/oppia/android/testing/espresso:edit_text_input_action",
+ "//testing/src/main/java/org/oppia/android/testing/junit:initialize_default_locale_rule",
+ "//testing/src/main/java/org/oppia/android/testing/junit:oppia_parameterized_test_runner",
+ "//testing/src/main/java/org/oppia/android/testing/junit:parameterized_auto_android_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:coroutine_executor_service",
+ "//testing/src/main/java/org/oppia/android/testing/threading:test_module",
+ "//testing/src/main/java/org/oppia/android/testing/time:test_module",
+ "//third_party:com_github_bumptech_glide_mocks",
+ "//third_party:com_google_truth_truth",
+ "//third_party:junit_junit",
+ "//third_party:org_robolectric_robolectric",
+ "//third_party:robolectric_android-all",
+ "//utility/src/main/java/org/oppia/android/util/accessibility:test_module",
+ "//utility/src/main/java/org/oppia/android/util/caching:asset_prod_module",
+ "//utility/src/main/java/org/oppia/android/util/caching/testing:caching_test_module",
+ "//utility/src/main/java/org/oppia/android/util/data:data_providers",
+ "//utility/src/main/java/org/oppia/android/util/locale/testing:test_module",
+ "//utility/src/main/java/org/oppia/android/util/logging:prod_module",
+ "//utility/src/main/java/org/oppia/android/util/logging/firebase:debug_module",
+ "//utility/src/main/java/org/oppia/android/util/networking:debug_module",
+ "//utility/src/main/java/org/oppia/android/util/networking:debug_util_module",
+ ],
+)
+
+dagger_rules()
diff --git a/app/src/sharedTest/java/org/oppia/android/app/splash/SplashActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/splash/SplashActivityTest.kt
index e554c9df2e1..9c1da667d90 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/splash/SplashActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/splash/SplashActivityTest.kt
@@ -3,23 +3,30 @@ package org.oppia.android.app.splash
import android.app.Application
import android.app.Instrumentation
import android.content.Context
+import android.content.Intent
+import android.view.View
import androidx.appcompat.app.AppCompatActivity
+import androidx.test.core.app.ActivityScenario
import androidx.test.core.app.ApplicationProvider
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.click
+import androidx.test.espresso.assertion.ViewAssertions.doesNotExist
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.intent.Intents
import androidx.test.espresso.intent.Intents.intended
import androidx.test.espresso.intent.matcher.IntentMatchers.hasComponent
import androidx.test.espresso.matcher.RootMatchers.isDialog
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
+import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withText
-import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
-import androidx.test.rule.ActivityTestRule
import com.google.common.truth.Truth.assertThat
import dagger.BindsInstance
import dagger.Component
+import dagger.Module
+import dagger.Provides
+import org.hamcrest.Matcher
+import org.hamcrest.Matchers.not
import org.junit.After
import org.junit.Before
import org.junit.Rule
@@ -35,6 +42,7 @@ import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
+import org.oppia.android.app.model.BuildFlavor
import org.oppia.android.app.model.OppiaLanguage.ARABIC
import org.oppia.android.app.model.OppiaLanguage.BRAZILIAN_PORTUGUESE
import org.oppia.android.app.model.OppiaLanguage.ENGLISH
@@ -85,6 +93,13 @@ import org.oppia.android.testing.OppiaTestRule
import org.oppia.android.testing.RunOn
import org.oppia.android.testing.TestLogReportingModule
import org.oppia.android.testing.TestPlatform
+import org.oppia.android.testing.data.DataProviderTestMonitor
+import org.oppia.android.testing.junit.OppiaParameterizedTestRunner
+import org.oppia.android.testing.junit.OppiaParameterizedTestRunner.Iteration
+import org.oppia.android.testing.junit.OppiaParameterizedTestRunner.Parameter
+import org.oppia.android.testing.junit.OppiaParameterizedTestRunner.RunParameterized
+import org.oppia.android.testing.junit.OppiaParameterizedTestRunner.SelectRunnerPlatform
+import org.oppia.android.testing.junit.ParameterizedAutoAndroidTestRunner
import org.oppia.android.testing.robolectric.RobolectricModule
import org.oppia.android.testing.threading.TestCoroutineDispatchers
import org.oppia.android.testing.threading.TestDispatcherModule
@@ -110,6 +125,7 @@ import java.time.Duration
import java.time.Instant
import java.util.Date
import java.util.Locale
+import java.util.concurrent.TimeUnit
import javax.inject.Inject
import javax.inject.Singleton
@@ -117,29 +133,33 @@ import javax.inject.Singleton
* Tests for [SplashActivity]. For context on the activity test rule setup see:
* https://jabknowsnothing.wordpress.com/2015/11/05/activitytestrule-espressos-test-lifecycle/.
*/
-@RunWith(AndroidJUnit4::class)
+// FunctionName: test names are conventionally named with underscores.
+@Suppress("FunctionName")
+@RunWith(OppiaParameterizedTestRunner::class)
+@SelectRunnerPlatform(ParameterizedAutoAndroidTestRunner::class)
@LooperMode(LooperMode.Mode.PAUSED)
@Config(application = SplashActivityTest.TestApplication::class, qualifiers = "port-xxhdpi")
class SplashActivityTest {
@get:Rule
val oppiaTestRule = OppiaTestRule()
- @Inject
- lateinit var context: Context
+ @Inject lateinit var context: Context
+ @Inject lateinit var testCoroutineDispatchers: TestCoroutineDispatchers
+ @Inject lateinit var fakeMetaDataRetriever: FakeExpirationMetaDataRetriever
+ @Inject lateinit var appLanguageLocaleHandler: AppLanguageLocaleHandler
+ @Inject lateinit var monitorFactory: DataProviderTestMonitor.Factory
+ @Inject lateinit var appStartupStateController: AppStartupStateController
- @Inject
- lateinit var testCoroutineDispatchers: TestCoroutineDispatchers
-
- @Inject
- lateinit var fakeMetaDataRetriever: FakeExpirationMetaDataRetriever
-
- @Inject
- lateinit var appLanguageLocaleHandler: AppLanguageLocaleHandler
+ @Parameter lateinit var firstOpen: String
+ @Parameter lateinit var secondOpen: String
private val expirationDateFormat by lazy { SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()) }
+ private val firstOpenFlavor by lazy { BuildFlavor.valueOf(firstOpen) }
+ private val secondOpenFlavor by lazy { BuildFlavor.valueOf(secondOpen) }
@Before
fun setUp() {
+ TestModule.buildFlavor = BuildFlavor.BUILD_FLAVOR_UNSPECIFIED
Intents.init()
}
@@ -149,23 +169,13 @@ class SplashActivityTest {
Intents.release()
}
- // The initialTouchMode enables the activity to be launched in touch mode. The launchActivity is
- // disabled to launch Activity explicitly within each test case.
- @get:Rule
- var activityTestRule: ActivityTestRule = ActivityTestRule(
- SplashActivity::class.java,
- /* initialTouchMode= */ true,
- /* launchActivity= */ false
- )
-
@Test
fun testSplashActivity_initialOpen_routesToOnboardingActivity() {
initializeTestApplication()
- activityTestRule.launchActivity(null)
- testCoroutineDispatchers.advanceUntilIdle()
-
- intended(hasComponent(OnboardingActivity::class.java.name))
+ launchSplashActivityFully {
+ intended(hasComponent(OnboardingActivity::class.java.name))
+ }
}
@Test
@@ -173,10 +183,9 @@ class SplashActivityTest {
simulateAppAlreadyOnboarded()
initializeTestApplication()
- activityTestRule.launchActivity(null)
- testCoroutineDispatchers.advanceUntilIdle()
-
- intended(hasComponent(ProfileChooserActivity::class.java.name))
+ launchSplashActivityFully {
+ intended(hasComponent(ProfileChooserActivity::class.java.name))
+ }
}
@Test
@@ -185,26 +194,24 @@ class SplashActivityTest {
setAutoAppExpirationEnabled(enabled = true)
setAutoAppExpirationDate(dateStringAfterToday())
- activityTestRule.launchActivity(null)
- testCoroutineDispatchers.advanceUntilIdle()
-
- // App deprecation is enabled, but this app hasn't yet expired.
- intended(hasComponent(OnboardingActivity::class.java.name))
+ launchSplashActivityFully {
+ // App deprecation is enabled, but this app hasn't yet expired.
+ intended(hasComponent(OnboardingActivity::class.java.name))
+ }
}
@Test
- fun testOpenApp_initial_expirationEnabled_afterExpDate_intentsToDeprecationDialog() {
+ fun testOpenApp_initial_expirationEnabled_afterExpDate_showsDeprecationDialog() {
initializeTestApplication()
setAutoAppExpirationEnabled(enabled = true)
setAutoAppExpirationDate(dateStringBeforeToday())
- activityTestRule.launchActivity(null)
- testCoroutineDispatchers.advanceUntilIdle()
-
- // The current app is expired.
- onView(withText(R.string.unsupported_app_version_dialog_title))
- .inRoot(isDialog())
- .check(matches(isDisplayed()))
+ launchSplashActivityFully {
+ // The current app is expired.
+ onView(withText(R.string.unsupported_app_version_dialog_title))
+ .inRoot(isDialog())
+ .check(matches(isDisplayed()))
+ }
}
@Test
@@ -212,61 +219,60 @@ class SplashActivityTest {
initializeTestApplication()
setAutoAppExpirationEnabled(enabled = true)
setAutoAppExpirationDate(dateStringBeforeToday())
- activityTestRule.launchActivity(null)
- testCoroutineDispatchers.advanceUntilIdle()
- onView(withText(R.string.unsupported_app_version_dialog_close_button_text))
- .inRoot(isDialog())
- .perform(click())
- testCoroutineDispatchers.advanceUntilIdle()
+ launchSplashActivityFully { scenario ->
+ onView(withText(R.string.unsupported_app_version_dialog_close_button_text))
+ .inRoot(isDialog())
+ .perform(click())
+ testCoroutineDispatchers.advanceUntilIdle()
- // Closing the dialog should close the activity (and thus, the app).
- assertThat(activityTestRule.activity.isFinishing).isTrue()
+ scenario.onActivity { activity ->
+ // Closing the dialog should close the activity (and thus, the app).
+ assertThat(activity.isFinishing).isTrue()
+ }
+ }
}
@Test
- fun testOpenApp_initial_expirationDisabled_afterExpDate_intentsToOnboardingFlow() {
+ fun testOpenApp_initial_expirationDisabled_afterExpDate_showsOnboardingFlow() {
initializeTestApplication()
setAutoAppExpirationEnabled(enabled = false)
setAutoAppExpirationDate(dateStringBeforeToday())
- activityTestRule.launchActivity(null)
- testCoroutineDispatchers.advanceUntilIdle()
-
- // The app is technically deprecated, but because the deprecation check is disabled the
- // onboarding flow should be shown, instead.
- intended(hasComponent(OnboardingActivity::class.java.name))
+ launchSplashActivityFully {
+ // The app is technically deprecated, but because the deprecation check is disabled the
+ // onboarding flow should be shown, instead.
+ intended(hasComponent(OnboardingActivity::class.java.name))
+ }
}
@Test
- fun testOpenApp_reopen_onboarded_expirationEnabled_beforeExpDate_intentsToProfileChooser() {
+ fun testOpenApp_reopen_onboarded_expirationEnabled_beforeExpDate_routesToProfileChooser() {
simulateAppAlreadyOnboarded()
initializeTestApplication()
setAutoAppExpirationEnabled(enabled = true)
setAutoAppExpirationDate(dateStringAfterToday())
- activityTestRule.launchActivity(null)
- testCoroutineDispatchers.advanceUntilIdle()
-
- // Reopening the app before it's expired should result in the profile activity showing since the
- // user has already been onboarded.
- intended(hasComponent(ProfileChooserActivity::class.java.name))
+ launchSplashActivityFully {
+ // Reopening the app before it's expired should result in the profile activity showing since
+ // the user has already been onboarded.
+ intended(hasComponent(ProfileChooserActivity::class.java.name))
+ }
}
@Test
- fun testOpenApp_reopen_onboarded_expirationEnabled_afterExpDate_intentsToDeprecationDialog() {
+ fun testOpenApp_reopen_onboarded_expirationEnabled_afterExpDate_showsToDeprecationDialog() {
simulateAppAlreadyOnboarded()
initializeTestApplication()
setAutoAppExpirationEnabled(enabled = true)
setAutoAppExpirationDate(dateStringBeforeToday())
- activityTestRule.launchActivity(null)
- testCoroutineDispatchers.advanceUntilIdle()
-
- // Reopening the app after it expires should prevent further access.
- onView(withText(R.string.unsupported_app_version_dialog_title))
- .inRoot(isDialog())
- .check(matches(isDisplayed()))
+ launchSplashActivityFully {
+ // Reopening the app after it expires should prevent further access.
+ onView(withText(R.string.unsupported_app_version_dialog_title))
+ .inRoot(isDialog())
+ .check(matches(isDisplayed()))
+ }
}
@Test
@@ -275,20 +281,19 @@ class SplashActivityTest {
initializeTestApplication()
forceDefaultLocale(Locale.ENGLISH)
- activityTestRule.launchActivity(null)
- testCoroutineDispatchers.advanceUntilIdle()
-
- // Verify that the locale is initialized (i.e. getDisplayLocale doesn't throw an exception) &
- // that the correct display locale is defined per the system locale.
- val displayLocale = appLanguageLocaleHandler.getDisplayLocale()
- val context = displayLocale.localeContext
- assertThat(context.languageDefinition.language).isEqualTo(ENGLISH)
- assertThat(context.languageDefinition.minAndroidSdkVersion).isEqualTo(1)
- assertThat(context.languageDefinition.appStringId.ietfBcp47Id.ietfLanguageTag).isEqualTo("en")
- assertThat(context.hasFallbackLanguageDefinition()).isFalse()
- assertThat(context.regionDefinition.region).isEqualTo(OppiaRegion.REGION_UNSPECIFIED)
- assertThat(context.regionDefinition.regionId.ietfRegionTag).isEqualTo("")
- assertThat(context.usageMode).isEqualTo(OppiaLocaleContext.LanguageUsageMode.APP_STRINGS)
+ launchSplashActivityFully {
+ // Verify that the locale is initialized (i.e. getDisplayLocale doesn't throw an exception) &
+ // that the correct display locale is defined per the system locale.
+ val displayLocale = appLanguageLocaleHandler.getDisplayLocale()
+ val context = displayLocale.localeContext
+ assertThat(context.languageDefinition.language).isEqualTo(ENGLISH)
+ assertThat(context.languageDefinition.minAndroidSdkVersion).isEqualTo(1)
+ assertThat(context.languageDefinition.appStringId.ietfBcp47Id.ietfLanguageTag).isEqualTo("en")
+ assertThat(context.hasFallbackLanguageDefinition()).isFalse()
+ assertThat(context.regionDefinition.region).isEqualTo(OppiaRegion.REGION_UNSPECIFIED)
+ assertThat(context.regionDefinition.regionId.ietfRegionTag).isEqualTo("")
+ assertThat(context.usageMode).isEqualTo(OppiaLocaleContext.LanguageUsageMode.APP_STRINGS)
+ }
}
@Test
@@ -297,14 +302,13 @@ class SplashActivityTest {
initializeTestApplication()
forceDefaultLocale(EGYPT_ARABIC_LOCALE)
- activityTestRule.launchActivity(null)
- testCoroutineDispatchers.advanceUntilIdle()
-
- // Verify that the locale is initialized (i.e. getDisplayLocale doesn't throw an exception) &
- // that the correct display locale is defined per the system locale.
- val displayLocale = appLanguageLocaleHandler.getDisplayLocale()
- val context = displayLocale.localeContext
- assertThat(context.languageDefinition.language).isEqualTo(ARABIC)
+ launchSplashActivityFully {
+ // Verify that the locale is initialized (i.e. getDisplayLocale doesn't throw an exception) &
+ // that the correct display locale is defined per the system locale.
+ val displayLocale = appLanguageLocaleHandler.getDisplayLocale()
+ val context = displayLocale.localeContext
+ assertThat(context.languageDefinition.language).isEqualTo(ARABIC)
+ }
}
@Test
@@ -313,14 +317,13 @@ class SplashActivityTest {
initializeTestApplication()
forceDefaultLocale(BRAZIL_PORTUGUESE_LOCALE)
- activityTestRule.launchActivity(null)
- testCoroutineDispatchers.advanceUntilIdle()
-
- // Verify that the locale is initialized (i.e. getDisplayLocale doesn't throw an exception) &
- // that the correct display locale is defined per the system locale.
- val displayLocale = appLanguageLocaleHandler.getDisplayLocale()
- val context = displayLocale.localeContext
- assertThat(context.languageDefinition.language).isEqualTo(BRAZILIAN_PORTUGUESE)
+ launchSplashActivityFully {
+ // Verify that the locale is initialized (i.e. getDisplayLocale doesn't throw an exception) &
+ // that the correct display locale is defined per the system locale.
+ val displayLocale = appLanguageLocaleHandler.getDisplayLocale()
+ val context = displayLocale.localeContext
+ assertThat(context.languageDefinition.language).isEqualTo(BRAZILIAN_PORTUGUESE)
+ }
}
@Test
@@ -328,73 +331,701 @@ class SplashActivityTest {
initializeTestApplication()
forceDefaultLocale(TURKEY_TURKISH_LOCALE)
- activityTestRule.launchActivity(null)
- testCoroutineDispatchers.advanceUntilIdle()
-
- // Verify that the context is the default state (due to the unsupported locale).
- val displayLocale = appLanguageLocaleHandler.getDisplayLocale()
- val languageDefinition = displayLocale.localeContext.languageDefinition
- assertThat(languageDefinition.language).isEqualTo(LANGUAGE_UNSPECIFIED)
- assertThat(languageDefinition.minAndroidSdkVersion).isEqualTo(1)
- assertThat(languageDefinition.appStringId.ietfBcp47Id.ietfLanguageTag).isEqualTo("tr-TR")
+ launchSplashActivityFully {
+ // Verify that the context is the default state (due to the unsupported locale).
+ val displayLocale = appLanguageLocaleHandler.getDisplayLocale()
+ val languageDefinition = displayLocale.localeContext.languageDefinition
+ assertThat(languageDefinition.language).isEqualTo(LANGUAGE_UNSPECIFIED)
+ assertThat(languageDefinition.minAndroidSdkVersion).isEqualTo(1)
+ assertThat(languageDefinition.appStringId.ietfBcp47Id.ietfLanguageTag).isEqualTo("tr-TR")
+ }
}
@Test
- @RunOn(TestPlatform.ROBOLECTRIC)
+ @RunOn(TestPlatform.ROBOLECTRIC, buildEnvironments = [BuildEnvironment.BAZEL])
fun testSplashActivity_initializationFailure_initializesLocaleHandlerWithDefaultContext() {
corruptCacheFile()
initializeTestApplication()
- activityTestRule.launchActivity(null)
- testCoroutineDispatchers.advanceUntilIdle()
-
- // Verify that the context is the default state (due to the unsupported locale).
- val displayLocale = appLanguageLocaleHandler.getDisplayLocale()
- val context = displayLocale.localeContext
- assertThat(context.languageDefinition.language).isEqualTo(ENGLISH)
- assertThat(context.languageDefinition.minAndroidSdkVersion).isEqualTo(1)
- assertThat(context.languageDefinition.appStringId.ietfBcp47Id.ietfLanguageTag).isEqualTo("en")
- assertThat(context.hasFallbackLanguageDefinition()).isFalse()
- assertThat(context.regionDefinition.region).isEqualTo(OppiaRegion.UNITED_STATES)
- assertThat(context.regionDefinition.regionId.ietfRegionTag).isEqualTo("US")
- assertThat(context.usageMode).isEqualTo(OppiaLocaleContext.LanguageUsageMode.APP_STRINGS)
+ launchSplashActivityFully {
+ // Verify that the context is the default state (due to the unsupported locale).
+ val displayLocale = appLanguageLocaleHandler.getDisplayLocale()
+ val context = displayLocale.localeContext
+ assertThat(context.languageDefinition.language).isEqualTo(ENGLISH)
+ assertThat(context.languageDefinition.minAndroidSdkVersion).isEqualTo(1)
+ assertThat(context.languageDefinition.appStringId.ietfBcp47Id.ietfLanguageTag).isEqualTo("en")
+ assertThat(context.hasFallbackLanguageDefinition()).isFalse()
+ assertThat(context.regionDefinition.region).isEqualTo(OppiaRegion.UNITED_STATES)
+ assertThat(context.regionDefinition.regionId.ietfRegionTag).isEqualTo("US")
+ assertThat(context.usageMode).isEqualTo(OppiaLocaleContext.LanguageUsageMode.APP_STRINGS)
+ }
}
@Test
- @RunOn(TestPlatform.ROBOLECTRIC)
- fun testSplashActivity_initializationFailure_logsError() {
- // Simulate a corrupted cache file to trigger an initialization failure.
+ fun testSplashActivity_initializationFailure_routesToOnboardingActivity() {
corruptCacheFile()
initializeTestApplication()
- activityTestRule.launchActivity(null)
- testCoroutineDispatchers.advanceUntilIdle()
-
- val logs = getShadowLogsOnRobolectric()
- assertThat(logs.any { it.contains("Failed to compute initial state") }).isTrue()
+ launchSplashActivityFully {
+ // Verify that an initialization failure leads to the onboarding activity by default.
+ intended(hasComponent(OnboardingActivity::class.java.name))
+ }
}
@Test
- fun testSplashActivity_initializationFailure_routesToOnboardingActivity() {
- corruptCacheFile()
+ fun testSplashActivity_hasCorrectActivityLabel() {
initializeTestApplication()
- activityTestRule.launchActivity(null)
- testCoroutineDispatchers.advanceUntilIdle()
+ launchSplashActivityFully { scenario ->
+ scenario.onActivity { activity ->
+ val title = activity.title
- // Verify that an initialization failure leads to the onboarding activity by default.
- intended(hasComponent(OnboardingActivity::class.java.name))
+ assertThat(title).isEqualTo(context.getString(R.string.app_name))
+ }
+ }
}
@Test
- fun testSplashActivity_hasCorrectActivityLabel() {
- initializeTestApplication()
+ fun testSplashActivity_newUser_firstTimeOpeningBetaFlavor_doesNotShowBetaNotice() {
+ initializeTestApplicationWithFlavor(BuildFlavor.BETA)
- activityTestRule.launchActivity(null)
- testCoroutineDispatchers.advanceUntilIdle()
+ launchSplashActivityFully {
+ // Verify that the beta notice does not open (since there wasn't a version change).
+ onView(withId(R.id.beta_notice_dialog_message)).check(doesNotExist())
+ }
+ }
+
+ @Test
+ @RunParameterized(
+ Iteration("testing_to_beta", "firstOpen=TESTING", "secondOpen=BETA"),
+ Iteration("dev_to_beta", "firstOpen=DEVELOPER", "secondOpen=BETA"),
+ Iteration("alpha_to_beta", "firstOpen=ALPHA", "secondOpen=BETA"),
+ Iteration("ga_to_beta", "firstOpen=GENERAL_AVAILABILITY", "secondOpen=BETA")
+ )
+ fun testSplashActivity_newUser_betaFlavorTransitions_showsBetaNotice() {
+ simulateAppAlreadyOpenedWithFlavor(firstOpenFlavor)
+
+ initializeTestApplicationWithFlavor(secondOpenFlavor)
+
+ launchSplashActivityFully {
+ onDialogView(withText(R.string.beta_notice_dialog_title)).check(matches(isDisplayed()))
+ onDialogView(withId(R.id.beta_notice_dialog_message)).check(matches(isDisplayed()))
+ }
+ }
+
+ @Test
+ @RunParameterized(
+ Iteration("testing_to_beta", "firstOpen=TESTING", "secondOpen=BETA"),
+ Iteration("dev_to_beta", "firstOpen=DEVELOPER", "secondOpen=BETA"),
+ Iteration("alpha_to_beta", "firstOpen=ALPHA", "secondOpen=BETA"),
+ Iteration("ga_to_beta", "firstOpen=GENERAL_AVAILABILITY", "secondOpen=BETA")
+ )
+ fun testSplashActivity_newUser_betaFlavorTransitions_closeNotice_routesToOnboardingFlow() {
+ simulateAppAlreadyOpenedWithFlavor(firstOpenFlavor)
+ initializeTestApplicationWithFlavor(secondOpenFlavor)
+
+ launchSplashActivityFully {
+ // Close the notice.
+ onDialogView(withText(R.string.beta_notice_dialog_close_button_text)).perform(click())
+ testCoroutineDispatchers.runCurrent()
+
+ // The user should be routed to the onboarding flow after seeing the beta notice.
+ intended(hasComponent(OnboardingActivity::class.java.name))
+ }
+ }
+
+ @Test
+ @RunParameterized(
+ Iteration("testing_to_beta", "firstOpen=TESTING", "secondOpen=BETA"),
+ Iteration("dev_to_beta", "firstOpen=DEVELOPER", "secondOpen=BETA"),
+ Iteration("alpha_to_beta", "firstOpen=ALPHA", "secondOpen=BETA"),
+ Iteration("ga_to_beta", "firstOpen=GENERAL_AVAILABILITY", "secondOpen=BETA")
+ )
+ fun testSplashActivity_newUser_betaFlavorTransitions_doNotShowAgain_routesToOnboardingFlow() {
+ simulateAppAlreadyOpenedWithFlavor(firstOpenFlavor)
+ initializeTestApplicationWithFlavor(secondOpenFlavor)
+
+ launchSplashActivityFully {
+ // Close the notice after selecting to never show it again.
+ onDialogView(withId(R.id.beta_notice_dialog_preference_checkbox)).perform(click())
+ onDialogView(withText(R.string.beta_notice_dialog_close_button_text)).perform(click())
+ testCoroutineDispatchers.runCurrent()
+
+ // The user should be routed to the onboarding flow after seeing the beta notice.
+ intended(hasComponent(OnboardingActivity::class.java.name))
+ }
+ }
+
+ @Test
+ fun testSplashActivity_newUser_dismissBetaNotice_reopenApp_doesNotShowNotice() {
+ // Open the app in beta notice mode, then dismiss the notice.
+ simulateAppAlreadyOpenedWithFlavor(BuildFlavor.ALPHA)
+ initializeTestApplicationWithFlavor(BuildFlavor.BETA)
+ launchSplashActivityFully {
+ onDialogView(withText(R.string.beta_notice_dialog_close_button_text)).perform(click())
+ testCoroutineDispatchers.runCurrent()
+ }
+
+ // Note this is a different "recreation" than other tests since the same instrumentation
+ // process needs to be preserved for Espresso to work correctly.
+ recreateExistingApplication()
+
+ launchSplashActivityFully {
+ // The user should be routed to the onboarding flow after seeing the beta notice.
+ onView(withId(R.id.beta_notice_dialog_message)).check(doesNotExist())
+ intended(hasComponent(OnboardingActivity::class.java.name))
+ }
+ }
+
+ @Test
+ fun testSplashActivity_newUser_dismissBetaNotice_retriggerNotice_showsBetaNotice() {
+ // Open the app in beta notice mode, then dismiss the notice.
+ simulateAppAlreadyOpenedWithFlavor(BuildFlavor.ALPHA)
+ initializeTestApplicationWithFlavor(BuildFlavor.BETA)
+ launchSplashActivityFully {
+ onDialogView(withText(R.string.beta_notice_dialog_close_button_text)).perform(click())
+ testCoroutineDispatchers.runCurrent()
+ }
+
+ // "Retrigger" the notice by switching flavors again, then "recreate" the existing application
+ // so that new states can be observed.
+ simulateAppAlreadyOpenedWithFlavor(BuildFlavor.ALPHA)
+ recreateExistingApplicationWithFlavor(BuildFlavor.BETA)
+
+ launchSplashActivityFully {
+ // The user should see the beta notice again despite dismissing it since the beta notice
+ // condition again occurred.
+ onDialogView(withText(R.string.beta_notice_dialog_title)).check(matches(isDisplayed()))
+ onDialogView(withId(R.id.beta_notice_dialog_message)).check(matches(isDisplayed()))
+ }
+ }
+
+ @Test
+ fun testSplashActivity_newUser_dismissBetaNoticeForever_retriggerNotice_doesNotShowNotice() {
+ // Open the app in beta notice mode, then dismiss the notice permanently.
+ simulateAppAlreadyOpenedWithFlavor(BuildFlavor.ALPHA)
+ initializeTestApplicationWithFlavor(BuildFlavor.BETA)
+ launchSplashActivityFully {
+ onDialogView(withId(R.id.beta_notice_dialog_preference_checkbox)).perform(click())
+ onDialogView(withText(R.string.beta_notice_dialog_close_button_text)).perform(click())
+ testCoroutineDispatchers.runCurrent()
+ }
+
+ // "Retrigger" the notice by switching flavors again, then "recreate" the existing application
+ // so that new states can be observed.
+ simulateAppAlreadyOpenedWithFlavor(BuildFlavor.ALPHA)
+ recreateExistingApplicationWithFlavor(BuildFlavor.BETA)
+
+ launchSplashActivityFully {
+ // The user should not see the beta notice again even though they changed flavors since they
+ // opted to permanently disable the notice.
+ onView(withId(R.id.beta_notice_dialog_message)).check(doesNotExist())
+ intended(hasComponent(OnboardingActivity::class.java.name))
+ }
+ }
+
+ @Test
+ fun testSplashActivity_newUser_firstTimeOpeningGaFlavor_doesNotShowGaUpgradeNotice() {
+ initializeTestApplicationWithFlavor(BuildFlavor.GENERAL_AVAILABILITY)
+
+ launchSplashActivityFully {
+ // Verify that the GA notice does not open (since there wasn't an upgrade).
+ onView(withId(R.id.ga_update_notice_dialog_message)).check(doesNotExist())
+ }
+ }
+
+ @Test
+ @RunParameterized(
+ Iteration("alpha_to_ga", "firstOpen=ALPHA", "secondOpen=GENERAL_AVAILABILITY"),
+ Iteration("beta_to_ga", "firstOpen=BETA", "secondOpen=GENERAL_AVAILABILITY")
+ )
+ fun testSplashActivity_onboarded_gaFlavorTransitions_showsGaUpgradeNotice() {
+ simulateAppAlreadyOnboardedWithFlavor(firstOpenFlavor)
+
+ initializeTestApplicationWithFlavor(secondOpenFlavor)
+
+ launchSplashActivityFully {
+ onDialogView(withText(R.string.general_availability_notice_dialog_title))
+ .check(matches(isDisplayed()))
+ onDialogView(withId(R.id.ga_update_notice_dialog_message)).check(matches(isDisplayed()))
+ }
+ }
+
+ @Test
+ @RunParameterized(
+ Iteration("alpha_to_ga", "firstOpen=ALPHA", "secondOpen=GENERAL_AVAILABILITY"),
+ Iteration("beta_to_ga", "firstOpen=BETA", "secondOpen=GENERAL_AVAILABILITY")
+ )
+ fun testSplashActivity_onboarded_gaFlavorTransitions_closeNotice_routesToProfileChooser() {
+ simulateAppAlreadyOnboardedWithFlavor(firstOpenFlavor)
+ initializeTestApplicationWithFlavor(secondOpenFlavor)
+
+ launchSplashActivityFully {
+ // Close the notice.
+ onDialogView(withText(R.string.general_availability_notice_dialog_close_button_text))
+ .perform(click())
+ testCoroutineDispatchers.runCurrent()
+
+ // The user should be routed to the profile chooser after seeing the GA upgrade notice.
+ intended(hasComponent(ProfileChooserActivity::class.java.name))
+ }
+ }
+
+ @Test
+ @RunParameterized(
+ Iteration("alpha_to_ga", "firstOpen=ALPHA", "secondOpen=GENERAL_AVAILABILITY"),
+ Iteration("beta_to_ga", "firstOpen=BETA", "secondOpen=GENERAL_AVAILABILITY")
+ )
+ fun testSplashActivity_onboarded_gaFlavorTransitions_doNotShowAgain_routesToProfileChooser() {
+ simulateAppAlreadyOnboardedWithFlavor(firstOpenFlavor)
+ initializeTestApplicationWithFlavor(secondOpenFlavor)
+
+ launchSplashActivityFully {
+ // Close the notice after selecting to never show it again.
+ onDialogView(withId(R.id.ga_update_notice_dialog_preference_checkbox)).perform(click())
+ onDialogView(withText(R.string.general_availability_notice_dialog_close_button_text))
+ .perform(click())
+ testCoroutineDispatchers.runCurrent()
+
+ // The user should be routed to the profile chooser after seeing the GA upgrade notice.
+ intended(hasComponent(ProfileChooserActivity::class.java.name))
+ }
+ }
+
+ @Test
+ fun testSplashActivity_onboarded_dismissGaNotice_reopenApp_doesNotShowNotice() {
+ // Open the app in GA upgrade mode, then dismiss the notice.
+ simulateAppAlreadyOnboardedWithFlavor(BuildFlavor.BETA)
+ initializeTestApplicationWithFlavor(BuildFlavor.GENERAL_AVAILABILITY)
+ launchSplashActivityFully {
+ onDialogView(withText(R.string.general_availability_notice_dialog_close_button_text))
+ .perform(click())
+ testCoroutineDispatchers.runCurrent()
+ }
+
+ // Note this is a different "recreation" than other tests since the same instrumentation
+ // process needs to be preserved for Espresso to work correctly.
+ recreateExistingApplication()
+
+ launchSplashActivityFully {
+ // The user should be routed to the profile chooser after seeing the GA upgrade notice.
+ onView(withId(R.id.ga_update_notice_dialog_message)).check(doesNotExist())
+ intended(hasComponent(ProfileChooserActivity::class.java.name))
+ }
+ }
+
+ @Test
+ fun testSplashActivity_onboarded_dismissGaNotice_retriggerNotice_showsGaNotice() {
+ // Open the app in GA upgrade mode, then dismiss the notice.
+ simulateAppAlreadyOpenedWithFlavor(BuildFlavor.ALPHA)
+ initializeTestApplicationWithFlavor(BuildFlavor.BETA)
+ launchSplashActivityFully {
+ onDialogView(withText(R.string.general_availability_notice_dialog_close_button_text))
+ .perform(click())
+ testCoroutineDispatchers.runCurrent()
+ }
+
+ // "Retrigger" the notice by switching flavors again, then "recreate" the existing application
+ // so that new states can be observed.
+ simulateAppAlreadyOpenedWithFlavor(BuildFlavor.ALPHA)
+ recreateExistingApplicationWithFlavor(BuildFlavor.GENERAL_AVAILABILITY)
+
+ launchSplashActivityFully {
+ // The user should see the GA upgrade notice again despite dismissing it since the notice
+ // condition again occurred.
+ onDialogView(withText(R.string.general_availability_notice_dialog_title))
+ .check(matches(isDisplayed()))
+ onDialogView(withId(R.id.ga_update_notice_dialog_message)).check(matches(isDisplayed()))
+ }
+ }
+
+ @Test
+ fun testSplashActivity_onboarded_dismissGaNoticeForever_retriggerNotice_doesNotShowNotice() {
+ // Open the app in GA upgrade mode, then dismiss the notice permanently.
+ simulateAppAlreadyOpenedWithFlavor(BuildFlavor.BETA)
+ initializeTestApplicationWithFlavor(BuildFlavor.GENERAL_AVAILABILITY)
+ launchSplashActivityFully {
+ onDialogView(withId(R.id.ga_update_notice_dialog_preference_checkbox)).perform(click())
+ onDialogView(withText(R.string.general_availability_notice_dialog_close_button_text))
+ .perform(click())
+ testCoroutineDispatchers.runCurrent()
+ }
+
+ // "Retrigger" the notice by switching flavors again, then "recreate" the existing application
+ // so that new states can be observed.
+ simulateAppAlreadyOpenedWithFlavor(BuildFlavor.ALPHA)
+ recreateExistingApplicationWithFlavor(BuildFlavor.GENERAL_AVAILABILITY)
+
+ launchSplashActivityFully {
+ // The user should not see the GA upgrade notice again even though they changed flavors since
+ // they opted to permanently disable the notice.
+ onView(withId(R.id.ga_update_notice_dialog_message)).check(doesNotExist())
+ intended(hasComponent(OnboardingActivity::class.java.name))
+ }
+ }
+
+ @Test
+ fun testSplashActivity_newUser_betaNoticeConditionsThenGa_showsGaNotice() {
+ // Simulate a beta notice first.
+ simulateAppAlreadyOpenedWithFlavor(BuildFlavor.ALPHA)
+ simulateAppAlreadyOpenedWithFlavor(BuildFlavor.BETA)
+
+ // Then simulate the GA upgrade notice.
+ initializeTestApplicationWithFlavor(BuildFlavor.GENERAL_AVAILABILITY)
+
+ // The GA upgrade notice should be the one to show since it's more recent.
+ launchSplashActivityFully {
+ onDialogView(withText(R.string.general_availability_notice_dialog_title))
+ .check(matches(isDisplayed()))
+ onDialogView(withId(R.id.ga_update_notice_dialog_message)).check(matches(isDisplayed()))
+ }
+ }
+
+ @Test
+ fun testSplashActivity_newUser_betaNoticeConditionsThenGa_gaDisabled_showsNoNotice() {
+ // First, disable the GA notice, then trigger a beta notice.
+ simulateAppAlreadyOpenedWithFlavor(BuildFlavor.ALPHA)
+ initializeTestApplicationWithFlavor(BuildFlavor.GENERAL_AVAILABILITY)
+ launchSplashActivityFully {
+ onDialogView(withId(R.id.ga_update_notice_dialog_preference_checkbox)).perform(click())
+ onDialogView(withText(R.string.general_availability_notice_dialog_close_button_text))
+ .perform(click())
+ testCoroutineDispatchers.runCurrent()
+ }
+ reopenAppWithNewFlavor(BuildFlavor.BETA)
+
+ // Then simulate the GA upgrade notice.
+ reopenAppWithNewFlavor(BuildFlavor.GENERAL_AVAILABILITY)
- val title = activityTestRule.activity.title
- assertThat(title).isEqualTo(context.getString(R.string.app_name))
+ // No notice should show since the GA upgrade notice would normally show, but it's been
+ // permanently disabled.
+ launchSplashActivityFully {
+ onView(withId(R.id.beta_notice_dialog_message)).check(doesNotExist())
+ onView(withId(R.id.ga_update_notice_dialog_message)).check(doesNotExist())
+ }
+ }
+
+ @Test
+ fun testSplashActivity_newUser_gaNoticeConditionsThenBeta_showsBetaNotice() {
+ // Simulate a GA upgrade notice first.
+ simulateAppAlreadyOpenedWithFlavor(BuildFlavor.BETA)
+ simulateAppAlreadyOpenedWithFlavor(BuildFlavor.GENERAL_AVAILABILITY)
+
+ // Then simulate the beta notice.
+ initializeTestApplicationWithFlavor(BuildFlavor.BETA)
+
+ // The beta notice should be the one to show since it's more recent.
+ launchSplashActivityFully {
+ onDialogView(withText(R.string.beta_notice_dialog_title)).check(matches(isDisplayed()))
+ onDialogView(withId(R.id.beta_notice_dialog_message)).check(matches(isDisplayed()))
+ }
+ }
+
+ @Test
+ fun testSplashActivity_newUser_gaNoticeConditionsThenBeta_betaDisabled_showsNoNotice() {
+ // First, disable the beta notice, then trigger a GA upgrade notice.
+ simulateAppAlreadyOpenedWithFlavor(BuildFlavor.ALPHA)
+ initializeTestApplicationWithFlavor(BuildFlavor.BETA)
+ launchSplashActivityFully {
+ onDialogView(withId(R.id.beta_notice_dialog_preference_checkbox)).perform(click())
+ onDialogView(withText(R.string.beta_notice_dialog_close_button_text)).perform(click())
+ testCoroutineDispatchers.runCurrent()
+ }
+ reopenAppWithNewFlavor(BuildFlavor.GENERAL_AVAILABILITY)
+
+ // Then simulate the beta notice.
+ reopenAppWithNewFlavor(BuildFlavor.BETA)
+
+ // No notice should show since the beta notice would normally show, but it's been permanently
+ // disabled.
+ launchSplashActivityFully {
+ onView(withId(R.id.beta_notice_dialog_message)).check(doesNotExist())
+ onView(withId(R.id.ga_update_notice_dialog_message)).check(doesNotExist())
+ }
+ }
+
+ @Test
+ @RunParameterized(
+ Iteration("testing_to_testing", "firstOpen=TESTING", "secondOpen=TESTING"),
+ Iteration("testing_to_dev", "firstOpen=TESTING", "secondOpen=DEVELOPER"),
+ Iteration("testing_to_alpha", "firstOpen=TESTING", "secondOpen=ALPHA"),
+ Iteration("testing_to_ga", "firstOpen=TESTING", "secondOpen=GENERAL_AVAILABILITY"),
+ Iteration("dev_to_testing", "firstOpen=DEVELOPER", "secondOpen=TESTING"),
+ Iteration("dev_to_dev", "firstOpen=DEVELOPER", "secondOpen=DEVELOPER"),
+ Iteration("dev_to_alpha", "firstOpen=DEVELOPER", "secondOpen=ALPHA"),
+ Iteration("dev_to_ga", "firstOpen=DEVELOPER", "secondOpen=GENERAL_AVAILABILITY"),
+ Iteration("alpha_to_testing", "firstOpen=ALPHA", "secondOpen=TESTING"),
+ Iteration("alpha_to_dev", "firstOpen=ALPHA", "secondOpen=DEVELOPER"),
+ Iteration("alpha_to_alpha", "firstOpen=ALPHA", "secondOpen=ALPHA"),
+ Iteration("beta_to_testing", "firstOpen=BETA", "secondOpen=TESTING"),
+ Iteration("beta_to_dev", "firstOpen=BETA", "secondOpen=DEVELOPER"),
+ Iteration("beta_to_alpha", "firstOpen=BETA", "secondOpen=ALPHA"),
+ Iteration("beta_to_beta", "firstOpen=BETA", "secondOpen=BETA"),
+ Iteration("ga_to_testing", "firstOpen=GENERAL_AVAILABILITY", "secondOpen=TESTING"),
+ Iteration("ga_to_dev", "firstOpen=GENERAL_AVAILABILITY", "secondOpen=DEVELOPER"),
+ Iteration("ga_to_alpha", "firstOpen=GENERAL_AVAILABILITY", "secondOpen=ALPHA"),
+ Iteration("ga_to_ga", "firstOpen=GENERAL_AVAILABILITY", "secondOpen=GENERAL_AVAILABILITY")
+ )
+ fun testSplashActivity_newUser_ignoredFlavorTransitions_routesToOnboardingFlow() {
+ simulateAppAlreadyOpenedWithFlavor(firstOpenFlavor)
+
+ initializeTestApplicationWithFlavor(secondOpenFlavor)
+
+ launchSplashActivityFully {
+ // The user should be immediately routed to the onboarding flow since this flavor transition
+ // does not trigger a notice.
+ intended(hasComponent(OnboardingActivity::class.java.name))
+ }
+ }
+
+ @Test
+ @RunParameterized(
+ Iteration("testing_to_testing", "firstOpen=TESTING", "secondOpen=TESTING"),
+ Iteration("testing_to_dev", "firstOpen=TESTING", "secondOpen=DEVELOPER"),
+ Iteration("testing_to_alpha", "firstOpen=TESTING", "secondOpen=ALPHA"),
+ Iteration("testing_to_ga", "firstOpen=TESTING", "secondOpen=GENERAL_AVAILABILITY"),
+ Iteration("dev_to_testing", "firstOpen=DEVELOPER", "secondOpen=TESTING"),
+ Iteration("dev_to_dev", "firstOpen=DEVELOPER", "secondOpen=DEVELOPER"),
+ Iteration("dev_to_alpha", "firstOpen=DEVELOPER", "secondOpen=ALPHA"),
+ Iteration("dev_to_ga", "firstOpen=DEVELOPER", "secondOpen=GENERAL_AVAILABILITY"),
+ Iteration("alpha_to_testing", "firstOpen=ALPHA", "secondOpen=TESTING"),
+ Iteration("alpha_to_dev", "firstOpen=ALPHA", "secondOpen=DEVELOPER"),
+ Iteration("alpha_to_alpha", "firstOpen=ALPHA", "secondOpen=ALPHA"),
+ Iteration("beta_to_testing", "firstOpen=BETA", "secondOpen=TESTING"),
+ Iteration("beta_to_dev", "firstOpen=BETA", "secondOpen=DEVELOPER"),
+ Iteration("beta_to_alpha", "firstOpen=BETA", "secondOpen=ALPHA"),
+ Iteration("beta_to_beta", "firstOpen=BETA", "secondOpen=BETA"),
+ Iteration("ga_to_testing", "firstOpen=GENERAL_AVAILABILITY", "secondOpen=TESTING"),
+ Iteration("ga_to_dev", "firstOpen=GENERAL_AVAILABILITY", "secondOpen=DEVELOPER"),
+ Iteration("ga_to_alpha", "firstOpen=GENERAL_AVAILABILITY", "secondOpen=ALPHA"),
+ Iteration("ga_to_ga", "firstOpen=GENERAL_AVAILABILITY", "secondOpen=GENERAL_AVAILABILITY")
+ )
+ fun testSplashActivity_onboarded_ignoredFlavorTransitions_routesToProfileChooser() {
+ simulateAppAlreadyOnboardedWithFlavor(firstOpenFlavor)
+
+ initializeTestApplicationWithFlavor(secondOpenFlavor)
+
+ launchSplashActivityFully {
+ // The user should be immediately routed to the profile chooser since this flavor transition
+ // does not trigger a notice.
+ intended(hasComponent(ProfileChooserActivity::class.java.name))
+ }
+ }
+
+ @Test
+ @RunParameterized(
+ Iteration("testing_to_testing", "firstOpen=TESTING", "secondOpen=TESTING"),
+ Iteration("testing_to_dev", "firstOpen=TESTING", "secondOpen=DEVELOPER"),
+ Iteration("testing_to_alpha", "firstOpen=TESTING", "secondOpen=ALPHA"),
+ Iteration("testing_to_beta", "firstOpen=TESTING", "secondOpen=BETA"),
+ Iteration("testing_to_ga", "firstOpen=TESTING", "secondOpen=GENERAL_AVAILABILITY"),
+ Iteration("dev_to_testing", "firstOpen=DEVELOPER", "secondOpen=TESTING"),
+ Iteration("dev_to_dev", "firstOpen=DEVELOPER", "secondOpen=DEVELOPER"),
+ Iteration("dev_to_alpha", "firstOpen=DEVELOPER", "secondOpen=ALPHA"),
+ Iteration("dev_to_beta", "firstOpen=DEVELOPER", "secondOpen=BETA"),
+ Iteration("dev_to_ga", "firstOpen=DEVELOPER", "secondOpen=GENERAL_AVAILABILITY"),
+ Iteration("alpha_to_testing", "firstOpen=ALPHA", "secondOpen=TESTING"),
+ Iteration("alpha_to_dev", "firstOpen=ALPHA", "secondOpen=DEVELOPER"),
+ Iteration("alpha_to_alpha", "firstOpen=ALPHA", "secondOpen=ALPHA"),
+ Iteration("alpha_to_beta", "firstOpen=ALPHA", "secondOpen=BETA"),
+ Iteration("alpha_to_ga", "firstOpen=ALPHA", "secondOpen=GENERAL_AVAILABILITY"),
+ Iteration("beta_to_testing", "firstOpen=BETA", "secondOpen=TESTING"),
+ Iteration("beta_to_dev", "firstOpen=BETA", "secondOpen=DEVELOPER"),
+ Iteration("beta_to_alpha", "firstOpen=BETA", "secondOpen=ALPHA"),
+ Iteration("beta_to_beta", "firstOpen=BETA", "secondOpen=BETA"),
+ Iteration("beta_to_ga", "firstOpen=BETA", "secondOpen=GENERAL_AVAILABILITY"),
+ Iteration("ga_to_testing", "firstOpen=GENERAL_AVAILABILITY", "secondOpen=TESTING"),
+ Iteration("ga_to_dev", "firstOpen=GENERAL_AVAILABILITY", "secondOpen=DEVELOPER"),
+ Iteration("ga_to_alpha", "firstOpen=GENERAL_AVAILABILITY", "secondOpen=ALPHA"),
+ Iteration("ga_to_beta", "firstOpen=GENERAL_AVAILABILITY", "secondOpen=BETA"),
+ Iteration("ga_to_ga", "firstOpen=GENERAL_AVAILABILITY", "secondOpen=GENERAL_AVAILABILITY")
+ )
+ fun testSplashActivity_appDeprecated_allFlavorTransitions_showsDeprecationNotice() {
+ simulateAppAlreadyOnboardedWithFlavor(firstOpenFlavor)
+
+ initializeTestApplicationWithFlavor(secondOpenFlavor)
+ setAutoAppExpirationEnabled(enabled = true)
+ setAutoAppExpirationDate(dateStringBeforeToday())
+
+ // The current app is expired, so the deprecation notice should show regardless of the build
+ // flavor notices that would normally show.
+ launchSplashActivityFully {
+ onView(withText(R.string.unsupported_app_version_dialog_title))
+ .inRoot(isDialog())
+ .check(matches(isDisplayed()))
+ }
+ }
+
+ @Test
+ fun testSplashActivity_onboarded_testingFlavor_showsNoFlavorText() {
+ simulateAppAlreadyOnboardedWithFlavor(BuildFlavor.TESTING)
+
+ initializeTestApplicationWithFlavor(BuildFlavor.TESTING)
+
+ // No label should show for this version of the app since it's meant to simulate the GA flavor.
+ launchSplashActivityFully {
+ onView(withId(R.id.build_flavor_label)).check(matches(not(isDisplayed())))
+ }
+ }
+
+ @Test
+ fun testSplashActivity_onboarded_devFlavor_showsDevFlavorText() {
+ simulateAppAlreadyOnboardedWithFlavor(BuildFlavor.DEVELOPER)
+
+ initializeTestApplicationWithFlavor(BuildFlavor.DEVELOPER)
+
+ // The developer label should be showing.
+ launchSplashActivityFully {
+ onView(withId(R.id.build_flavor_label)).check(matches(isDisplayed()))
+ onView(withId(R.id.build_flavor_label))
+ .check(matches(withText(R.string.splash_screen_developer_label)))
+ }
+ }
+
+ @Test
+ fun testSplashActivity_onboarded_alphaFlavor_showsAlphaFlavorText() {
+ simulateAppAlreadyOnboardedWithFlavor(BuildFlavor.ALPHA)
+
+ initializeTestApplicationWithFlavor(BuildFlavor.ALPHA)
+
+ // The alpha label should be showing.
+ launchSplashActivityFully {
+ onView(withId(R.id.build_flavor_label)).check(matches(isDisplayed()))
+ onView(withId(R.id.build_flavor_label))
+ .check(matches(withText(R.string.splash_screen_alpha_label)))
+ }
+ }
+
+ @Test
+ fun testSplashActivity_onboarded_betaFlavor_showsBetaFlavorText() {
+ simulateAppAlreadyOnboardedWithFlavor(BuildFlavor.BETA)
+
+ initializeTestApplicationWithFlavor(BuildFlavor.BETA)
+
+ // The beta label should be showing.
+ launchSplashActivityFully {
+ onView(withId(R.id.build_flavor_label)).check(matches(isDisplayed()))
+ onView(withId(R.id.build_flavor_label))
+ .check(matches(withText(R.string.splash_screen_beta_label)))
+ }
+ }
+
+ @Test
+ fun testSplashActivity_onboarded_generalAvailabilityFlavor_showsNoFlavorText() {
+ simulateAppAlreadyOnboardedWithFlavor(BuildFlavor.GENERAL_AVAILABILITY)
+
+ initializeTestApplicationWithFlavor(BuildFlavor.GENERAL_AVAILABILITY)
+
+ // No label should show for this version of the app.
+ launchSplashActivityFully {
+ onView(withId(R.id.build_flavor_label)).check(matches(not(isDisplayed())))
+ }
+ }
+
+ @Test
+ @RunOn(TestPlatform.ROBOLECTRIC)
+ fun testSplashActivity_onboarded_testingFlavor_doesNotWaitToStart() {
+ simulateAppAlreadyOnboardedWithFlavor(BuildFlavor.TESTING)
+ initializeTestApplicationWithFlavor(BuildFlavor.TESTING)
+
+ // The profile chooser opens immediately for the testing flavor since it has no delay.
+ launchSplashActivityPartially {
+ testCoroutineDispatchers.runCurrent()
+
+ intended(hasComponent(ProfileChooserActivity::class.java.name))
+ }
+ }
+
+ @Test
+ @RunOn(TestPlatform.ROBOLECTRIC)
+ fun testSplashActivity_onboarded_devFlavor_doesNotWaitToStart() {
+ simulateAppAlreadyOnboardedWithFlavor(BuildFlavor.DEVELOPER)
+ initializeTestApplicationWithFlavor(BuildFlavor.DEVELOPER)
+
+ // The profile chooser opens immediately for the developer flavor since it has no delay.
+ launchSplashActivityPartially {
+ testCoroutineDispatchers.runCurrent()
+
+ intended(hasComponent(ProfileChooserActivity::class.java.name))
+ }
+ }
+
+ @Test
+ @RunOn(TestPlatform.ROBOLECTRIC)
+ fun testSplashActivity_onboarded_alphaFlavor_doNotWait_doesNotStart() {
+ simulateAppAlreadyOnboardedWithFlavor(BuildFlavor.ALPHA)
+ initializeTestApplicationWithFlavor(BuildFlavor.ALPHA)
+
+ // Nothing opens without waiting for the alpha startup notice to finish.
+ launchSplashActivityPartially {
+ testCoroutineDispatchers.runCurrent()
+
+ Intents.assertNoUnverifiedIntents()
+ }
+ }
+
+ @Test
+ @RunOn(TestPlatform.ROBOLECTRIC)
+ fun testSplashActivity_onboarded_alphaFlavor_waitTwoSeconds_intentsToProfileChooser() {
+ simulateAppAlreadyOnboardedWithFlavor(BuildFlavor.ALPHA)
+ initializeTestApplicationWithFlavor(BuildFlavor.ALPHA)
+
+ // The profile chooser should appear after the 2 seconds wait for the alpha splash screen.
+ launchSplashActivityPartially {
+ testCoroutineDispatchers.advanceTimeBy(TimeUnit.SECONDS.toMillis(2))
+
+ intended(hasComponent(ProfileChooserActivity::class.java.name))
+ }
+ }
+
+ @Test
+ @RunOn(TestPlatform.ROBOLECTRIC)
+ fun testSplashActivity_onboarded_betaFlavor_doNotWait_doesNotStart() {
+ simulateAppAlreadyOnboardedWithFlavor(BuildFlavor.BETA)
+ initializeTestApplicationWithFlavor(BuildFlavor.BETA)
+
+ // Nothing opens without waiting for the beta startup notice to finish.
+ launchSplashActivityPartially {
+ testCoroutineDispatchers.runCurrent()
+
+ Intents.assertNoUnverifiedIntents()
+ }
+ }
+
+ @Test
+ @RunOn(TestPlatform.ROBOLECTRIC)
+ fun testSplashActivity_onboarded_betaFlavor_waitTwoSeconds_intentsToProfileChooser() {
+ simulateAppAlreadyOnboardedWithFlavor(BuildFlavor.BETA)
+ initializeTestApplicationWithFlavor(BuildFlavor.BETA)
+
+ // The profile chooser should appear after the 2 seconds wait for the beta splash screen.
+ launchSplashActivityPartially {
+ testCoroutineDispatchers.advanceTimeBy(TimeUnit.SECONDS.toMillis(2))
+
+ intended(hasComponent(ProfileChooserActivity::class.java.name))
+ }
+ }
+
+ @Test
+ @RunOn(TestPlatform.ROBOLECTRIC)
+ fun testSplashActivity_onboarded_gaFlavor_doesNotWaitToStart() {
+ simulateAppAlreadyOnboardedWithFlavor(BuildFlavor.GENERAL_AVAILABILITY)
+ initializeTestApplicationWithFlavor(BuildFlavor.GENERAL_AVAILABILITY)
+
+ // The profile chooser opens immediately for the GA flavor since it has no delay.
+ launchSplashActivityPartially {
+ testCoroutineDispatchers.runCurrent()
+
+ intended(hasComponent(ProfileChooserActivity::class.java.name))
+ }
+ }
+
+ private fun simulateAppAlreadyOpened() {
+ runInNewTestApplication {
+ val monitor = monitorFactory.createMonitor(appStartupStateController.getAppStartupState())
+ testCoroutineDispatchers.advanceUntilIdle()
+ monitor.ensureNextResultIsSuccess()
+ }
}
private fun simulateAppAlreadyOnboarded() {
@@ -403,12 +1034,63 @@ class SplashActivityTest {
// to be done in an isolated test application since the test application of this class shares
// state with production code under test. The isolated test application must be created through
// Instrumentation to ensure it's properly attached.
- val testApplication = Instrumentation.newApplication(
+ runInNewTestApplication {
+ appStartupStateController.markOnboardingFlowCompleted()
+ testCoroutineDispatchers.advanceUntilIdle()
+ }
+ }
+
+ private fun runInNewTestApplication(block: TestApplication.() -> Unit) {
+ val newApplication = Instrumentation.newApplication(
TestApplication::class.java,
InstrumentationRegistry.getInstrumentation().targetContext
) as TestApplication
- testApplication.getAppStartupStateController().markOnboardingFlowCompleted()
- testApplication.getTestCoroutineDispatchers().advanceUntilIdle()
+ newApplication.testCoroutineDispatchers.registerIdlingResource()
+ newApplication.block()
+ newApplication.testCoroutineDispatchers.unregisterIdlingResource()
+ }
+
+ /**
+ * Allows the existing [TestApplication] to be treated as though it was recreated.
+ *
+ * This should only be used when Espresso needs to run operations in a "previous" application
+ * instance (since Espresso can only use the current instrumentation and not a new one). For all
+ * other cases, prefer [runInNewTestApplication] since it actually creates an entirely new
+ * application in isolation, and is closer to a separate app instance than what this method
+ * produces.
+ */
+ private fun recreateExistingApplication() {
+ testCoroutineDispatchers.unregisterIdlingResource()
+ ApplicationProvider.getApplicationContext().recreateDaggerGraph()
+ initializeTestApplication()
+
+ // Reset any intents previously recorded.
+ Intents.release()
+ Intents.init()
+ }
+
+ private fun recreateExistingApplicationWithFlavor(buildFlavor: BuildFlavor) {
+ TestModule.buildFlavor = buildFlavor
+ recreateExistingApplication()
+ }
+
+ /** See [recreateExistingApplication] for when to use this. */
+ private fun reopenAppWithNewFlavor(buildFlavor: BuildFlavor) {
+ TestModule.buildFlavor = buildFlavor
+ recreateExistingApplication()
+ val monitor = monitorFactory.createMonitor(appStartupStateController.getAppStartupState())
+ testCoroutineDispatchers.advanceUntilIdle()
+ monitor.ensureNextResultIsSuccess()
+ }
+
+ private fun simulateAppAlreadyOpenedWithFlavor(buildFlavor: BuildFlavor) {
+ TestModule.buildFlavor = buildFlavor
+ simulateAppAlreadyOpened()
+ }
+
+ private fun simulateAppAlreadyOnboardedWithFlavor(buildFlavor: BuildFlavor) {
+ TestModule.buildFlavor = buildFlavor
+ simulateAppAlreadyOnboarded()
}
private fun initializeTestApplication() {
@@ -417,6 +1099,38 @@ class SplashActivityTest {
setAutoAppExpirationEnabled(enabled = false) // Default to disabled.
}
+ private fun initializeTestApplicationWithFlavor(buildFlavor: BuildFlavor) {
+ TestModule.buildFlavor = buildFlavor
+ initializeTestApplication()
+ }
+
+ /**
+ * Launches [SplashActivity] and waits for all initial time-based operations to complete before
+ * executing [testBlock].
+ */
+ private fun launchSplashActivityFully(testBlock: (ActivityScenario) -> Unit) {
+ launchSplashActivity {
+ testCoroutineDispatchers.advanceUntilIdle()
+ testBlock(it)
+ }
+ }
+
+ /** Launches [SplashActivity] and waits for initial time-based operations to start. */
+ private fun launchSplashActivityPartially(testBlock: (ActivityScenario) -> Unit) {
+ launchSplashActivity {
+ testCoroutineDispatchers.runCurrent()
+ testBlock(it)
+ }
+ }
+
+ private fun launchSplashActivity(testBlock: (ActivityScenario) -> Unit) {
+ val openFromLauncher = Intent(context, SplashActivity::class.java).also {
+ it.action = Intent.ACTION_MAIN
+ it.addCategory(Intent.CATEGORY_LAUNCHER)
+ }
+ ActivityScenario.launch(openFromLauncher).use(testBlock)
+ }
+
private fun setAutoAppExpirationEnabled(enabled: Boolean) {
fakeMetaDataRetriever.putMetaDataBoolean("automatic_app_expiration_enabled", enabled)
}
@@ -448,26 +1162,26 @@ class SplashActivityTest {
Locale.setDefault(locale)
}
- private fun getShadowLogsOnRobolectric(): List {
- val shadowLogClass = Class.forName("org.robolectric.shadows.ShadowLog")
- val shadowLogItem = Class.forName("org.robolectric.shadows.ShadowLog\$LogItem")
- val msgField = shadowLogItem.getDeclaredField("msg")
- val logItems = shadowLogClass.getDeclaredMethod("getLogs").invoke(/* obj= */ null) as? List<*>
- return logItems?.map { logItem ->
- msgField.get(logItem) as String
- } ?: listOf()
- }
-
private fun corruptCacheFile() {
// Statically retrieve the application context since injection may not have yet occurred.
val applicationContext = ApplicationProvider.getApplicationContext()
File(applicationContext.filesDir, "on_boarding_flow.cache").writeText("broken")
}
+ @Module
+ class TestModule {
+ companion object {
+ var buildFlavor = BuildFlavor.BUILD_FLAVOR_UNSPECIFIED
+ }
+
+ @Provides
+ fun provideTestingBuildFlavor(): BuildFlavor = buildFlavor
+ }
+
@Singleton
@Component(
modules = [
- RobolectricModule::class,
+ TestModule::class, RobolectricModule::class,
TestDispatcherModule::class, ApplicationModule::class, PlatformParameterModule::class,
LoggerModule::class, ContinueModule::class, FractionInputModule::class,
ItemSelectionInputModule::class, MultipleChoiceInputModule::class,
@@ -505,34 +1219,47 @@ class SplashActivityTest {
fun getTestCoroutineDispatchers(): TestCoroutineDispatchers
+ fun getMonitorFactory(): DataProviderTestMonitor.Factory
+
fun inject(splashActivityTest: SplashActivityTest)
}
class TestApplication : Application(), ActivityComponentFactory, ApplicationInjectorProvider {
- private val component: TestApplicationComponent by lazy {
- DaggerSplashActivityTest_TestApplicationComponent.builder()
- .setApplication(this)
- .build()
- }
+ private var component: TestApplicationComponent = createTestApplicationComponent()
+
+ val appStartupStateController: AppStartupStateController
+ get() = component.getAppStartupStateController()
+ val testCoroutineDispatchers: TestCoroutineDispatchers
+ get() = component.getTestCoroutineDispatchers()
+ val monitorFactory: DataProviderTestMonitor.Factory
+ get() = component.getMonitorFactory()
fun inject(splashActivityTest: SplashActivityTest) {
component.inject(splashActivityTest)
}
- fun getAppStartupStateController() = component.getAppStartupStateController()
-
- fun getTestCoroutineDispatchers() = component.getTestCoroutineDispatchers()
-
override fun createActivityComponent(activity: AppCompatActivity): ActivityComponent {
return component.getActivityComponentBuilderProvider().get().setActivity(activity).build()
}
override fun getApplicationInjector(): ApplicationInjector = component
+
+ fun recreateDaggerGraph() {
+ component = createTestApplicationComponent()
+ }
+
+ private fun createTestApplicationComponent(): TestApplicationComponent {
+ return DaggerSplashActivityTest_TestApplicationComponent.builder()
+ .setApplication(this)
+ .build()
+ }
}
private companion object {
private val EGYPT_ARABIC_LOCALE = Locale("ar", "EG")
private val BRAZIL_PORTUGUESE_LOCALE = Locale("pt", "BR")
private val TURKEY_TURKISH_LOCALE = Locale("tr", "TR")
+
+ private fun onDialogView(matcher: Matcher) = onView(matcher).inRoot(isDialog())
}
}
diff --git a/app/src/sharedTest/java/org/oppia/android/app/story/StoryActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/story/StoryActivityTest.kt
index 54df28345a1..2fa6bda9d46 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/story/StoryActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/story/StoryActivityTest.kt
@@ -34,6 +34,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.exploration.ExplorationActivity
@@ -235,7 +236,7 @@ class StoryActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/story/StoryFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/story/StoryFragmentTest.kt
index 74fae89ca56..e1b9859c69c 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/story/StoryFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/story/StoryFragmentTest.kt
@@ -61,6 +61,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.customview.LessonThumbnailImageView
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
@@ -903,7 +904,7 @@ class StoryFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/testing/DragDropTestActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/testing/DragDropTestActivityTest.kt
index fc866ddceb1..3e79cccd1b6 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/testing/DragDropTestActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/testing/DragDropTestActivityTest.kt
@@ -24,6 +24,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -228,7 +229,7 @@ class DragDropTestActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/testing/ImageRegionSelectionInteractionViewTest.kt b/app/src/sharedTest/java/org/oppia/android/app/testing/ImageRegionSelectionInteractionViewTest.kt
index 20d315e0475..15ced77dc59 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/testing/ImageRegionSelectionInteractionViewTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/testing/ImageRegionSelectionInteractionViewTest.kt
@@ -36,6 +36,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.ImageRegionSelectionInteractionView
@@ -415,7 +416,7 @@ class ImageRegionSelectionInteractionViewTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/testing/InputInteractionViewTestActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/testing/InputInteractionViewTestActivityTest.kt
index da4d3031acd..97d4326ceaf 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/testing/InputInteractionViewTestActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/testing/InputInteractionViewTestActivityTest.kt
@@ -36,6 +36,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.customview.interaction.RatioInputInteractionView
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
@@ -1126,7 +1127,7 @@ class InputInteractionViewTestActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/testing/NavigationDrawerActivityDebugTest.kt b/app/src/sharedTest/java/org/oppia/android/app/testing/NavigationDrawerActivityDebugTest.kt
index 69a7cfcc0ac..6096a49752e 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/testing/NavigationDrawerActivityDebugTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/testing/NavigationDrawerActivityDebugTest.kt
@@ -55,6 +55,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsActivity
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
@@ -439,7 +440,7 @@ class NavigationDrawerActivityDebugTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/testing/NavigationDrawerActivityProdTest.kt b/app/src/sharedTest/java/org/oppia/android/app/testing/NavigationDrawerActivityProdTest.kt
index c7a0fc12355..e9c6b2a98ac 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/testing/NavigationDrawerActivityProdTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/testing/NavigationDrawerActivityProdTest.kt
@@ -60,6 +60,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.drawer.NavigationDrawerItem
import org.oppia.android.app.help.HelpActivity
@@ -988,7 +989,7 @@ class NavigationDrawerActivityProdTest {
AlgebraicExpressionInputModule::class, MathEquationInputModule::class,
SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/testing/TestFontScaleConfigurationUtilActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/testing/TestFontScaleConfigurationUtilActivityTest.kt
index 7488560d8d9..5cfe02d9bdc 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/testing/TestFontScaleConfigurationUtilActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/testing/TestFontScaleConfigurationUtilActivityTest.kt
@@ -25,6 +25,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.model.ReadingTextSize
@@ -206,7 +207,7 @@ class TestFontScaleConfigurationUtilActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/testing/TopicTestActivityForStoryTest.kt b/app/src/sharedTest/java/org/oppia/android/app/testing/TopicTestActivityForStoryTest.kt
index 5aebaae32fa..329648407b1 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/testing/TopicTestActivityForStoryTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/testing/TopicTestActivityForStoryTest.kt
@@ -28,6 +28,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -203,7 +204,7 @@ class TopicTestActivityForStoryTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseListActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseListActivityTest.kt
index efb85e232b1..32993ac8369 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseListActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseListActivityTest.kt
@@ -21,6 +21,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.help.thirdparty.LicenseListActivity
@@ -163,7 +164,7 @@ class LicenseListActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class,
- MetricLogSchedulerModule::class
+ MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
diff --git a/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseListFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseListFragmentTest.kt
index 4fd305d3ce0..0b5f2eae1ab 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseListFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseListFragmentTest.kt
@@ -34,6 +34,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.help.thirdparty.LicenseListActivity
@@ -373,7 +374,7 @@ class LicenseListFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class,
- MetricLogSchedulerModule::class
+ MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
diff --git a/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseTextViewerActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseTextViewerActivityTest.kt
index a751f1b52de..198ef7c20f5 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseTextViewerActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseTextViewerActivityTest.kt
@@ -21,6 +21,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.help.thirdparty.LicenseListActivity
@@ -172,7 +173,7 @@ class LicenseTextViewerActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class,
- MetricLogSchedulerModule::class
+ MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
diff --git a/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseTextViewerFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseTextViewerFragmentTest.kt
index bd5f229906f..b12abd0898a 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseTextViewerFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseTextViewerFragmentTest.kt
@@ -26,6 +26,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.help.thirdparty.LicenseTextViewerActivity
@@ -351,7 +352,7 @@ class LicenseTextViewerFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class,
- MetricLogSchedulerModule::class
+ MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
diff --git a/app/src/sharedTest/java/org/oppia/android/app/thirdparty/ThirdPartyDependencyListActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/thirdparty/ThirdPartyDependencyListActivityTest.kt
index 2298212d383..b6a7a2093b7 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/thirdparty/ThirdPartyDependencyListActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/thirdparty/ThirdPartyDependencyListActivityTest.kt
@@ -21,6 +21,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.help.thirdparty.ThirdPartyDependencyListActivity
@@ -160,7 +161,7 @@ class ThirdPartyDependencyListActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class,
- MetricLogSchedulerModule::class
+ MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
diff --git a/app/src/sharedTest/java/org/oppia/android/app/thirdparty/ThirdPartyDependencyListFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/thirdparty/ThirdPartyDependencyListFragmentTest.kt
index f9dd5befd2e..cd7839f3fdb 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/thirdparty/ThirdPartyDependencyListFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/thirdparty/ThirdPartyDependencyListFragmentTest.kt
@@ -33,6 +33,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.help.thirdparty.LicenseListActivity
@@ -483,7 +484,7 @@ class ThirdPartyDependencyListFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class,
- MetricLogSchedulerModule::class
+ MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/TopicActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/TopicActivityTest.kt
index 15c80f80eca..9cbbb6dd857 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/TopicActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/TopicActivityTest.kt
@@ -33,6 +33,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.model.ProfileId
@@ -209,7 +210,7 @@ class TopicActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt
index 87fb560776c..a83ee19558f 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt
@@ -43,6 +43,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -664,7 +665,7 @@ class TopicFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/conceptcard/ConceptCardFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/conceptcard/ConceptCardFragmentTest.kt
index 6a3c9d7be97..3af01c379e0 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/conceptcard/ConceptCardFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/conceptcard/ConceptCardFragmentTest.kt
@@ -38,6 +38,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.model.OppiaLanguage
@@ -435,7 +436,7 @@ class ConceptCardFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/info/TopicInfoFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/info/TopicInfoFragmentTest.kt
index e743d17c05d..ab908ad0315 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/info/TopicInfoFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/info/TopicInfoFragmentTest.kt
@@ -43,6 +43,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -491,7 +492,7 @@ class TopicInfoFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/lessons/TopicLessonsFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/lessons/TopicLessonsFragmentTest.kt
index 2e12f85d07a..6cccfd1f84a 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/lessons/TopicLessonsFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/lessons/TopicLessonsFragmentTest.kt
@@ -43,6 +43,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.model.ProfileId
@@ -1020,7 +1021,7 @@ class TopicLessonsFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/practice/TopicPracticeFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/practice/TopicPracticeFragmentTest.kt
index 98ae842aa2d..be3f067135a 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/practice/TopicPracticeFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/practice/TopicPracticeFragmentTest.kt
@@ -37,6 +37,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -436,7 +437,7 @@ class TopicPracticeFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/questionplayer/QuestionPlayerActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/questionplayer/QuestionPlayerActivityTest.kt
index 8fbee49074d..13e515ebefc 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/questionplayer/QuestionPlayerActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/questionplayer/QuestionPlayerActivityTest.kt
@@ -54,6 +54,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.model.OppiaLanguage
@@ -725,7 +726,7 @@ class QuestionPlayerActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/revision/TopicRevisionFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/revision/TopicRevisionFragmentTest.kt
index 86da92fe690..01054765d12 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/revision/TopicRevisionFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/revision/TopicRevisionFragmentTest.kt
@@ -37,6 +37,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -332,7 +333,7 @@ class TopicRevisionFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/revisioncard/RevisionCardActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/revisioncard/RevisionCardActivityTest.kt
index 6d8fbf9be40..894dec9cb73 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/revisioncard/RevisionCardActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/revisioncard/RevisionCardActivityTest.kt
@@ -32,6 +32,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.model.OppiaLanguage
@@ -286,7 +287,7 @@ class RevisionCardActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/revisioncard/RevisionCardFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/revisioncard/RevisionCardFragmentTest.kt
index 84f04139d51..85c1e26ef3d 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/revisioncard/RevisionCardFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/revisioncard/RevisionCardFragmentTest.kt
@@ -45,6 +45,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.help.HelpActivity
@@ -602,7 +603,7 @@ class RevisionCardFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/utility/RatioExtensionsTest.kt b/app/src/sharedTest/java/org/oppia/android/app/utility/RatioExtensionsTest.kt
index 3596c8533d1..8ea214e120a 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/utility/RatioExtensionsTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/utility/RatioExtensionsTest.kt
@@ -18,6 +18,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.model.RatioExpression
@@ -159,7 +160,7 @@ class RatioExtensionsTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughActivityTest.kt
index cd49b90d400..9d977f37a02 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughActivityTest.kt
@@ -31,6 +31,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -237,7 +238,7 @@ class WalkthroughActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughFinalFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughFinalFragmentTest.kt
index 7bdea47cd8c..d27197c2cad 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughFinalFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughFinalFragmentTest.kt
@@ -33,6 +33,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -294,7 +295,7 @@ class WalkthroughFinalFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughTopicListFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughTopicListFragmentTest.kt
index f334d5e7080..ec3ab607a23 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughTopicListFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughTopicListFragmentTest.kt
@@ -34,6 +34,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -320,7 +321,7 @@ class WalkthroughTopicListFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughWelcomeFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughWelcomeFragmentTest.kt
index 59b4f9f4ca8..d8b48d6dbdb 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughWelcomeFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughWelcomeFragmentTest.kt
@@ -29,6 +29,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.model.ProfileId
@@ -217,7 +218,7 @@ class WalkthroughWelcomeFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/activity/ActivityIntentFactoriesTest.kt b/app/src/test/java/org/oppia/android/app/activity/ActivityIntentFactoriesTest.kt
index f0491f38b65..80145e188cc 100644
--- a/app/src/test/java/org/oppia/android/app/activity/ActivityIntentFactoriesTest.kt
+++ b/app/src/test/java/org/oppia/android/app/activity/ActivityIntentFactoriesTest.kt
@@ -19,6 +19,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.home.recentlyplayed.RecentlyPlayedActivity
@@ -182,7 +183,7 @@ class ActivityIntentFactoriesTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/activity/BUILD.bazel b/app/src/test/java/org/oppia/android/app/activity/BUILD.bazel
index a3c4e616851..ec052a7416a 100644
--- a/app/src/test/java/org/oppia/android/app/activity/BUILD.bazel
+++ b/app/src/test/java/org/oppia/android/app/activity/BUILD.bazel
@@ -19,6 +19,7 @@ oppia_android_test(
"//app/src/main/java/org/oppia/android/app/application:application_injector",
"//app/src/main/java/org/oppia/android/app/application:application_injector_provider",
"//app/src/main/java/org/oppia/android/app/application:common_application_modules",
+ "//app/src/main/java/org/oppia/android/app/application/testing:testing_build_flavor_module",
"//app/src/main/java/org/oppia/android/app/translation/testing:test_module",
"//domain",
"//domain/src/main/java/org/oppia/android/domain/classify:interactions_module",
diff --git a/app/src/test/java/org/oppia/android/app/application/alpha/AlphaBuildFlavorModuleTest.kt b/app/src/test/java/org/oppia/android/app/application/alpha/AlphaBuildFlavorModuleTest.kt
new file mode 100644
index 00000000000..f40c984f7b4
--- /dev/null
+++ b/app/src/test/java/org/oppia/android/app/application/alpha/AlphaBuildFlavorModuleTest.kt
@@ -0,0 +1,81 @@
+package org.oppia.android.app.application.alpha
+
+import android.app.Application
+import android.content.Context
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.google.common.truth.Truth.assertThat
+import dagger.BindsInstance
+import dagger.Component
+import dagger.Module
+import dagger.Provides
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.oppia.android.app.model.BuildFlavor
+import org.robolectric.annotation.Config
+import org.robolectric.annotation.LooperMode
+import javax.inject.Inject
+import javax.inject.Singleton
+
+/** Tests for [AlphaBuildFlavorModule]. */
+// FunctionName: test names are conventionally named with underscores.
+@Suppress("FunctionName")
+@RunWith(AndroidJUnit4::class)
+@LooperMode(LooperMode.Mode.PAUSED)
+@Config(application = AlphaBuildFlavorModuleTest.TestApplication::class)
+class AlphaBuildFlavorModuleTest {
+ @Inject
+ lateinit var buildFlavor: BuildFlavor
+
+ @Before
+ fun setUp() {
+ setUpTestApplicationComponent()
+ }
+
+ @Test
+ fun testBuildFlavor_isAlphaBuildFlavor() {
+ assertThat(buildFlavor).isEqualTo(BuildFlavor.ALPHA)
+ }
+
+ private fun setUpTestApplicationComponent() {
+ ApplicationProvider.getApplicationContext().inject(this)
+ }
+
+ // TODO(#89): Move this to a common test application component.
+ @Module
+ class TestModule {
+ @Provides
+ @Singleton
+ fun provideContext(application: Application): Context {
+ return application
+ }
+ }
+
+ // TODO(#89): Move this to a common test application component.
+ @Singleton
+ @Component(modules = [TestModule::class, AlphaBuildFlavorModule::class])
+ interface TestApplicationComponent {
+ @Component.Builder
+ interface Builder {
+ @BindsInstance
+ fun setApplication(application: Application): Builder
+
+ fun build(): TestApplicationComponent
+ }
+
+ fun inject(test: AlphaBuildFlavorModuleTest)
+ }
+
+ class TestApplication : Application() {
+ private val component: TestApplicationComponent by lazy {
+ DaggerAlphaBuildFlavorModuleTest_TestApplicationComponent.builder()
+ .setApplication(this)
+ .build()
+ }
+
+ fun inject(test: AlphaBuildFlavorModuleTest) {
+ component.inject(test)
+ }
+ }
+}
diff --git a/app/src/test/java/org/oppia/android/app/application/alpha/BUILD.bazel b/app/src/test/java/org/oppia/android/app/application/alpha/BUILD.bazel
new file mode 100644
index 00000000000..900715a50e6
--- /dev/null
+++ b/app/src/test/java/org/oppia/android/app/application/alpha/BUILD.bazel
@@ -0,0 +1,26 @@
+"""
+Tests for alpha-specific top-level application configurations.
+"""
+
+load("@dagger//:workspace_defs.bzl", "dagger_rules")
+load("//:oppia_android_test.bzl", "oppia_android_test")
+
+oppia_android_test(
+ name = "AlphaBuildFlavorModuleTest",
+ srcs = ["AlphaBuildFlavorModuleTest.kt"],
+ custom_package = "org.oppia.android.app.application.alpha",
+ test_class = "org.oppia.android.app.application.alpha.AlphaBuildFlavorModuleTest",
+ test_manifest = "//app:test_manifest",
+ deps = [
+ ":dagger",
+ "//app/src/main/java/org/oppia/android/app/application/alpha:alpha_build_flavor_module",
+ "//model/src/main/proto:version_java_proto_lite",
+ "//third_party:androidx_test_ext_junit",
+ "//third_party:com_google_truth_truth",
+ "//third_party:junit_junit",
+ "//third_party:org_robolectric_robolectric",
+ "//third_party:robolectric_android-all",
+ ],
+)
+
+dagger_rules()
diff --git a/app/src/test/java/org/oppia/android/app/application/beta/BUILD.bazel b/app/src/test/java/org/oppia/android/app/application/beta/BUILD.bazel
new file mode 100644
index 00000000000..4706b193b26
--- /dev/null
+++ b/app/src/test/java/org/oppia/android/app/application/beta/BUILD.bazel
@@ -0,0 +1,26 @@
+"""
+Tests for beta-specific top-level application configurations.
+"""
+
+load("@dagger//:workspace_defs.bzl", "dagger_rules")
+load("//:oppia_android_test.bzl", "oppia_android_test")
+
+oppia_android_test(
+ name = "BetaBuildFlavorModuleTest",
+ srcs = ["BetaBuildFlavorModuleTest.kt"],
+ custom_package = "org.oppia.android.app.application.beta",
+ test_class = "org.oppia.android.app.application.beta.BetaBuildFlavorModuleTest",
+ test_manifest = "//app:test_manifest",
+ deps = [
+ ":dagger",
+ "//app/src/main/java/org/oppia/android/app/application/beta:beta_application",
+ "//model/src/main/proto:version_java_proto_lite",
+ "//third_party:androidx_test_ext_junit",
+ "//third_party:com_google_truth_truth",
+ "//third_party:junit_junit",
+ "//third_party:org_robolectric_robolectric",
+ "//third_party:robolectric_android-all",
+ ],
+)
+
+dagger_rules()
diff --git a/app/src/test/java/org/oppia/android/app/application/beta/BetaBuildFlavorModuleTest.kt b/app/src/test/java/org/oppia/android/app/application/beta/BetaBuildFlavorModuleTest.kt
new file mode 100644
index 00000000000..efbe6eab3e7
--- /dev/null
+++ b/app/src/test/java/org/oppia/android/app/application/beta/BetaBuildFlavorModuleTest.kt
@@ -0,0 +1,81 @@
+package org.oppia.android.app.application.beta
+
+import android.app.Application
+import android.content.Context
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.google.common.truth.Truth.assertThat
+import dagger.BindsInstance
+import dagger.Component
+import dagger.Module
+import dagger.Provides
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.oppia.android.app.model.BuildFlavor
+import org.robolectric.annotation.Config
+import org.robolectric.annotation.LooperMode
+import javax.inject.Inject
+import javax.inject.Singleton
+
+/** Tests for [BetaBuildFlavorModule]. */
+// FunctionName: test names are conventionally named with underscores.
+@Suppress("FunctionName")
+@RunWith(AndroidJUnit4::class)
+@LooperMode(LooperMode.Mode.PAUSED)
+@Config(application = BetaBuildFlavorModuleTest.TestApplication::class)
+class BetaBuildFlavorModuleTest {
+ @Inject
+ lateinit var buildFlavor: BuildFlavor
+
+ @Before
+ fun setUp() {
+ setUpTestApplicationComponent()
+ }
+
+ @Test
+ fun testBuildFlavor_isBetaBuildFlavor() {
+ assertThat(buildFlavor).isEqualTo(BuildFlavor.BETA)
+ }
+
+ private fun setUpTestApplicationComponent() {
+ ApplicationProvider.getApplicationContext().inject(this)
+ }
+
+ // TODO(#89): Move this to a common test application component.
+ @Module
+ class TestModule {
+ @Provides
+ @Singleton
+ fun provideContext(application: Application): Context {
+ return application
+ }
+ }
+
+ // TODO(#89): Move this to a common test application component.
+ @Singleton
+ @Component(modules = [TestModule::class, BetaBuildFlavorModule::class])
+ interface TestApplicationComponent {
+ @Component.Builder
+ interface Builder {
+ @BindsInstance
+ fun setApplication(application: Application): Builder
+
+ fun build(): TestApplicationComponent
+ }
+
+ fun inject(test: BetaBuildFlavorModuleTest)
+ }
+
+ class TestApplication : Application() {
+ private val component: TestApplicationComponent by lazy {
+ DaggerBetaBuildFlavorModuleTest_TestApplicationComponent.builder()
+ .setApplication(this)
+ .build()
+ }
+
+ fun inject(test: BetaBuildFlavorModuleTest) {
+ component.inject(test)
+ }
+ }
+}
diff --git a/app/src/test/java/org/oppia/android/app/application/dev/BUILD.bazel b/app/src/test/java/org/oppia/android/app/application/dev/BUILD.bazel
new file mode 100644
index 00000000000..c6566c6f2a6
--- /dev/null
+++ b/app/src/test/java/org/oppia/android/app/application/dev/BUILD.bazel
@@ -0,0 +1,26 @@
+"""
+Tests for developer-specific top-level application configurations.
+"""
+
+load("@dagger//:workspace_defs.bzl", "dagger_rules")
+load("//:oppia_android_test.bzl", "oppia_android_test")
+
+oppia_android_test(
+ name = "DeveloperBuildFlavorModuleTest",
+ srcs = ["DeveloperBuildFlavorModuleTest.kt"],
+ custom_package = "org.oppia.android.app.application.dev",
+ test_class = "org.oppia.android.app.application.dev.DeveloperBuildFlavorModuleTest",
+ test_manifest = "//app:test_manifest",
+ deps = [
+ ":dagger",
+ "//app/src/main/java/org/oppia/android/app/application/dev:developer_application",
+ "//model/src/main/proto:version_java_proto_lite",
+ "//third_party:androidx_test_ext_junit",
+ "//third_party:com_google_truth_truth",
+ "//third_party:junit_junit",
+ "//third_party:org_robolectric_robolectric",
+ "//third_party:robolectric_android-all",
+ ],
+)
+
+dagger_rules()
diff --git a/app/src/test/java/org/oppia/android/app/application/dev/DeveloperBuildFlavorModuleTest.kt b/app/src/test/java/org/oppia/android/app/application/dev/DeveloperBuildFlavorModuleTest.kt
new file mode 100644
index 00000000000..9f5a1c6e7ee
--- /dev/null
+++ b/app/src/test/java/org/oppia/android/app/application/dev/DeveloperBuildFlavorModuleTest.kt
@@ -0,0 +1,81 @@
+package org.oppia.android.app.application.dev
+
+import android.app.Application
+import android.content.Context
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.google.common.truth.Truth.assertThat
+import dagger.BindsInstance
+import dagger.Component
+import dagger.Module
+import dagger.Provides
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.oppia.android.app.model.BuildFlavor
+import org.robolectric.annotation.Config
+import org.robolectric.annotation.LooperMode
+import javax.inject.Inject
+import javax.inject.Singleton
+
+/** Tests for [DeveloperBuildFlavorModule]. */
+// FunctionName: test names are conventionally named with underscores.
+@Suppress("FunctionName")
+@RunWith(AndroidJUnit4::class)
+@LooperMode(LooperMode.Mode.PAUSED)
+@Config(application = DeveloperBuildFlavorModuleTest.TestApplication::class)
+class DeveloperBuildFlavorModuleTest {
+ @Inject
+ lateinit var buildFlavor: BuildFlavor
+
+ @Before
+ fun setUp() {
+ setUpTestApplicationComponent()
+ }
+
+ @Test
+ fun testBuildFlavor_isDeveloperBuildFlavor() {
+ assertThat(buildFlavor).isEqualTo(BuildFlavor.DEVELOPER)
+ }
+
+ private fun setUpTestApplicationComponent() {
+ ApplicationProvider.getApplicationContext().inject(this)
+ }
+
+ // TODO(#89): Move this to a common test application component.
+ @Module
+ class TestModule {
+ @Provides
+ @Singleton
+ fun provideContext(application: Application): Context {
+ return application
+ }
+ }
+
+ // TODO(#89): Move this to a common test application component.
+ @Singleton
+ @Component(modules = [TestModule::class, DeveloperBuildFlavorModule::class])
+ interface TestApplicationComponent {
+ @Component.Builder
+ interface Builder {
+ @BindsInstance
+ fun setApplication(application: Application): Builder
+
+ fun build(): TestApplicationComponent
+ }
+
+ fun inject(test: DeveloperBuildFlavorModuleTest)
+ }
+
+ class TestApplication : Application() {
+ private val component: TestApplicationComponent by lazy {
+ DaggerDeveloperBuildFlavorModuleTest_TestApplicationComponent.builder()
+ .setApplication(this)
+ .build()
+ }
+
+ fun inject(test: DeveloperBuildFlavorModuleTest) {
+ component.inject(test)
+ }
+ }
+}
diff --git a/app/src/test/java/org/oppia/android/app/application/ga/BUILD.bazel b/app/src/test/java/org/oppia/android/app/application/ga/BUILD.bazel
new file mode 100644
index 00000000000..c3ce6168c22
--- /dev/null
+++ b/app/src/test/java/org/oppia/android/app/application/ga/BUILD.bazel
@@ -0,0 +1,26 @@
+"""
+Tests for general availability-specific top-level application configurations.
+"""
+
+load("@dagger//:workspace_defs.bzl", "dagger_rules")
+load("//:oppia_android_test.bzl", "oppia_android_test")
+
+oppia_android_test(
+ name = "GaBuildFlavorModuleTest",
+ srcs = ["GaBuildFlavorModuleTest.kt"],
+ custom_package = "org.oppia.android.app.application.ga",
+ test_class = "org.oppia.android.app.application.ga.GaBuildFlavorModuleTest",
+ test_manifest = "//app:test_manifest",
+ deps = [
+ ":dagger",
+ "//app/src/main/java/org/oppia/android/app/application/ga:general_availability_application",
+ "//model/src/main/proto:version_java_proto_lite",
+ "//third_party:androidx_test_ext_junit",
+ "//third_party:com_google_truth_truth",
+ "//third_party:junit_junit",
+ "//third_party:org_robolectric_robolectric",
+ "//third_party:robolectric_android-all",
+ ],
+)
+
+dagger_rules()
diff --git a/app/src/test/java/org/oppia/android/app/application/ga/GaBuildFlavorModuleTest.kt b/app/src/test/java/org/oppia/android/app/application/ga/GaBuildFlavorModuleTest.kt
new file mode 100644
index 00000000000..b8a848a432e
--- /dev/null
+++ b/app/src/test/java/org/oppia/android/app/application/ga/GaBuildFlavorModuleTest.kt
@@ -0,0 +1,81 @@
+package org.oppia.android.app.application.ga
+
+import android.app.Application
+import android.content.Context
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.google.common.truth.Truth.assertThat
+import dagger.BindsInstance
+import dagger.Component
+import dagger.Module
+import dagger.Provides
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.oppia.android.app.model.BuildFlavor
+import org.robolectric.annotation.Config
+import org.robolectric.annotation.LooperMode
+import javax.inject.Inject
+import javax.inject.Singleton
+
+/** Tests for [GaBuildFlavorModule]. */
+// FunctionName: test names are conventionally named with underscores.
+@Suppress("FunctionName")
+@RunWith(AndroidJUnit4::class)
+@LooperMode(LooperMode.Mode.PAUSED)
+@Config(application = GaBuildFlavorModuleTest.TestApplication::class)
+class GaBuildFlavorModuleTest {
+ @Inject
+ lateinit var buildFlavor: BuildFlavor
+
+ @Before
+ fun setUp() {
+ setUpTestApplicationComponent()
+ }
+
+ @Test
+ fun testBuildFlavor_isGeneralAvailabilityBuildFlavor() {
+ assertThat(buildFlavor).isEqualTo(BuildFlavor.GENERAL_AVAILABILITY)
+ }
+
+ private fun setUpTestApplicationComponent() {
+ ApplicationProvider.getApplicationContext().inject(this)
+ }
+
+ // TODO(#89): Move this to a common test application component.
+ @Module
+ class TestModule {
+ @Provides
+ @Singleton
+ fun provideContext(application: Application): Context {
+ return application
+ }
+ }
+
+ // TODO(#89): Move this to a common test application component.
+ @Singleton
+ @Component(modules = [TestModule::class, GaBuildFlavorModule::class])
+ interface TestApplicationComponent {
+ @Component.Builder
+ interface Builder {
+ @BindsInstance
+ fun setApplication(application: Application): Builder
+
+ fun build(): TestApplicationComponent
+ }
+
+ fun inject(test: GaBuildFlavorModuleTest)
+ }
+
+ class TestApplication : Application() {
+ private val component: TestApplicationComponent by lazy {
+ DaggerGaBuildFlavorModuleTest_TestApplicationComponent.builder()
+ .setApplication(this)
+ .build()
+ }
+
+ fun inject(test: GaBuildFlavorModuleTest) {
+ component.inject(test)
+ }
+ }
+}
diff --git a/app/src/test/java/org/oppia/android/app/application/testing/BUILD.bazel b/app/src/test/java/org/oppia/android/app/application/testing/BUILD.bazel
new file mode 100644
index 00000000000..2168366aeb4
--- /dev/null
+++ b/app/src/test/java/org/oppia/android/app/application/testing/BUILD.bazel
@@ -0,0 +1,26 @@
+"""
+Tests for testing-specific top-level application configurations.
+"""
+
+load("@dagger//:workspace_defs.bzl", "dagger_rules")
+load("//:oppia_android_test.bzl", "oppia_android_test")
+
+oppia_android_test(
+ name = "TestingBuildFlavorModuleTest",
+ srcs = ["TestingBuildFlavorModuleTest.kt"],
+ custom_package = "org.oppia.android.app.application.testing",
+ test_class = "org.oppia.android.app.application.testing.TestingBuildFlavorModuleTest",
+ test_manifest = "//app:test_manifest",
+ deps = [
+ ":dagger",
+ "//app/src/main/java/org/oppia/android/app/application/testing:testing_build_flavor_module",
+ "//model/src/main/proto:version_java_proto_lite",
+ "//third_party:androidx_test_ext_junit",
+ "//third_party:com_google_truth_truth",
+ "//third_party:junit_junit",
+ "//third_party:org_robolectric_robolectric",
+ "//third_party:robolectric_android-all",
+ ],
+)
+
+dagger_rules()
diff --git a/app/src/test/java/org/oppia/android/app/application/testing/TestingBuildFlavorModuleTest.kt b/app/src/test/java/org/oppia/android/app/application/testing/TestingBuildFlavorModuleTest.kt
new file mode 100644
index 00000000000..f1b3136ccb0
--- /dev/null
+++ b/app/src/test/java/org/oppia/android/app/application/testing/TestingBuildFlavorModuleTest.kt
@@ -0,0 +1,81 @@
+package org.oppia.android.app.application.testing
+
+import android.app.Application
+import android.content.Context
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.google.common.truth.Truth.assertThat
+import dagger.BindsInstance
+import dagger.Component
+import dagger.Module
+import dagger.Provides
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.oppia.android.app.model.BuildFlavor
+import org.robolectric.annotation.Config
+import org.robolectric.annotation.LooperMode
+import javax.inject.Inject
+import javax.inject.Singleton
+
+/** Tests for [TestingBuildFlavorModule]. */
+// FunctionName: test names are conventionally named with underscores.
+@Suppress("FunctionName")
+@RunWith(AndroidJUnit4::class)
+@LooperMode(LooperMode.Mode.PAUSED)
+@Config(application = TestingBuildFlavorModuleTest.TestApplication::class)
+class TestingBuildFlavorModuleTest {
+ @Inject
+ lateinit var buildFlavor: BuildFlavor
+
+ @Before
+ fun setUp() {
+ setUpTestApplicationComponent()
+ }
+
+ @Test
+ fun testBuildFlavor_isTestingBuildFlavor() {
+ assertThat(buildFlavor).isEqualTo(BuildFlavor.TESTING)
+ }
+
+ private fun setUpTestApplicationComponent() {
+ ApplicationProvider.getApplicationContext().inject(this)
+ }
+
+ // TODO(#89): Move this to a common test application component.
+ @Module
+ class TestModule {
+ @Provides
+ @Singleton
+ fun provideContext(application: Application): Context {
+ return application
+ }
+ }
+
+ // TODO(#89): Move this to a common test application component.
+ @Singleton
+ @Component(modules = [TestModule::class, TestingBuildFlavorModule::class])
+ interface TestApplicationComponent {
+ @Component.Builder
+ interface Builder {
+ @BindsInstance
+ fun setApplication(application: Application): Builder
+
+ fun build(): TestApplicationComponent
+ }
+
+ fun inject(test: TestingBuildFlavorModuleTest)
+ }
+
+ class TestApplication : Application() {
+ private val component: TestApplicationComponent by lazy {
+ DaggerTestingBuildFlavorModuleTest_TestApplicationComponent.builder()
+ .setApplication(this)
+ .build()
+ }
+
+ fun inject(test: TestingBuildFlavorModuleTest) {
+ component.inject(test)
+ }
+ }
+}
diff --git a/app/src/test/java/org/oppia/android/app/home/HomeActivityLocalTest.kt b/app/src/test/java/org/oppia/android/app/home/HomeActivityLocalTest.kt
index 445649d393b..810f35b9475 100644
--- a/app/src/test/java/org/oppia/android/app/home/HomeActivityLocalTest.kt
+++ b/app/src/test/java/org/oppia/android/app/home/HomeActivityLocalTest.kt
@@ -21,6 +21,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.model.EventLog
@@ -154,7 +155,7 @@ class HomeActivityLocalTest {
AlgebraicExpressionInputModule::class, MathEquationInputModule::class,
SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/parser/FractionParsingUiErrorTest.kt b/app/src/test/java/org/oppia/android/app/parser/FractionParsingUiErrorTest.kt
index d6cb209d2c1..c0216f6e8c6 100644
--- a/app/src/test/java/org/oppia/android/app/parser/FractionParsingUiErrorTest.kt
+++ b/app/src/test/java/org/oppia/android/app/parser/FractionParsingUiErrorTest.kt
@@ -18,6 +18,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -264,7 +265,7 @@ class FractionParsingUiErrorTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/parser/ListItemLeadingMarginSpanTest.kt b/app/src/test/java/org/oppia/android/app/parser/ListItemLeadingMarginSpanTest.kt
index 1ccba698308..8c3fc424a40 100644
--- a/app/src/test/java/org/oppia/android/app/parser/ListItemLeadingMarginSpanTest.kt
+++ b/app/src/test/java/org/oppia/android/app/parser/ListItemLeadingMarginSpanTest.kt
@@ -36,6 +36,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.model.LanguageSupportDefinition
@@ -1106,7 +1107,7 @@ class ListItemLeadingMarginSpanTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
diff --git a/app/src/test/java/org/oppia/android/app/parser/StringToRatioParserTest.kt b/app/src/test/java/org/oppia/android/app/parser/StringToRatioParserTest.kt
index 73ab39d434f..0c038ea5d11 100644
--- a/app/src/test/java/org/oppia/android/app/parser/StringToRatioParserTest.kt
+++ b/app/src/test/java/org/oppia/android/app/parser/StringToRatioParserTest.kt
@@ -18,6 +18,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.model.RatioExpression
@@ -268,7 +269,7 @@ class StringToRatioParserTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/player/exploration/ExplorationActivityLocalTest.kt b/app/src/test/java/org/oppia/android/app/player/exploration/ExplorationActivityLocalTest.kt
index 1c875e82863..25d38fd6333 100644
--- a/app/src/test/java/org/oppia/android/app/player/exploration/ExplorationActivityLocalTest.kt
+++ b/app/src/test/java/org/oppia/android/app/player/exploration/ExplorationActivityLocalTest.kt
@@ -20,6 +20,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.model.EventLog
@@ -215,7 +216,7 @@ class ExplorationActivityLocalTest {
AlgebraicExpressionInputModule::class, MathEquationInputModule::class,
SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/player/state/StateFragmentLocalTest.kt b/app/src/test/java/org/oppia/android/app/player/state/StateFragmentLocalTest.kt
index 30849532780..0a6b6a31e01 100644
--- a/app/src/test/java/org/oppia/android/app/player/state/StateFragmentLocalTest.kt
+++ b/app/src/test/java/org/oppia/android/app/player/state/StateFragmentLocalTest.kt
@@ -58,6 +58,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.hintsandsolution.TAG_REVEAL_SOLUTION_DIALOG
@@ -2297,7 +2298,7 @@ class StateFragmentLocalTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/profile/ProfileChooserFragmentLocalTest.kt b/app/src/test/java/org/oppia/android/app/profile/ProfileChooserFragmentLocalTest.kt
index df5ab8f58d0..db5a73a3add 100644
--- a/app/src/test/java/org/oppia/android/app/profile/ProfileChooserFragmentLocalTest.kt
+++ b/app/src/test/java/org/oppia/android/app/profile/ProfileChooserFragmentLocalTest.kt
@@ -19,6 +19,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.OPEN_PROFILE_CHOOSER
@@ -143,7 +144,7 @@ class ProfileChooserFragmentLocalTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/story/StoryActivityLocalTest.kt b/app/src/test/java/org/oppia/android/app/story/StoryActivityLocalTest.kt
index 5d9cc5e3e75..dbe875db082 100644
--- a/app/src/test/java/org/oppia/android/app/story/StoryActivityLocalTest.kt
+++ b/app/src/test/java/org/oppia/android/app/story/StoryActivityLocalTest.kt
@@ -21,6 +21,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.model.EventLog
@@ -168,7 +169,7 @@ class StoryActivityLocalTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/testing/CompletedStoryListSpanTest.kt b/app/src/test/java/org/oppia/android/app/testing/CompletedStoryListSpanTest.kt
index 86a05a175dc..e2874312b64 100644
--- a/app/src/test/java/org/oppia/android/app/testing/CompletedStoryListSpanTest.kt
+++ b/app/src/test/java/org/oppia/android/app/testing/CompletedStoryListSpanTest.kt
@@ -22,6 +22,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.completedstorylist.CompletedStoryListActivity
import org.oppia.android.app.completedstorylist.CompletedStoryListFragment.Companion.COMPLETED_STORY_LIST_FRAGMENT_TAG
import org.oppia.android.app.devoptions.DeveloperOptionsModule
@@ -177,7 +178,7 @@ class CompletedStoryListSpanTest {
AlgebraicExpressionInputModule::class, MathEquationInputModule::class,
SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/testing/HomeSpanTest.kt b/app/src/test/java/org/oppia/android/app/testing/HomeSpanTest.kt
index 83e920a77bd..d34e7fa7a19 100644
--- a/app/src/test/java/org/oppia/android/app/testing/HomeSpanTest.kt
+++ b/app/src/test/java/org/oppia/android/app/testing/HomeSpanTest.kt
@@ -22,6 +22,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.home.HomeActivity
@@ -191,7 +192,7 @@ class HomeSpanTest {
AlgebraicExpressionInputModule::class, MathEquationInputModule::class,
SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/testing/OngoingTopicListSpanTest.kt b/app/src/test/java/org/oppia/android/app/testing/OngoingTopicListSpanTest.kt
index fc6c6aff74e..ae741ccd5b8 100644
--- a/app/src/test/java/org/oppia/android/app/testing/OngoingTopicListSpanTest.kt
+++ b/app/src/test/java/org/oppia/android/app/testing/OngoingTopicListSpanTest.kt
@@ -23,6 +23,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.ongoingtopiclist.OngoingTopicListActivity
@@ -188,7 +189,7 @@ class OngoingTopicListSpanTest {
AlgebraicExpressionInputModule::class, MathEquationInputModule::class,
SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/testing/PlatformParameterIntegrationTest.kt b/app/src/test/java/org/oppia/android/app/testing/PlatformParameterIntegrationTest.kt
index 5d30677deb7..abb5758dc05 100644
--- a/app/src/test/java/org/oppia/android/app/testing/PlatformParameterIntegrationTest.kt
+++ b/app/src/test/java/org/oppia/android/app/testing/PlatformParameterIntegrationTest.kt
@@ -33,6 +33,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.model.PlatformParameter
@@ -361,7 +362,7 @@ class PlatformParameterIntegrationTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/testing/ProfileChooserSpanTest.kt b/app/src/test/java/org/oppia/android/app/testing/ProfileChooserSpanTest.kt
index ac18c7ff49f..07fa5fc3e8a 100644
--- a/app/src/test/java/org/oppia/android/app/testing/ProfileChooserSpanTest.kt
+++ b/app/src/test/java/org/oppia/android/app/testing/ProfileChooserSpanTest.kt
@@ -22,6 +22,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -390,7 +391,7 @@ class ProfileChooserSpanTest {
AlgebraicExpressionInputModule::class, MathEquationInputModule::class,
SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/testing/ProfileProgressSpanCountTest.kt b/app/src/test/java/org/oppia/android/app/testing/ProfileProgressSpanCountTest.kt
index 7b515278346..a51118c53c2 100644
--- a/app/src/test/java/org/oppia/android/app/testing/ProfileProgressSpanCountTest.kt
+++ b/app/src/test/java/org/oppia/android/app/testing/ProfileProgressSpanCountTest.kt
@@ -22,6 +22,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -174,7 +175,7 @@ class ProfileProgressSpanCountTest {
AlgebraicExpressionInputModule::class, MathEquationInputModule::class,
SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/testing/RecentlyPlayedSpanTest.kt b/app/src/test/java/org/oppia/android/app/testing/RecentlyPlayedSpanTest.kt
index 4571ab23451..d922623fe3f 100644
--- a/app/src/test/java/org/oppia/android/app/testing/RecentlyPlayedSpanTest.kt
+++ b/app/src/test/java/org/oppia/android/app/testing/RecentlyPlayedSpanTest.kt
@@ -23,6 +23,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.home.recentlyplayed.RecentlyPlayedActivity
@@ -309,7 +310,7 @@ class RecentlyPlayedSpanTest {
AlgebraicExpressionInputModule::class, MathEquationInputModule::class,
SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/testing/TopicRevisionSpanTest.kt b/app/src/test/java/org/oppia/android/app/testing/TopicRevisionSpanTest.kt
index 9ea7e810383..24822b4c5f2 100644
--- a/app/src/test/java/org/oppia/android/app/testing/TopicRevisionSpanTest.kt
+++ b/app/src/test/java/org/oppia/android/app/testing/TopicRevisionSpanTest.kt
@@ -22,6 +22,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -174,7 +175,7 @@ class TopicRevisionSpanTest {
AlgebraicExpressionInputModule::class, MathEquationInputModule::class,
SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/testing/activity/BUILD.bazel b/app/src/test/java/org/oppia/android/app/testing/activity/BUILD.bazel
index e56a257b618..6b3c8185dd7 100644
--- a/app/src/test/java/org/oppia/android/app/testing/activity/BUILD.bazel
+++ b/app/src/test/java/org/oppia/android/app/testing/activity/BUILD.bazel
@@ -18,6 +18,7 @@ oppia_android_test(
"//app/src/main/java/org/oppia/android/app/application:application_injector",
"//app/src/main/java/org/oppia/android/app/application:application_injector_provider",
"//app/src/main/java/org/oppia/android/app/application:common_application_modules",
+ "//app/src/main/java/org/oppia/android/app/application/testing:testing_build_flavor_module",
"//app/src/main/java/org/oppia/android/app/testing/activity:test_activity",
"//app/src/main/java/org/oppia/android/app/translation/testing:test_module",
"//domain",
diff --git a/app/src/test/java/org/oppia/android/app/testing/activity/TestActivityTest.kt b/app/src/test/java/org/oppia/android/app/testing/activity/TestActivityTest.kt
index bb510bd60c1..a2b18b6500a 100644
--- a/app/src/test/java/org/oppia/android/app/testing/activity/TestActivityTest.kt
+++ b/app/src/test/java/org/oppia/android/app/testing/activity/TestActivityTest.kt
@@ -21,6 +21,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -199,7 +200,7 @@ class TestActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/testing/administratorcontrols/AdministratorControlsFragmentTest.kt b/app/src/test/java/org/oppia/android/app/testing/administratorcontrols/AdministratorControlsFragmentTest.kt
index 1f95d05540e..9f0d0a5e4a3 100644
--- a/app/src/test/java/org/oppia/android/app/testing/administratorcontrols/AdministratorControlsFragmentTest.kt
+++ b/app/src/test/java/org/oppia/android/app/testing/administratorcontrols/AdministratorControlsFragmentTest.kt
@@ -30,6 +30,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -198,7 +199,7 @@ class AdministratorControlsFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/testing/options/OptionsFragmentTest.kt b/app/src/test/java/org/oppia/android/app/testing/options/OptionsFragmentTest.kt
index 3ebe6f52678..b0481e189ec 100644
--- a/app/src/test/java/org/oppia/android/app/testing/options/OptionsFragmentTest.kt
+++ b/app/src/test/java/org/oppia/android/app/testing/options/OptionsFragmentTest.kt
@@ -27,6 +27,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.options.AppLanguageFragment
@@ -252,7 +253,7 @@ class OptionsFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/testing/player/split/PlayerSplitScreenTest.kt b/app/src/test/java/org/oppia/android/app/testing/player/split/PlayerSplitScreenTest.kt
index a7d14d4a6c2..1b7ff73b2c3 100644
--- a/app/src/test/java/org/oppia/android/app/testing/player/split/PlayerSplitScreenTest.kt
+++ b/app/src/test/java/org/oppia/android/app/testing/player/split/PlayerSplitScreenTest.kt
@@ -20,6 +20,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -207,7 +208,7 @@ class PlayerSplitScreenTest {
AlgebraicExpressionInputModule::class, MathEquationInputModule::class,
SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/testing/player/state/StateFragmentAccessibilityTest.kt b/app/src/test/java/org/oppia/android/app/testing/player/state/StateFragmentAccessibilityTest.kt
index 11c88ca340c..369862684ef 100644
--- a/app/src/test/java/org/oppia/android/app/testing/player/state/StateFragmentAccessibilityTest.kt
+++ b/app/src/test/java/org/oppia/android/app/testing/player/state/StateFragmentAccessibilityTest.kt
@@ -24,6 +24,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.StateFragment
@@ -214,7 +215,7 @@ class StateFragmentAccessibilityTest {
AlgebraicExpressionInputModule::class, MathEquationInputModule::class,
SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/topic/info/TopicInfoFragmentLocalTest.kt b/app/src/test/java/org/oppia/android/app/topic/info/TopicInfoFragmentLocalTest.kt
index 68b9da3603a..2ce810912e1 100644
--- a/app/src/test/java/org/oppia/android/app/topic/info/TopicInfoFragmentLocalTest.kt
+++ b/app/src/test/java/org/oppia/android/app/topic/info/TopicInfoFragmentLocalTest.kt
@@ -18,6 +18,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.model.EventLog
@@ -156,7 +157,7 @@ class TopicInfoFragmentLocalTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/topic/lessons/TopicLessonsFragmentLocalTest.kt b/app/src/test/java/org/oppia/android/app/topic/lessons/TopicLessonsFragmentLocalTest.kt
index cd09a71eb8b..34e74865716 100644
--- a/app/src/test/java/org/oppia/android/app/topic/lessons/TopicLessonsFragmentLocalTest.kt
+++ b/app/src/test/java/org/oppia/android/app/topic/lessons/TopicLessonsFragmentLocalTest.kt
@@ -18,6 +18,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.model.EventLog
@@ -159,7 +160,7 @@ class TopicLessonsFragmentLocalTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/topic/questionplayer/QuestionPlayerActivityLocalTest.kt b/app/src/test/java/org/oppia/android/app/topic/questionplayer/QuestionPlayerActivityLocalTest.kt
index aedeb8e43cc..f095af739b5 100644
--- a/app/src/test/java/org/oppia/android/app/topic/questionplayer/QuestionPlayerActivityLocalTest.kt
+++ b/app/src/test/java/org/oppia/android/app/topic/questionplayer/QuestionPlayerActivityLocalTest.kt
@@ -35,6 +35,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.model.ProfileId
@@ -507,7 +508,7 @@ class QuestionPlayerActivityLocalTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/topic/revisioncard/RevisionCardActivityLocalTest.kt b/app/src/test/java/org/oppia/android/app/topic/revisioncard/RevisionCardActivityLocalTest.kt
index 510f56bd197..df63ed67dbb 100644
--- a/app/src/test/java/org/oppia/android/app/topic/revisioncard/RevisionCardActivityLocalTest.kt
+++ b/app/src/test/java/org/oppia/android/app/topic/revisioncard/RevisionCardActivityLocalTest.kt
@@ -18,6 +18,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.model.EventLog
@@ -148,7 +149,7 @@ class RevisionCardActivityLocalTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/translation/AppLanguageResourceHandlerTest.kt b/app/src/test/java/org/oppia/android/app/translation/AppLanguageResourceHandlerTest.kt
index 3ef2af12404..12c7ed9d8c3 100644
--- a/app/src/test/java/org/oppia/android/app/translation/AppLanguageResourceHandlerTest.kt
+++ b/app/src/test/java/org/oppia/android/app/translation/AppLanguageResourceHandlerTest.kt
@@ -22,6 +22,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.model.AppLanguageSelection
@@ -557,7 +558,7 @@ class AppLanguageResourceHandlerTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/translation/AppLanguageWatcherMixinTest.kt b/app/src/test/java/org/oppia/android/app/translation/AppLanguageWatcherMixinTest.kt
index 21ac94faac3..5b4a6ede4fb 100644
--- a/app/src/test/java/org/oppia/android/app/translation/AppLanguageWatcherMixinTest.kt
+++ b/app/src/test/java/org/oppia/android/app/translation/AppLanguageWatcherMixinTest.kt
@@ -23,6 +23,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.model.AppLanguageSelection
@@ -272,7 +273,7 @@ class AppLanguageWatcherMixinTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/translation/BUILD.bazel b/app/src/test/java/org/oppia/android/app/translation/BUILD.bazel
index 54853ed376f..171d07f5602 100644
--- a/app/src/test/java/org/oppia/android/app/translation/BUILD.bazel
+++ b/app/src/test/java/org/oppia/android/app/translation/BUILD.bazel
@@ -53,6 +53,7 @@ oppia_android_test(
"//app/src/main/java/org/oppia/android/app/application:application_injector",
"//app/src/main/java/org/oppia/android/app/application:application_injector_provider",
"//app/src/main/java/org/oppia/android/app/application:common_application_modules",
+ "//app/src/main/java/org/oppia/android/app/application/testing:testing_build_flavor_module",
"//app/src/main/java/org/oppia/android/app/translation:app_language_locale_handler",
"//app/src/main/java/org/oppia/android/app/translation/testing:test_module",
"//domain",
@@ -99,6 +100,7 @@ oppia_android_test(
"//app/src/main/java/org/oppia/android/app/application:application_injector",
"//app/src/main/java/org/oppia/android/app/application:application_injector_provider",
"//app/src/main/java/org/oppia/android/app/application:common_application_modules",
+ "//app/src/main/java/org/oppia/android/app/application/testing:testing_build_flavor_module",
"//app/src/main/java/org/oppia/android/app/translation/testing:test_module",
"//data/src/main/java/org/oppia/android/data/backends/gae:prod_module",
"//domain/src/main/java/org/oppia/android/domain/onboarding/testing:retriever_test_module",
diff --git a/app/src/test/java/org/oppia/android/app/utility/datetime/DateTimeUtilTest.kt b/app/src/test/java/org/oppia/android/app/utility/datetime/DateTimeUtilTest.kt
index 67d0b06add7..95ba0d375ff 100644
--- a/app/src/test/java/org/oppia/android/app/utility/datetime/DateTimeUtilTest.kt
+++ b/app/src/test/java/org/oppia/android/app/utility/datetime/DateTimeUtilTest.kt
@@ -22,6 +22,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -185,7 +186,7 @@ class DateTimeUtilTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class
+ SyncStatusModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/utility/math/BUILD.bazel b/app/src/test/java/org/oppia/android/app/utility/math/BUILD.bazel
index b50532b834d..24a84596c68 100644
--- a/app/src/test/java/org/oppia/android/app/utility/math/BUILD.bazel
+++ b/app/src/test/java/org/oppia/android/app/utility/math/BUILD.bazel
@@ -18,6 +18,7 @@ oppia_android_test(
"//app/src/main/java/org/oppia/android/app/application:application_injector",
"//app/src/main/java/org/oppia/android/app/application:application_injector_provider",
"//app/src/main/java/org/oppia/android/app/application:common_application_modules",
+ "//app/src/main/java/org/oppia/android/app/application/testing:testing_build_flavor_module",
"//app/src/main/java/org/oppia/android/app/translation/testing:test_module",
"//app/src/main/java/org/oppia/android/app/utility/math:math_expression_accessibility_util",
"//domain/src/main/java/org/oppia/android/domain/onboarding/testing:retriever_test_module",
diff --git a/app/src/test/java/org/oppia/android/app/utility/math/MathExpressionAccessibilityUtilTest.kt b/app/src/test/java/org/oppia/android/app/utility/math/MathExpressionAccessibilityUtilTest.kt
index d742b20a586..293f8b0e94a 100644
--- a/app/src/test/java/org/oppia/android/app/utility/math/MathExpressionAccessibilityUtilTest.kt
+++ b/app/src/test/java/org/oppia/android/app/utility/math/MathExpressionAccessibilityUtilTest.kt
@@ -21,6 +21,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.model.MathBinaryOperation
@@ -1331,7 +1332,7 @@ class MathExpressionAccessibilityUtilTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/build_flavors.bzl b/build_flavors.bzl
index a5ca841a737..ec541fe8046 100644
--- a/build_flavors.bzl
+++ b/build_flavors.bzl
@@ -3,7 +3,7 @@ Macros & definitions corresponding to Oppia binary build flavors.
"""
load("//:oppia_android_application.bzl", "declare_deployable_application", "oppia_android_application")
-load("//:version.bzl", "MAJOR_VERSION", "MINOR_VERSION", "OPPIA_ALPHA_KENYA_VERSION_CODE", "OPPIA_ALPHA_KITKAT_VERSION_CODE", "OPPIA_ALPHA_VERSION_CODE", "OPPIA_DEV_KITKAT_VERSION_CODE", "OPPIA_DEV_VERSION_CODE")
+load("//:version.bzl", "MAJOR_VERSION", "MINOR_VERSION", "OPPIA_ALPHA_KENYA_VERSION_CODE", "OPPIA_ALPHA_KITKAT_VERSION_CODE", "OPPIA_ALPHA_VERSION_CODE", "OPPIA_BETA_VERSION_CODE", "OPPIA_DEV_KITKAT_VERSION_CODE", "OPPIA_DEV_VERSION_CODE", "OPPIA_GA_VERSION_CODE")
# Defines the list of flavors available to build the Oppia app in. Note to developers: this list
# should be ordered by the development pipeline (i.e. features go through dev first, then other
@@ -14,6 +14,8 @@ AVAILABLE_FLAVORS = [
"alpha",
"alpha_kitkat",
"alpha_kenya",
+ "beta",
+ "ga",
]
# This file contains the list of classes that must be in the main dex list for the legacy multidex
@@ -108,6 +110,32 @@ _FLAVOR_METADATA = {
"version_code": OPPIA_ALPHA_KENYA_VERSION_CODE,
"application_class": ".app.application.alphakenya.AlphaKenyaOppiaApplication",
},
+ "beta": {
+ "manifest": "//app:src/main/AndroidManifest.xml",
+ "min_sdk_version": 21,
+ "target_sdk_version": 30,
+ "multidex": "native",
+ "proguard_specs": _PRODUCTION_PROGUARD_SPECS,
+ "production_release": True,
+ "deps": [
+ "//app/src/main/java/org/oppia/android/app/application/beta:beta_application",
+ ],
+ "version_code": OPPIA_BETA_VERSION_CODE,
+ "application_class": ".app.application.beta.BetaOppiaApplication",
+ },
+ "ga": {
+ "manifest": "//app:src/main/AndroidManifest.xml",
+ "min_sdk_version": 21,
+ "target_sdk_version": 30,
+ "multidex": "native",
+ "proguard_specs": _PRODUCTION_PROGUARD_SPECS,
+ "production_release": True,
+ "deps": [
+ "//app/src/main/java/org/oppia/android/app/application/ga:general_availability_application",
+ ],
+ "version_code": OPPIA_GA_VERSION_CODE,
+ "application_class": ".app.application.ga.GaOppiaApplication",
+ },
}
def _transform_android_manifest_impl(ctx):
diff --git a/data/BUILD.bazel b/data/BUILD.bazel
index aecd0697a62..8189af63a2f 100644
--- a/data/BUILD.bazel
+++ b/data/BUILD.bazel
@@ -6,6 +6,12 @@ This library provides data to the rest of the application.
load("@dagger//:workspace_defs.bzl", "dagger_rules")
load("//data:data_test.bzl", "data_test")
+filegroup(
+ name = "test_manifest",
+ srcs = ["src/test/AndroidManifest.xml"],
+ visibility = ["//:oppia_testing_visibility"],
+)
+
# keep sorted
TEST_DEPS = [
":dagger",
diff --git a/data/src/main/java/org/oppia/android/data/persistence/PersistentCacheStore.kt b/data/src/main/java/org/oppia/android/data/persistence/PersistentCacheStore.kt
index daacb9b8822..e7c081e6834 100644
--- a/data/src/main/java/org/oppia/android/data/persistence/PersistentCacheStore.kt
+++ b/data/src/main/java/org/oppia/android/data/persistence/PersistentCacheStore.kt
@@ -1,6 +1,6 @@
package org.oppia.android.data.persistence
-import android.content.Context
+import android.app.Application
import androidx.annotation.GuardedBy
import com.google.protobuf.MessageLite
import kotlinx.coroutines.Deferred
@@ -21,24 +21,27 @@ import kotlin.concurrent.withLock
/**
* An on-disk persistent cache for proto messages that ensures reads and writes happen in a
- * well-defined order. Note that if this cache is used like a [DataProvider], there is a race
- * condition between the initial store's data being retrieved and any early writes to the store
- * (writes generally win). If this is not ideal, callers should use [primeInMemoryCacheAsync] to
- * synchronously kick-off a read update to the store that is guaranteed to complete before any
- * writes. This will be reflected in the first time the store's state is delivered to a subscriber
- * to a LiveData version of this data provider.
+ * well-defined order.
*
- * Note that this is a fast-response data provider, meaning it will provide a pending [AsyncResult]
- * to subscribers immediately until the actual store is retrieved from disk.
+ * Note that if this cache is used like a [DataProvider], there is a race condition between the
+ * initial store's data being retrieved and any early writes to the store (writes generally win). If
+ * this is not ideal, callers should use [primeInMemoryAndDiskCacheAsync] to synchronously kick-off
+ * a read update to the store that is guaranteed to complete before any writes. This will be
+ * reflected in the first time the store's state is delivered to a subscriber to a LiveData version
+ * of this data provider. Note that this priming will always complete before any updates if it's
+ * called before updates/reads.
+ *
+ * Note that this is a fast-response data provider, meaning it will provide a [AsyncResult.Pending]
+ * result to subscribers immediately until the actual store is retrieved from disk.
*/
class PersistentCacheStore private constructor(
- context: Context,
+ application: Application,
cacheFactory: InMemoryBlockingCache.Factory,
private val asyncDataSubscriptionManager: AsyncDataSubscriptionManager,
cacheName: String,
private val initialValue: T,
- directory: File = context.filesDir
-) : DataProvider(context) {
+ directory: File = application.filesDir
+) : DataProvider(application) {
private val cacheFileName = "$cacheName.cache"
private val providerId = PersistentCacheStoreId(cacheFileName)
private val failureLock = ReentrantLock()
@@ -50,14 +53,21 @@ class PersistentCacheStore private constructor(
cacheFactory.create(CachePayload(state = CacheState.UNLOADED, value = initialValue))
init {
- cache.observeChanges {
- asyncDataSubscriptionManager.notifyChange(providerId)
+ cache.observeChanges { oldValue, newValue ->
+ // Only notice subscribers if the in-memory version of the cache actually changed (not just
+ // its load state). This extra check ensures that priming the cache does not unnecessarily
+ // trigger a notification which would result in an unnecessary retrieveData() call. The
+ // exception is that changing from an UNLOADED state always results in a notification (since
+ // UNLOADED is treated as 'pending' by default).
+ val wasPending = oldValue?.state == CacheState.UNLOADED
+ val nowPending = newValue?.state == CacheState.UNLOADED
+ if ((wasPending && !nowPending) || oldValue?.value != newValue?.value) {
+ asyncDataSubscriptionManager.notifyChange(providerId)
+ }
}
}
- override fun getId(): Any {
- return providerId
- }
+ override fun getId(): Any = providerId
override suspend fun retrieveData(): AsyncResult {
cache.readIfPresentAsync().await().let { cachePayload ->
@@ -85,69 +95,81 @@ class PersistentCacheStore private constructor(
}
/**
- * Kicks off a read operation to update the in-memory cache. This operation blocks against calls
- * to [storeDataAsync] and deferred calls to [retrieveData].
+ * Primes the current cache such that certain guarantees can be assured for both the in-memory and
+ * on-disk version of this cache, depending on which policies are selected.
*
- * @param forceUpdate indicates whether to force a reset of the in-memory cache. Note that this
- * only forces a load; if the load fails then the store will remain in its same state. If this
- * value is false (the default), it will only perform file I/O if the cache is not already
- * loaded into memory.
- * @returns a [Deferred] that completes upon the completion of priming the cache, or failure to do
- * so with the failed exception. Note that the failure reason will not be propagated to a
- * LiveData-converted version of this data provider, so it must be handled at the callsite for
- * this method.
- */
- fun primeInMemoryCacheAsync(forceUpdate: Boolean = false): Deferred {
- return cache.updateIfPresentAsync { cachePayload ->
- if (forceUpdate || cachePayload.state == CacheState.UNLOADED) {
- // Store the retrieved on-disk cache, if it's present (otherwise set up state such that
- // retrieveData() does not attempt to load the file from disk again since the attempt was
- // made here).
- loadFileCache(cachePayload)
- } else {
- // Otherwise, keep the cache the same.
- cachePayload
- }
- }
- }
-
- /**
- * Primes the current cache such that both the in-memory and on-disk versions of this cache are
- * guaranteed to be in sync, returning a [Deferred] that completes only after the operation is
- * finished.
+ * Note that the value of the returned [Deferred] is not useful. The state of the cache should
+ * monitored by treating this provider as a [DataProvider]. This method may result in an update
+ * notification to observers of this [DataProvider].
*
- * The provided [initialize] initializer will only ever be called if the on-disk cache is not yet
- * initialized, and it will be passed the initial value used to create this cache store. The value
- * it returns will be used to initialize both the in-memory and on-disk copies of the cache.
+ * Note also that this method is particularly useful in two specific cases:
+ * 1. When an instance of this cache needs to be loaded from disk before an update operation
+ * occurs (otherwise update() will likely complete before a load, overwriting the current
+ * on-disk cache state).
+ * 2. When the cache needs to be initialized exactly once to a specific value (such as the case
+ * when an ID that cannot change after initialization needs to be generated and stored exactly
+ * once).
*
- * The value of the returned [Deferred] is not useful. The state of the cache should monitored by
- * treating this provider as a [DataProvider]. This method may result in multiple update
- * notifications to observers of this [DataProvider], but the latest value will be the source of
- * truth.
+ * Each of the above states are possible using different combinations of the provided [UpdateMode]
+ * and [PublishMode] parameters.
*
- * Where [primeInMemoryCacheAsync] is useful to ensure any on-disk cache is properly loaded into
- * memory prior to using a cache store, this method is useful when a disk cache has a
- * contextually-sensitive initialization routine (such as an ID that cannot change after
- * initialization) as it ensures a reliable, initial clean state for the cache store that will be
- * consistent with future runs of the app.
+ * Finally, this method succeeding more or less guarantees that the cache store is now in a good
+ * state (i.e. it will even recover from a corrupted or invalid disk cache file).
+ *
+ * @param updateMode how the cache should be changed (depending on whether it's been loaded yet,
+ * and whether it has an on-disk cache)
+ * @param publishMode whether changes to the cache's in-memory copy during priming should be kept
+ * in-memory and sent to observers (otherwise, only store the results on-disk and do not
+ * notify changes). Note that the in-memory cache *will* be updated if it hasn't yet been
+ * initialized (which may mean saving a result from [update]).
+ * @param update an optional function to transform the cache's current (in-memory if loaded, or
+ * from-disk if not) state to a new state, and then update the on-disk cache (and potentially
+ * the in-memory cache based on [publishMode]). Note that if the cache has not been loaded yet
+ * and has no on-disk copy then the cache's [initialValue] will be passed, instead. Omitting
+ * this transformation will just ensure the in-memory and/or on-disk cache are appropriately
+ * initialized.
+ * @return a [Deferred] tracking the success/failure of priming this cache store
*/
- fun primeInMemoryAndDiskCacheAsync(initialize: (T) -> T): Deferred {
+ fun primeInMemoryAndDiskCacheAsync(
+ updateMode: UpdateMode,
+ publishMode: PublishMode,
+ update: (T) -> T = { it }
+ ): Deferred {
return cache.updateIfPresentAsync { cachePayload ->
- when (cachePayload.state) {
+ // It's expected 'oldState' to match 'cachePayload' unless the cache hasn't yet been read
+ // (since then 'cachePayload' will be based on the store's default value).
+ val (oldState, newState) = when (cachePayload.state) {
CacheState.UNLOADED -> {
val loadedPayload = loadFileCache(cachePayload)
when (loadedPayload.state) {
// The state should never stay as UNLOADED.
CacheState.UNLOADED ->
error("Something went wrong loading the cache during priming: $cacheFile")
- CacheState.IN_MEMORY_ONLY -> storeFileCache(loadedPayload, initialize) // Needs saving.
- CacheState.IN_MEMORY_AND_ON_DISK -> loadedPayload // Loaded from disk successfully.
+ CacheState.IN_MEMORY_ONLY -> {
+ // Needs saving. In this case, there is no "old" value since the cache was never
+ // initialized.
+ val storedPayload = storeFileCache(loadedPayload, update)
+ storedPayload to storedPayload
+ }
+ CacheState.IN_MEMORY_AND_ON_DISK -> // Loaded from disk successfully.
+ loadedPayload to loadedPayload.maybeReprimePayload(updateMode, update)
}
}
- // This generally indicates that something went wrong reading the on-disk cache, so make
- // sure it's properly initialized.
- CacheState.IN_MEMORY_ONLY -> storeFileCache(cachePayload, initialize)
- CacheState.IN_MEMORY_AND_ON_DISK -> cachePayload
+ // Generally indicates that the cache was loaded but never written.
+ CacheState.IN_MEMORY_ONLY -> cachePayload to storeFileCache(cachePayload, update)
+ CacheState.IN_MEMORY_AND_ON_DISK ->
+ cachePayload to cachePayload.maybeReprimePayload(updateMode, update)
+ }
+
+ // The returned payload is always expected to be IN_MEMORY_AND_ON_DISK, but the in-memory copy
+ // may be intentionally kept out-of-date so that cache reads pick up the original version
+ // rather than the new one stored on-disk. Furthermore, this method guarantees by this point
+ // that the cache is in a good, non-error state (so the error is cleared in case one occurred
+ // during early priming).
+ failureLock.withLock { deferredLoadCacheFailure = null }
+ return@updateIfPresentAsync when (publishMode) {
+ PublishMode.PUBLISH_TO_IN_MEMORY_CACHE -> newState
+ PublishMode.DO_NOT_PUBLISH_TO_IN_MEMORY_CACHE -> newState.copy(value = oldState.value)
}
}
}
@@ -290,6 +312,16 @@ class PersistentCacheStore private constructor(
)
}
+ private fun CachePayload.maybeReprimePayload(
+ updateMode: UpdateMode,
+ initialize: (T) -> T
+ ): CachePayload {
+ return when (updateMode) {
+ UpdateMode.UPDATE_IF_NEW_CACHE -> this // Nothing extra to do.
+ UpdateMode.UPDATE_ALWAYS -> storeFileCache(this, initialize) // Recompute the payload.
+ }
+ }
+
private data class PersistentCacheStoreId(private val id: String)
/** Represents different states the cache store can be in. */
@@ -306,13 +338,46 @@ class PersistentCacheStore private constructor(
private data class CachePayload(val state: CacheState, val value: T)
+ /**
+ * The mode of on-disk data updating that can be configured for specific operations like cache
+ * priming.
+ *
+ * This mode only configures on-disk data changes, not in-memory (see [PublishMode] for that).
+ */
+ enum class UpdateMode {
+ /** Indicates that the on-disk cache should only be changed if it doesn't already exist. */
+ UPDATE_IF_NEW_CACHE,
+
+ /**
+ * Indicates that the on-disk cache should always be changed regardless of if it already exists.
+ */
+ UPDATE_ALWAYS
+ }
+
+ /**
+ * The mode of in-memory data updating that can be configured for specific operations like cache
+ * priming.
+ *
+ * This mode only configures in-memory data changes, not on-disk (see [UpdateMode] for that).
+ */
+ enum class PublishMode {
+ /**
+ * Indicates that data changes should update the in-memory cache and be broadcast to
+ * subscribers.
+ */
+ PUBLISH_TO_IN_MEMORY_CACHE,
+
+ /** Indicates that data changes should not change the in-memory cache. */
+ DO_NOT_PUBLISH_TO_IN_MEMORY_CACHE
+ }
+
/**
* An injectable factory for [PersistentCacheStore]s. The stores themselves should be retrievable
* from central controllers since they can't be placed directly in the Dagger graph.
*/
@Singleton
class Factory @Inject constructor(
- private val context: Context,
+ private val application: Application,
private val cacheFactory: InMemoryBlockingCache.Factory,
private val asyncDataSubscriptionManager: AsyncDataSubscriptionManager,
private val directoryManagementUtil: DirectoryManagementUtil
@@ -325,7 +390,7 @@ class PersistentCacheStore private constructor(
*/
fun create(cacheName: String, initialValue: T): PersistentCacheStore {
return PersistentCacheStore(
- context,
+ application,
cacheFactory,
asyncDataSubscriptionManager,
cacheName,
@@ -344,7 +409,7 @@ class PersistentCacheStore private constructor(
): PersistentCacheStore {
val profileDirectory = directoryManagementUtil.getOrCreateDir(profileId.internalId.toString())
return PersistentCacheStore(
- context,
+ application,
cacheFactory,
asyncDataSubscriptionManager,
cacheName,
diff --git a/data/src/test/java/org/oppia/android/data/persistence/BUILD.bazel b/data/src/test/java/org/oppia/android/data/persistence/BUILD.bazel
new file mode 100644
index 00000000000..9a0686181ab
--- /dev/null
+++ b/data/src/test/java/org/oppia/android/data/persistence/BUILD.bazel
@@ -0,0 +1,32 @@
+"""
+Tests for infrastructure that provides data persistence support for the rest of the app.
+"""
+
+load("@dagger//:workspace_defs.bzl", "dagger_rules")
+load("//:oppia_android_test.bzl", "oppia_android_test")
+
+oppia_android_test(
+ name = "PersistentCacheStoreTest",
+ srcs = ["PersistentCacheStoreTest.kt"],
+ custom_package = "org.oppia.android.data.persistence",
+ test_class = "org.oppia.android.data.persistence.PersistentCacheStoreTest",
+ test_manifest = "//data:test_manifest",
+ deps = [
+ ":dagger",
+ "//data/src/main/java/org/oppia/android/data/persistence:cache_store",
+ "//model/src/main/proto:test_models",
+ "//testing",
+ "//testing/src/main/java/org/oppia/android/testing/data:data_provider_test_monitor",
+ "//testing/src/main/java/org/oppia/android/testing/robolectric:test_module",
+ "//testing/src/main/java/org/oppia/android/testing/threading:test_module",
+ "//third_party:androidx_test_ext_junit",
+ "//third_party:com_google_truth_extensions_truth-liteproto-extension",
+ "//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",
+ ],
+)
+
+dagger_rules()
diff --git a/data/src/test/java/org/oppia/android/data/persistence/PersistentCacheStoreTest.kt b/data/src/test/java/org/oppia/android/data/persistence/PersistentCacheStoreTest.kt
index c14643c3baa..6143cf71b39 100644
--- a/data/src/test/java/org/oppia/android/data/persistence/PersistentCacheStoreTest.kt
+++ b/data/src/test/java/org/oppia/android/data/persistence/PersistentCacheStoreTest.kt
@@ -19,19 +19,32 @@ import kotlinx.coroutines.async
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import org.junit.Before
+import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.never
+import org.mockito.Mockito.verify
+import org.mockito.junit.MockitoJUnit
+import org.mockito.junit.MockitoRule
import org.oppia.android.app.model.TestMessage
+import org.oppia.android.data.persistence.PersistentCacheStore.PublishMode.DO_NOT_PUBLISH_TO_IN_MEMORY_CACHE
+import org.oppia.android.data.persistence.PersistentCacheStore.PublishMode.PUBLISH_TO_IN_MEMORY_CACHE
+import org.oppia.android.data.persistence.PersistentCacheStore.UpdateMode.UPDATE_ALWAYS
+import org.oppia.android.data.persistence.PersistentCacheStore.UpdateMode.UPDATE_IF_NEW_CACHE
+import org.oppia.android.data.persistence.PersistentCacheStoreTest.SubscriptionCallback.Companion.toAsyncChange
import org.oppia.android.testing.TestLogReportingModule
import org.oppia.android.testing.data.AsyncResultSubject.Companion.assertThat
import org.oppia.android.testing.data.DataProviderTestMonitor
import org.oppia.android.testing.robolectric.RobolectricModule
import org.oppia.android.testing.threading.TestCoroutineDispatchers
import org.oppia.android.testing.threading.TestDispatcherModule
+import org.oppia.android.util.data.AsyncDataSubscriptionManager
import org.oppia.android.util.data.AsyncResult
import org.oppia.android.util.data.DataProviders
import org.oppia.android.util.data.DataProvidersInjector
import org.oppia.android.util.data.DataProvidersInjectorProvider
+import org.oppia.android.util.data.ObserveAsyncChange
import org.oppia.android.util.threading.BackgroundDispatcher
import org.robolectric.annotation.Config
import org.robolectric.annotation.LooperMode
@@ -42,6 +55,7 @@ import java.io.IOException
import java.lang.IllegalStateException
import javax.inject.Inject
import javax.inject.Singleton
+import kotlin.reflect.full.staticFunctions
private const val CACHE_NAME_1 = "test_cache_1"
private const val CACHE_NAME_2 = "test_cache_2"
@@ -55,16 +69,38 @@ private const val CACHE_NAME_2 = "test_cache_2"
@Config(application = PersistentCacheStoreTest.TestApplication::class)
class PersistentCacheStoreTest {
private companion object {
- private val TEST_MESSAGE_V1 = TestMessage.newBuilder().setIntValue(1).build()
- private val TEST_MESSAGE_V2 = TestMessage.newBuilder().setIntValue(2).build()
+ private const val TEST_INT_V1 = 1
+ private const val TEST_INT_V2 = 2
+ private const val TEST_STR_V1 = "test string"
+ private val DEFAULT_TEST_MESSAGE = TestMessage.getDefaultInstance()
+ private val TEST_INT_MESSAGE_V1 = createTestMessage(intValue = TEST_INT_V1)
+ private val TEST_INT_MESSAGE_V2 = createTestMessage(intValue = TEST_INT_V2)
+
+ private fun TestMessage.addString(strValue: String) = toBuilder().apply {
+ this.strValue = strValue
+ }.build()
+
+ private fun createTestMessage(
+ intValue: Int = DEFAULT_TEST_MESSAGE.intValue,
+ strValue: String = DEFAULT_TEST_MESSAGE.strValue
+ ) = TestMessage.newBuilder().apply {
+ this.intValue = intValue
+ this.strValue = strValue
+ }.build()
}
+ @Rule
+ @JvmField
+ val mockitoRule: MockitoRule = MockitoJUnit.rule()
+
@Inject lateinit var context: Context
@Inject lateinit var cacheFactory: PersistentCacheStore.Factory
@Inject lateinit var dataProviders: DataProviders
@Inject lateinit var testCoroutineDispatchers: TestCoroutineDispatchers
@field:[Inject BackgroundDispatcher] lateinit var backgroundDispatcher: CoroutineDispatcher
@Inject lateinit var monitorFactory: DataProviderTestMonitor.Factory
+ @Inject lateinit var asyncDataSubscriptionManager: AsyncDataSubscriptionManager
+ @Mock lateinit var mockSubscriptionCallback: SubscriptionCallback
private val backgroundDispatcherScope by lazy { CoroutineScope(backgroundDispatcher) }
@@ -107,12 +143,12 @@ class PersistentCacheStoreTest {
@Test
fun testCache_nonDefaultInitialState_loaded_providesCorrectInitialVal() {
- val cacheStore = cacheFactory.create(CACHE_NAME_1, TEST_MESSAGE_V1)
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, TEST_INT_MESSAGE_V1)
val value = monitorFactory.waitForNextSuccessfulResult(cacheStore)
// Caches can have non-default initial states.
- assertThat(value).isEqualTo(TEST_MESSAGE_V1)
+ assertThat(value).isEqualTo(TEST_INT_MESSAGE_V1)
}
@Test
@@ -120,27 +156,28 @@ class PersistentCacheStoreTest {
val cacheStore = cacheFactory.create(CACHE_NAME_1, TestMessage.getDefaultInstance())
monitorFactory.waitForNextSuccessfulResult(cacheStore)
- val storeOp = cacheStore.storeDataAsync { TEST_MESSAGE_V1 }
+ val storeOp = cacheStore.storeDataAsync { TEST_INT_MESSAGE_V1 }
testCoroutineDispatchers.advanceUntilIdle()
// The store operation should be completed, and the observer should be notified of the changed
// value.
assertThat(storeOp.isCompleted).isTrue()
- assertThat(monitorFactory.waitForNextSuccessfulResult(cacheStore)).isEqualTo(TEST_MESSAGE_V1)
+ assertThat(monitorFactory.waitForNextSuccessfulResult(cacheStore))
+ .isEqualTo(TEST_INT_MESSAGE_V1)
}
@Test
fun testCache_registerObserver_updateBefore_observesUpdatedStateInitially() {
val cacheStore = cacheFactory.create(CACHE_NAME_1, TestMessage.getDefaultInstance())
- val storeOp = cacheStore.storeDataAsync { TEST_MESSAGE_V1 }
+ val storeOp = cacheStore.storeDataAsync { TEST_INT_MESSAGE_V1 }
testCoroutineDispatchers.advanceUntilIdle()
// The store operation should be completed, and the observer's only call should be the updated
// state.
val value = monitorFactory.waitForNextSuccessfulResult(cacheStore)
assertThat(storeOp.isCompleted).isTrue()
- assertThat(value).isEqualTo(TEST_MESSAGE_V1)
+ assertThat(value).isEqualTo(TEST_INT_MESSAGE_V1)
}
@Test
@@ -149,7 +186,7 @@ class PersistentCacheStoreTest {
val monitor = monitorFactory.createMonitor(cacheStore)
monitor.waitForNextSuccessResult()
- val storeOp = cacheStore.storeDataAsync(updateInMemoryCache = false) { TEST_MESSAGE_V1 }
+ val storeOp = cacheStore.storeDataAsync(updateInMemoryCache = false) { TEST_INT_MESSAGE_V1 }
testCoroutineDispatchers.advanceUntilIdle()
// The store operation should be completed, but the observe will not be notified of changes
@@ -162,7 +199,7 @@ class PersistentCacheStoreTest {
fun testCache_noMemoryCacheUpdate_updateBeforeReg_observesUpdatedState() {
val cacheStore = cacheFactory.create(CACHE_NAME_1, TestMessage.getDefaultInstance())
- val storeOp = cacheStore.storeDataAsync(updateInMemoryCache = false) { TEST_MESSAGE_V1 }
+ val storeOp = cacheStore.storeDataAsync(updateInMemoryCache = false) { TEST_INT_MESSAGE_V1 }
testCoroutineDispatchers.advanceUntilIdle()
// The store operation should be completed, but the observer will receive the updated state
@@ -170,13 +207,14 @@ class PersistentCacheStoreTest {
// NB: This may not be ideal behavior long-term; the store may need to be updated to be more
// resilient to these types of scenarios.
assertThat(storeOp.isCompleted).isTrue()
- assertThat(monitorFactory.waitForNextSuccessfulResult(cacheStore)).isEqualTo(TEST_MESSAGE_V1)
+ assertThat(monitorFactory.waitForNextSuccessfulResult(cacheStore))
+ .isEqualTo(TEST_INT_MESSAGE_V1)
}
@Test
fun testCache_updated_newCache_newObserver_observesNewValue() {
val cacheStore1 = cacheFactory.create(CACHE_NAME_1, TestMessage.getDefaultInstance())
- val storeOp = cacheStore1.storeDataAsync { TEST_MESSAGE_V1 }
+ val storeOp = cacheStore1.storeDataAsync { TEST_INT_MESSAGE_V1 }
testCoroutineDispatchers.advanceUntilIdle()
// Create a new cache with the same name.
@@ -187,13 +225,14 @@ class PersistentCacheStoreTest {
// refresh since UI components should share the same cache instance via an application-bound
// controller object.
assertThat(storeOp.isCompleted).isTrue()
- assertThat(monitorFactory.waitForNextSuccessfulResult(cacheStore2)).isEqualTo(TEST_MESSAGE_V1)
+ assertThat(monitorFactory.waitForNextSuccessfulResult(cacheStore2))
+ .isEqualTo(TEST_INT_MESSAGE_V1)
}
@Test
fun testCache_updated_noInMemoryCacheUpdate_newCache_newObserver_observesNewVal() {
val cacheStore1 = cacheFactory.create(CACHE_NAME_1, TestMessage.getDefaultInstance())
- val storeOp = cacheStore1.storeDataAsync(updateInMemoryCache = false) { TEST_MESSAGE_V1 }
+ val storeOp = cacheStore1.storeDataAsync(updateInMemoryCache = false) { TEST_INT_MESSAGE_V1 }
testCoroutineDispatchers.advanceUntilIdle()
// Create a new cache with the same name.
@@ -205,108 +244,28 @@ class PersistentCacheStoreTest {
// Dagger component refresh since UI components should share the same cache instance via an
// application-bound controller object.
assertThat(storeOp.isCompleted).isTrue()
- assertThat(monitorFactory.waitForNextSuccessfulResult(cacheStore2)).isEqualTo(TEST_MESSAGE_V1)
+ assertThat(monitorFactory.waitForNextSuccessfulResult(cacheStore2))
+ .isEqualTo(TEST_INT_MESSAGE_V1)
}
@Test
fun testExistingDiskCache_newCacheObject_updateNoMemThenRead_receivesNewValue() {
val cacheStore1 = cacheFactory.create(CACHE_NAME_1, TestMessage.getDefaultInstance())
val storeOp1 =
- cacheStore1.storeDataAsync(updateInMemoryCache = false) { TEST_MESSAGE_V1 }
+ cacheStore1.storeDataAsync(updateInMemoryCache = false) { TEST_INT_MESSAGE_V1 }
testCoroutineDispatchers.advanceUntilIdle()
// Create a new cache with the same name and update it, then observe it.
val cacheStore2 = cacheFactory.create(CACHE_NAME_1, TestMessage.getDefaultInstance())
- val storeOp2 = cacheStore2.storeDataAsync(updateInMemoryCache = false) { TEST_MESSAGE_V2 }
+ val storeOp2 = cacheStore2.storeDataAsync(updateInMemoryCache = false) { TEST_INT_MESSAGE_V2 }
testCoroutineDispatchers.advanceUntilIdle()
// Both operations should be complete, and the observer will receive the latest value since the
// update was posted before the read occurred.
assertThat(storeOp1.isCompleted).isTrue()
assertThat(storeOp2.isCompleted).isTrue()
- assertThat(monitorFactory.waitForNextSuccessfulResult(cacheStore2)).isEqualTo(TEST_MESSAGE_V2)
- }
-
- @Test
- fun testExistingDiskCache_newObject_updateNoMemThenRead_primed_receivesPrevVal() {
- val cacheStore1 = cacheFactory.create(CACHE_NAME_1, TestMessage.getDefaultInstance())
- val storeOp1 =
- cacheStore1.storeDataAsync(updateInMemoryCache = false) { TEST_MESSAGE_V1 }
- testCoroutineDispatchers.advanceUntilIdle()
-
- // Create a new cache with the same name and update it, then observe it. However, first prime
- // it.
- val cacheStore2 = cacheFactory.create(CACHE_NAME_1, TestMessage.getDefaultInstance())
- val primeOp = cacheStore2.primeInMemoryCacheAsync()
- testCoroutineDispatchers.advanceUntilIdle()
- val storeOp2 = cacheStore2.storeDataAsync(updateInMemoryCache = false) { TEST_MESSAGE_V2 }
- testCoroutineDispatchers.advanceUntilIdle()
-
- // All operations should be complete, but the observer will receive the previous update rather
- // than the latest since it wasn't updated in memory and the cache was pre-primed.
- assertThat(storeOp1.isCompleted).isTrue()
- assertThat(storeOp2.isCompleted).isTrue()
- assertThat(primeOp.isCompleted).isTrue()
- assertThat(monitorFactory.waitForNextSuccessfulResult(cacheStore2)).isEqualTo(TEST_MESSAGE_V1)
- }
-
- @Test
- fun testExistingDiskCache_newObject_updateMemThenRead_primed_receivesNewVal() {
- val cacheStore1 = cacheFactory.create(CACHE_NAME_1, TestMessage.getDefaultInstance())
- val storeOp1 =
- cacheStore1.storeDataAsync(updateInMemoryCache = false) { TEST_MESSAGE_V1 }
- testCoroutineDispatchers.advanceUntilIdle()
-
- // Create a new cache with the same name and update it, then observe it. However, first prime
- // it.
- val cacheStore2 = cacheFactory.create(CACHE_NAME_1, TestMessage.getDefaultInstance())
- val primeOp = cacheStore2.primeInMemoryCacheAsync()
- testCoroutineDispatchers.advanceUntilIdle()
- val storeOp2 = cacheStore2.storeDataAsync { TEST_MESSAGE_V2 }
- testCoroutineDispatchers.advanceUntilIdle()
-
- // Similar to the previous test, except due to the in-memory update the observer will receive
- // the latest result regardless of the cache priming.
- assertThat(storeOp1.isCompleted).isTrue()
- assertThat(storeOp2.isCompleted).isTrue()
- assertThat(primeOp.isCompleted).isTrue()
- assertThat(monitorFactory.waitForNextSuccessfulResult(cacheStore2)).isEqualTo(TEST_MESSAGE_V2)
- }
-
- @Test
- fun testCache_primed_afterStoreUpdateWithoutMemUpdate_notForced_observesOldValue() {
- val cacheStore = cacheFactory.create(CACHE_NAME_1, TestMessage.getDefaultInstance())
- // Force initializing the store's in-memory cache
- monitorFactory.waitForNextSuccessfulResult(cacheStore)
-
- val storeOp = cacheStore.storeDataAsync(updateInMemoryCache = false) { TEST_MESSAGE_V1 }
- testCoroutineDispatchers.advanceUntilIdle()
- val primeOp = cacheStore.primeInMemoryCacheAsync(forceUpdate = false)
- testCoroutineDispatchers.advanceUntilIdle()
-
- // Both ops will succeed, and the observer will receive the old value due to the update not
- // changing the in-memory cache, and the prime no-oping due to the cache already being
- // initialized.
- assertThat(storeOp.isCompleted).isTrue()
- assertThat(primeOp.isCompleted).isTrue()
- assertThat(monitorFactory.waitForNextSuccessfulResult(cacheStore)).isEqualToDefaultInstance()
- }
-
- @Test
- fun testCache_primed_afterStoreUpdateWithoutMemoryUpdate_forced_observesNewValue() {
- val cacheStore = cacheFactory.create(CACHE_NAME_1, TestMessage.getDefaultInstance())
- monitorFactory.waitForNextSuccessfulResult(cacheStore)
-
- val storeOp = cacheStore.storeDataAsync(updateInMemoryCache = false) { TEST_MESSAGE_V1 }
- testCoroutineDispatchers.advanceUntilIdle()
- val primeOp = cacheStore.primeInMemoryCacheAsync(forceUpdate = true)
- testCoroutineDispatchers.advanceUntilIdle()
-
- // The observer will receive the new value because the prime was forced. This ensures the
- // store's in-memory cache is now up-to-date with the on-disk representation.
- assertThat(storeOp.isCompleted).isTrue()
- assertThat(primeOp.isCompleted).isTrue()
- assertThat(monitorFactory.waitForNextSuccessfulResult(cacheStore)).isEqualTo(TEST_MESSAGE_V1)
+ assertThat(monitorFactory.waitForNextSuccessfulResult(cacheStore2))
+ .isEqualTo(TEST_INT_MESSAGE_V2)
}
@Test
@@ -325,7 +284,7 @@ class PersistentCacheStoreTest {
@Test
fun testCache_update_clear_resetsCacheToInitialState() {
val cacheStore = cacheFactory.create(CACHE_NAME_1, TestMessage.getDefaultInstance())
- val storeOp = cacheStore.storeDataAsync { TEST_MESSAGE_V1 }
+ val storeOp = cacheStore.storeDataAsync { TEST_INT_MESSAGE_V1 }
testCoroutineDispatchers.advanceUntilIdle()
val clearOp = cacheStore.clearCacheAsync()
@@ -340,7 +299,7 @@ class PersistentCacheStoreTest {
@Test
fun testCache_update_existingObserver_clear_isNotifiedOfClear() {
val cacheStore = cacheFactory.create(CACHE_NAME_1, TestMessage.getDefaultInstance())
- val storeOp = cacheStore.storeDataAsync { TEST_MESSAGE_V1 }
+ val storeOp = cacheStore.storeDataAsync { TEST_INT_MESSAGE_V1 }
testCoroutineDispatchers.advanceUntilIdle()
val monitor = monitorFactory.createMonitor(cacheStore)
@@ -357,34 +316,36 @@ class PersistentCacheStoreTest {
@Test
fun testCache_update_newCache_observesInitialState() {
val cacheStore1 = cacheFactory.create(CACHE_NAME_1, TestMessage.getDefaultInstance())
- val storeOp = cacheStore1.storeDataAsync { TEST_MESSAGE_V1 }
+ val storeOp = cacheStore1.storeDataAsync { TEST_INT_MESSAGE_V1 }
testCoroutineDispatchers.advanceUntilIdle()
val clearOp = cacheStore1.clearCacheAsync()
testCoroutineDispatchers.advanceUntilIdle()
- val cacheStore2 = cacheFactory.create(CACHE_NAME_1, TEST_MESSAGE_V2)
+ val cacheStore2 = cacheFactory.create(CACHE_NAME_1, TEST_INT_MESSAGE_V2)
// The new observer should observe that there's no persisted on-disk store since it has a
// different default value that would only be used if there wasn't already on-disk storage.
assertThat(storeOp.isCompleted).isTrue()
assertThat(clearOp.isCompleted).isTrue()
- assertThat(monitorFactory.waitForNextSuccessfulResult(cacheStore2)).isEqualTo(TEST_MESSAGE_V2)
+ assertThat(monitorFactory.waitForNextSuccessfulResult(cacheStore2))
+ .isEqualTo(TEST_INT_MESSAGE_V2)
}
@Test
fun testMultipleCaches_oneUpdates_newCacheSameNameDiffInit_observesUpdatedValue() {
val cacheStore1 = cacheFactory.create(CACHE_NAME_1, TestMessage.getDefaultInstance())
- val storeOp = cacheStore1.storeDataAsync { TEST_MESSAGE_V1 }
+ val storeOp = cacheStore1.storeDataAsync { TEST_INT_MESSAGE_V1 }
testCoroutineDispatchers.advanceUntilIdle()
- val cacheStore2 = cacheFactory.create(CACHE_NAME_1, TEST_MESSAGE_V2)
+ val cacheStore2 = cacheFactory.create(CACHE_NAME_1, TEST_INT_MESSAGE_V2)
// The new cache should observe the updated on-disk value rather than its new default since an
// on-disk value exists. This isn't a very realistic test since all caches should use default
// proto instances for initialization, but it's a possible edge case that should at least have
// established behavior that can be adjusted later if it isn't desirable in some circumstances.
assertThat(storeOp.isCompleted).isTrue()
- assertThat(monitorFactory.waitForNextSuccessfulResult(cacheStore2)).isEqualTo(TEST_MESSAGE_V1)
+ assertThat(monitorFactory.waitForNextSuccessfulResult(cacheStore2))
+ .isEqualTo(TEST_INT_MESSAGE_V1)
}
@Test
@@ -394,7 +355,7 @@ class PersistentCacheStoreTest {
val monitor1 = monitorFactory.createMonitor(cacheStore1)
val monitor2 = monitorFactory.createMonitor(cacheStore2)
- val storeOp = cacheStore1.storeDataAsync { TEST_MESSAGE_V1 }
+ val storeOp = cacheStore1.storeDataAsync { TEST_INT_MESSAGE_V1 }
testCoroutineDispatchers.advanceUntilIdle()
// The observer of the second store will be not notified of the change to the first store since
@@ -408,7 +369,7 @@ class PersistentCacheStoreTest {
fun testMultipleCaches_diffNames_oneUpdates_cachesRecreated_onlyOneObservesVal() {
val cacheStore1a = cacheFactory.create(CACHE_NAME_1, TestMessage.getDefaultInstance())
cacheFactory.create(CACHE_NAME_2, TestMessage.getDefaultInstance())
- val storeOp = cacheStore1a.storeDataAsync { TEST_MESSAGE_V1 }
+ val storeOp = cacheStore1a.storeDataAsync { TEST_INT_MESSAGE_V1 }
testCoroutineDispatchers.advanceUntilIdle()
// Recreate the stores and observe them.
@@ -418,14 +379,15 @@ class PersistentCacheStoreTest {
// Only the observer of the first cache should notice the update since they are different
// caches.
assertThat(storeOp.isCompleted).isTrue()
- assertThat(monitorFactory.waitForNextSuccessfulResult(cacheStore1b)).isEqualTo(TEST_MESSAGE_V1)
+ assertThat(monitorFactory.waitForNextSuccessfulResult(cacheStore1b))
+ .isEqualTo(TEST_INT_MESSAGE_V1)
assertThat(monitorFactory.waitForNextSuccessfulResult(cacheStore2b)).isEqualToDefaultInstance()
}
@Test
fun testNewCache_fileCorrupted_providesError() {
val cacheStore1 = cacheFactory.create(CACHE_NAME_1, TestMessage.getDefaultInstance())
- val storeOp = cacheStore1.storeDataAsync { TEST_MESSAGE_V1 }
+ val storeOp = cacheStore1.storeDataAsync { TEST_INT_MESSAGE_V1 }
testCoroutineDispatchers.advanceUntilIdle()
// Simulate the file being corrupted & reopen the file in a new store.
@@ -470,17 +432,1000 @@ class PersistentCacheStoreTest {
assertThat(monitorFactory.waitForNextSuccessfulResult(cacheStore).strValue).isEqualTo("initial")
}
+ @Test
+ fun testNoPrime_noDiskCache_unloadedCache_noNotifyOrLoadedOrDisk() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ // Verify that a default cache store performs no notifications, nor does it create a disk cache.
+ // This helps to establish the baseline assumed in later testPrime_* tests.
+ verifyCacheStoreDidNotSendDataProviderNotification()
+ assertThat(getCacheFile(CACHE_NAME_1).exists()).isFalse()
+ }
+
+ @Test
+ fun testPrime_noDiskCache_unloadedCache_updateIfNew_publish_noXform_initsMemDiskNotify() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(UPDATE_IF_NEW_CACHE, PUBLISH_TO_IN_MEMORY_CACHE)
+ primeDeferred.waitForSuccessfulResult()
+
+ verifyCacheStoreSentDataProviderNotification()
+ verifyDiskCacheHasValue(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, DEFAULT_TEST_MESSAGE)
+ }
+
+ @Test
+ fun testPrime_noDiskCache_unloadedCache_updateIfNew_publish_withXform_initsMemDiskNotify() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(UPDATE_IF_NEW_CACHE, PUBLISH_TO_IN_MEMORY_CACHE) {
+ it.addString(TEST_STR_V1)
+ }
+ primeDeferred.waitForSuccessfulResult()
+
+ val expectedMessage = createTestMessage(strValue = TEST_STR_V1)
+ verifyCacheStoreSentDataProviderNotification()
+ verifyDiskCacheHasValue(CACHE_NAME_1, expectedMessage)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, expectedMessage)
+ }
+
+ @Test
+ fun testPrime_noDiskCache_unloadedCache_updateIfNew_noPublish_noXform_initsMemDiskNotify() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(
+ UPDATE_IF_NEW_CACHE, DO_NOT_PUBLISH_TO_IN_MEMORY_CACHE
+ )
+ primeDeferred.waitForSuccessfulResult()
+
+ // The cache will notify in this case since the in-memory cache wasn't yet initialized.
+ verifyCacheStoreSentDataProviderNotification()
+ verifyDiskCacheHasValue(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, DEFAULT_TEST_MESSAGE)
+ }
+
+ @Test
+ fun testPrime_noDiskCache_unloadedCache_updateIfNew_noPublish_withXform_initsMemDiskNotify() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(
+ UPDATE_IF_NEW_CACHE, DO_NOT_PUBLISH_TO_IN_MEMORY_CACHE
+ ) { it.addString(TEST_STR_V1) }
+ primeDeferred.waitForSuccessfulResult()
+
+ // The cache will notify in this case since the in-memory cache wasn't yet initialized.
+ val expectedMessage = createTestMessage(strValue = TEST_STR_V1)
+ verifyCacheStoreSentDataProviderNotification()
+ verifyDiskCacheHasValue(CACHE_NAME_1, expectedMessage)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, expectedMessage)
+ }
+
+ @Test
+ fun testPrime_noDiskCache_unloadedCache_updateAlways_publish_noXform_initsMemDiskNotify() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(UPDATE_ALWAYS, PUBLISH_TO_IN_MEMORY_CACHE)
+ primeDeferred.waitForSuccessfulResult()
+
+ verifyCacheStoreSentDataProviderNotification()
+ verifyDiskCacheHasValue(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, DEFAULT_TEST_MESSAGE)
+ }
+
+ @Test
+ fun testPrime_noDiskCache_unloadedCache_updateAlways_publish_withXform_initsMemDiskNotify() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(UPDATE_ALWAYS, PUBLISH_TO_IN_MEMORY_CACHE) {
+ it.addString(TEST_STR_V1)
+ }
+ primeDeferred.waitForSuccessfulResult()
+
+ val expectedMessage = createTestMessage(strValue = TEST_STR_V1)
+ verifyCacheStoreSentDataProviderNotification()
+ verifyDiskCacheHasValue(CACHE_NAME_1, expectedMessage)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, expectedMessage)
+ }
+
+ @Test
+ fun testPrime_noDiskCache_unloadedCache_updateAlways_noPublish_noXform_initsMemDiskNotify() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(UPDATE_ALWAYS, DO_NOT_PUBLISH_TO_IN_MEMORY_CACHE)
+ primeDeferred.waitForSuccessfulResult()
+
+ // The cache will notify in this case since the in-memory cache wasn't yet initialized.
+ verifyCacheStoreSentDataProviderNotification()
+ verifyDiskCacheHasValue(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, DEFAULT_TEST_MESSAGE)
+ }
+
+ @Test
+ fun testPrime_noDiskCache_unloadedCache_updateAlways_noPublish_withXform_initsMemDiskNotify() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(UPDATE_ALWAYS, DO_NOT_PUBLISH_TO_IN_MEMORY_CACHE) {
+ it.addString(TEST_STR_V1)
+ }
+ primeDeferred.waitForSuccessfulResult()
+
+ // The cache will notify in this case since the in-memory cache wasn't yet initialized.
+ val expectedMessage = createTestMessage(strValue = TEST_STR_V1)
+ verifyCacheStoreSentDataProviderNotification()
+ verifyDiskCacheHasValue(CACHE_NAME_1, expectedMessage)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, expectedMessage)
+ }
+
+ @Test
+ fun testPrime_noDiskCache_cacheFromMem_updateIfNew_publish_noXform_initsDiskOnlyNoNotify() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ loadCacheIntoMemory(cacheStore)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(UPDATE_IF_NEW_CACHE, PUBLISH_TO_IN_MEMORY_CACHE)
+ primeDeferred.waitForSuccessfulResult()
+
+ // No notification is sent since the in-memory cache is already initialized ahead of priming.
+ // The on-disk cache still needs to be initialized.
+ verifyCacheStoreDidNotSendDataProviderNotification()
+ verifyDiskCacheHasValue(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, DEFAULT_TEST_MESSAGE)
+ }
+
+ @Test
+ fun testPrime_noDiskCache_cacheFromMem_updateIfNew_publish_withXform_initsMemDiskNotify() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ loadCacheIntoMemory(cacheStore)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(UPDATE_IF_NEW_CACHE, PUBLISH_TO_IN_MEMORY_CACHE) {
+ it.addString(TEST_STR_V1)
+ }
+ primeDeferred.waitForSuccessfulResult()
+
+ val expectedMessage = createTestMessage(strValue = TEST_STR_V1)
+ verifyCacheStoreSentDataProviderNotification()
+ verifyDiskCacheHasValue(CACHE_NAME_1, expectedMessage)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, expectedMessage)
+ }
+
+ @Test
+ fun testPrime_noDiskCache_cacheFromMem_updateIfNew_noPublish_noXform_initsDiskOnlyNoNotify() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ loadCacheIntoMemory(cacheStore)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(
+ UPDATE_IF_NEW_CACHE, DO_NOT_PUBLISH_TO_IN_MEMORY_CACHE
+ )
+ primeDeferred.waitForSuccessfulResult()
+
+ verifyCacheStoreDidNotSendDataProviderNotification()
+ verifyDiskCacheHasValue(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, DEFAULT_TEST_MESSAGE)
+ }
+
+ @Test
+ fun testPrime_noDiskCache_cacheFromMem_updateIfNew_noPublish_withXform_initsDiskOnlyNoNotify() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ loadCacheIntoMemory(cacheStore)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(
+ UPDATE_IF_NEW_CACHE, DO_NOT_PUBLISH_TO_IN_MEMORY_CACHE
+ ) { it.addString(TEST_STR_V1) }
+ primeDeferred.waitForSuccessfulResult()
+
+ // The in-memory cache will not be updated in this situation since it was already loaded ahead
+ // of priming the cache (and thus established).
+ val expectedDiskMessage = createTestMessage(strValue = TEST_STR_V1)
+ verifyCacheStoreDidNotSendDataProviderNotification()
+ verifyDiskCacheHasValue(CACHE_NAME_1, expectedDiskMessage)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, DEFAULT_TEST_MESSAGE)
+ }
+
+ @Test
+ fun testPrime_noDiskCache_cacheFromMem_updateAlways_publish_noXform_initsDiskOnlyNoNotify() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ loadCacheIntoMemory(cacheStore)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(UPDATE_ALWAYS, PUBLISH_TO_IN_MEMORY_CACHE)
+ primeDeferred.waitForSuccessfulResult()
+
+ // Despite the update & publish policies, no notification will be sent here since priming
+ // doesn't change the cache store and the store has already be initialized into memory.
+ verifyCacheStoreDidNotSendDataProviderNotification()
+ verifyDiskCacheHasValue(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, DEFAULT_TEST_MESSAGE)
+ }
+
+ @Test
+ fun testPrime_noDiskCache_cacheFromMem_updateAlways_publish_withXform_initsMemDiskNotify() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ loadCacheIntoMemory(cacheStore)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(UPDATE_ALWAYS, PUBLISH_TO_IN_MEMORY_CACHE) {
+ it.addString(TEST_STR_V1)
+ }
+ primeDeferred.waitForSuccessfulResult()
+
+ val expectedMessage = createTestMessage(strValue = TEST_STR_V1)
+ verifyCacheStoreSentDataProviderNotification()
+ verifyDiskCacheHasValue(CACHE_NAME_1, expectedMessage)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, expectedMessage)
+ }
+
+ @Test
+ fun testPrime_noDiskCache_cacheFromMem_updateAlways_noPublish_noXform_initsDiskOnlyNoNotify() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ loadCacheIntoMemory(cacheStore)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(UPDATE_ALWAYS, DO_NOT_PUBLISH_TO_IN_MEMORY_CACHE)
+ primeDeferred.waitForSuccessfulResult()
+
+ verifyCacheStoreDidNotSendDataProviderNotification()
+ verifyDiskCacheHasValue(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, DEFAULT_TEST_MESSAGE)
+ }
+
+ @Test
+ fun testPrime_noDiskCache_cacheFromMem_updateAlways_noPublish_withXform_initsDiskOnlyNoNotify() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ loadCacheIntoMemory(cacheStore)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(UPDATE_ALWAYS, DO_NOT_PUBLISH_TO_IN_MEMORY_CACHE) {
+ it.addString(TEST_STR_V1)
+ }
+ primeDeferred.waitForSuccessfulResult()
+
+ // The in-memory cache will not be updated in this situation since it was already loaded ahead
+ // of priming the cache (and thus established).
+ val expectedDiskMessage = createTestMessage(strValue = TEST_STR_V1)
+ verifyCacheStoreDidNotSendDataProviderNotification()
+ verifyDiskCacheHasValue(CACHE_NAME_1, expectedDiskMessage)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, DEFAULT_TEST_MESSAGE)
+ }
+
+ @Test
+ fun testPrime_diskCache_unloadedCache_updateIfNew_publish_noXform_initsMemOnlyNotify() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ writeFileCache(CACHE_NAME_1, TEST_INT_MESSAGE_V1)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(UPDATE_IF_NEW_CACHE, PUBLISH_TO_IN_MEMORY_CACHE)
+ primeDeferred.waitForSuccessfulResult()
+
+ // Effectively, only the in-memory version of the cache changes.
+ verifyCacheStoreSentDataProviderNotification()
+ verifyDiskCacheHasValue(CACHE_NAME_1, TEST_INT_MESSAGE_V1)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, TEST_INT_MESSAGE_V1)
+ }
+
+ @Test
+ fun testPrime_diskCache_unloadedCache_updateIfNew_publish_withXform_initsMemOnlyNotify() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ writeFileCache(CACHE_NAME_1, TEST_INT_MESSAGE_V1)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(UPDATE_IF_NEW_CACHE, PUBLISH_TO_IN_MEMORY_CACHE) {
+ it.addString(TEST_STR_V1)
+ }
+ primeDeferred.waitForSuccessfulResult()
+
+ // The in-memory version should be initialized, but not updated (since it already exists). Plus,
+ // the disk cache should not be read or updated.
+ val expectedMessage = createTestMessage(intValue = TEST_INT_V1)
+ verifyCacheStoreSentDataProviderNotification()
+ verifyDiskCacheHasValue(CACHE_NAME_1, expectedMessage)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, expectedMessage)
+ }
+
+ @Test
+ fun testPrime_diskCache_unloadedCache_updateIfNew_noPublish_noXform_initsMemOnlyNotify() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ writeFileCache(CACHE_NAME_1, TEST_INT_MESSAGE_V1)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(
+ UPDATE_IF_NEW_CACHE, DO_NOT_PUBLISH_TO_IN_MEMORY_CACHE
+ )
+ primeDeferred.waitForSuccessfulResult()
+
+ // Effectively, only the in-memory version of the cache changes, which in turn still results in
+ // a notification being sent.
+ verifyCacheStoreSentDataProviderNotification()
+ verifyDiskCacheHasValue(CACHE_NAME_1, TEST_INT_MESSAGE_V1)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, TEST_INT_MESSAGE_V1)
+ }
+
+ @Test
+ fun testPrime_diskCache_unloadedCache_updateIfNew_noPublish_withXform_initsMemOnlyNotify() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ writeFileCache(CACHE_NAME_1, TEST_INT_MESSAGE_V1)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(
+ UPDATE_IF_NEW_CACHE, DO_NOT_PUBLISH_TO_IN_MEMORY_CACHE
+ ) { it.addString(TEST_STR_V1) }
+ primeDeferred.waitForSuccessfulResult()
+
+ // The in-memory version should be initialized, but not updated (since it already exists). Plus,
+ // the disk cache should not be read or updated. However, this will result in a notification
+ // since the in-memory cache was unloaded.
+ val expectedMessage = createTestMessage(intValue = TEST_INT_V1)
+ verifyCacheStoreSentDataProviderNotification()
+ verifyDiskCacheHasValue(CACHE_NAME_1, expectedMessage)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, expectedMessage)
+ }
+
+ @Test
+ fun testPrime_diskCache_unloadedCache_updateAlways_publish_noXform_initsMemOnlyNotify() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ writeFileCache(CACHE_NAME_1, TEST_INT_MESSAGE_V1)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(UPDATE_ALWAYS, PUBLISH_TO_IN_MEMORY_CACHE)
+ primeDeferred.waitForSuccessfulResult()
+
+ // Effectively, only the in-memory version of the cache changes.
+ verifyCacheStoreSentDataProviderNotification()
+ verifyDiskCacheHasValue(CACHE_NAME_1, TEST_INT_MESSAGE_V1)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, TEST_INT_MESSAGE_V1)
+ }
+
+ @Test
+ fun testPrime_diskCache_unloadedCache_updateAlways_publish_withXform_initsMemDiskNotify() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ writeFileCache(CACHE_NAME_1, TEST_INT_MESSAGE_V1)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(UPDATE_ALWAYS, PUBLISH_TO_IN_MEMORY_CACHE) {
+ it.addString(TEST_STR_V1)
+ }
+ primeDeferred.waitForSuccessfulResult()
+
+ // Both the in-memory and on-disk variants should change per the UPDATE_ALWAYS policy.
+ val expectedMessage = createTestMessage(intValue = TEST_INT_V1, strValue = TEST_STR_V1)
+ verifyCacheStoreSentDataProviderNotification()
+ verifyDiskCacheHasValue(CACHE_NAME_1, expectedMessage)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, expectedMessage)
+ }
+
+ @Test
+ fun testPrime_diskCache_unloadedCache_updateAlways_noPublish_noXform_initsMemOnlyNotify() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ writeFileCache(CACHE_NAME_1, TEST_INT_MESSAGE_V1)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(UPDATE_ALWAYS, DO_NOT_PUBLISH_TO_IN_MEMORY_CACHE)
+ primeDeferred.waitForSuccessfulResult()
+
+ // Effectively, only the in-memory version of the cache changes, which in turn still results in
+ // a notification being sent.
+ verifyCacheStoreSentDataProviderNotification()
+ verifyDiskCacheHasValue(CACHE_NAME_1, TEST_INT_MESSAGE_V1)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, TEST_INT_MESSAGE_V1)
+ }
+
+ @Test
+ fun testPrime_diskCache_unloadedCache_updateAlways_noPublish_withXform_initsDiskOnlyNotify() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ writeFileCache(CACHE_NAME_1, TEST_INT_MESSAGE_V1)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(UPDATE_ALWAYS, DO_NOT_PUBLISH_TO_IN_MEMORY_CACHE) {
+ it.addString(TEST_STR_V1)
+ }
+ primeDeferred.waitForSuccessfulResult()
+
+ // Only the on-disk variant should actually change (per UPDATE_ALWAYS), since the publish policy
+ // indicates that the in-memory cache shouldn't reflect the new value (only the existing disk
+ // cache). Furthermore, a notification will be sent anyway since the in-memory cache hasn't yet
+ // been initialized.
+ val expectedMemoryMessage = createTestMessage(intValue = TEST_INT_V1)
+ val expectedDiskMessage = createTestMessage(intValue = TEST_INT_V1, strValue = TEST_STR_V1)
+ verifyCacheStoreSentDataProviderNotification()
+ verifyDiskCacheHasValue(CACHE_NAME_1, expectedDiskMessage)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, expectedMemoryMessage)
+ }
+
+ @Test
+ fun testPrime_diskCache_cacheFromDisk_updateIfNew_publish_noXform_noChangeOrNotify() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ writeFileCache(CACHE_NAME_1, TEST_INT_MESSAGE_V1)
+ loadCacheIntoMemory(cacheStore)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(UPDATE_IF_NEW_CACHE, PUBLISH_TO_IN_MEMORY_CACHE)
+ primeDeferred.waitForSuccessfulResult()
+
+ // Nothing should be notified, or change on-disk or in-memory (other initing the cache).
+ verifyCacheStoreDidNotSendDataProviderNotification()
+ verifyDiskCacheHasValue(CACHE_NAME_1, TEST_INT_MESSAGE_V1)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, TEST_INT_MESSAGE_V1)
+ }
+
+ @Test
+ fun testPrime_diskCache_cacheFromDisk_updateIfNew_publish_withXform_noChangeOrNotify() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ writeFileCache(CACHE_NAME_1, TEST_INT_MESSAGE_V1)
+ loadCacheIntoMemory(cacheStore)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(UPDATE_IF_NEW_CACHE, PUBLISH_TO_IN_MEMORY_CACHE) {
+ it.addString(TEST_STR_V1)
+ }
+ primeDeferred.waitForSuccessfulResult()
+
+ // Nothing should be notified, or change on-disk or in-memory per UPDATE_IF_NEW_CACHE.
+ val expectedMessage = createTestMessage(intValue = TEST_INT_V1)
+ verifyCacheStoreDidNotSendDataProviderNotification()
+ verifyDiskCacheHasValue(CACHE_NAME_1, expectedMessage)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, expectedMessage)
+ }
+
+ @Test
+ fun testPrime_diskCache_cacheFromDisk_updateIfNew_noPublish_noXform_noChangeOrNotify() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ writeFileCache(CACHE_NAME_1, TEST_INT_MESSAGE_V1)
+ loadCacheIntoMemory(cacheStore)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(
+ UPDATE_IF_NEW_CACHE, DO_NOT_PUBLISH_TO_IN_MEMORY_CACHE
+ )
+ primeDeferred.waitForSuccessfulResult()
+
+ // Nothing should be notified, or change on-disk or in-memory (other initing the cache).
+ verifyCacheStoreDidNotSendDataProviderNotification()
+ verifyDiskCacheHasValue(CACHE_NAME_1, TEST_INT_MESSAGE_V1)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, TEST_INT_MESSAGE_V1)
+ }
+
+ @Test
+ fun testPrime_diskCache_cacheFromDisk_updateIfNew_noPublish_withXform_noChangeOrNotify() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ writeFileCache(CACHE_NAME_1, TEST_INT_MESSAGE_V1)
+ loadCacheIntoMemory(cacheStore)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(
+ UPDATE_IF_NEW_CACHE, DO_NOT_PUBLISH_TO_IN_MEMORY_CACHE
+ ) { it.addString(TEST_STR_V1) }
+ primeDeferred.waitForSuccessfulResult()
+
+ // Nothing should be notified, or change on-disk or in-memory per UPDATE_IF_NEW_CACHE.
+ val expectedMessage = createTestMessage(intValue = TEST_INT_V1)
+ verifyCacheStoreDidNotSendDataProviderNotification()
+ verifyDiskCacheHasValue(CACHE_NAME_1, expectedMessage)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, expectedMessage)
+ }
+
+ @Test
+ fun testPrime_diskCache_cacheFromDisk_updateAlways_publish_noXform_noChangeOrNotify() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ writeFileCache(CACHE_NAME_1, TEST_INT_MESSAGE_V1)
+ loadCacheIntoMemory(cacheStore)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(UPDATE_ALWAYS, PUBLISH_TO_IN_MEMORY_CACHE)
+ primeDeferred.waitForSuccessfulResult()
+
+ // Nothing should be notified, or change on-disk or in-memory (other initing the cache).
+ verifyCacheStoreDidNotSendDataProviderNotification()
+ verifyDiskCacheHasValue(CACHE_NAME_1, TEST_INT_MESSAGE_V1)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, TEST_INT_MESSAGE_V1)
+ }
+
+ @Test
+ fun testPrime_diskCache_cacheFromDisk_updateAlways_publish_withXform_initsMemDiskNotify() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ writeFileCache(CACHE_NAME_1, TEST_INT_MESSAGE_V1)
+ loadCacheIntoMemory(cacheStore)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(UPDATE_ALWAYS, PUBLISH_TO_IN_MEMORY_CACHE) {
+ it.addString(TEST_STR_V1)
+ }
+ primeDeferred.waitForSuccessfulResult()
+
+ // Since the policy is to always update the cache, the in-memory & on-disk versions should be
+ // updated plus a notification sent.
+ val expectedMessage = createTestMessage(intValue = TEST_INT_V1, strValue = TEST_STR_V1)
+ verifyCacheStoreSentDataProviderNotification()
+ verifyDiskCacheHasValue(CACHE_NAME_1, expectedMessage)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, expectedMessage)
+ }
+
+ @Test
+ fun testPrime_diskCache_cacheFromDisk_updateAlways_noPublish_noXform_noChangeOrNotify() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ writeFileCache(CACHE_NAME_1, TEST_INT_MESSAGE_V1)
+ loadCacheIntoMemory(cacheStore)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(UPDATE_ALWAYS, DO_NOT_PUBLISH_TO_IN_MEMORY_CACHE)
+ primeDeferred.waitForSuccessfulResult()
+
+ // Nothing should be notified, or change on-disk or in-memory (other initing the cache).
+ verifyCacheStoreDidNotSendDataProviderNotification()
+ verifyDiskCacheHasValue(CACHE_NAME_1, TEST_INT_MESSAGE_V1)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, TEST_INT_MESSAGE_V1)
+ }
+
+ @Test
+ fun testPrime_diskCache_cacheFromDisk_updateAlways_noPublish_withXform_initsMemDiskNoNotify() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ writeFileCache(CACHE_NAME_1, TEST_INT_MESSAGE_V1)
+ loadCacheIntoMemory(cacheStore)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(UPDATE_ALWAYS, DO_NOT_PUBLISH_TO_IN_MEMORY_CACHE) {
+ it.addString(TEST_STR_V1)
+ }
+ primeDeferred.waitForSuccessfulResult()
+
+ // Since the policy is to always update the cache, the on-disk version should be updated.
+ // However, the in-memory cache will not be updated since it was already loaded ahead of priming
+ // (and hence established). Furthermore, no notification sent per the publish policy.
+ val expectedMemoryMessage = createTestMessage(intValue = TEST_INT_V1)
+ val expectedDiskMessage = createTestMessage(intValue = TEST_INT_V1, strValue = TEST_STR_V1)
+ verifyCacheStoreDidNotSendDataProviderNotification()
+ verifyDiskCacheHasValue(CACHE_NAME_1, expectedDiskMessage)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, expectedMemoryMessage)
+ }
+
+ @Test
+ fun testPrime_badDiskCache_unloadedCache_updateIfNew_publish_noXform_initsMemDiskNotify() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ corruptFileCache(CACHE_NAME_1)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(UPDATE_IF_NEW_CACHE, PUBLISH_TO_IN_MEMORY_CACHE)
+ primeDeferred.waitForSuccessfulResult()
+
+ // A corrupted disk cache is treated as a completely new cache.
+ verifyCacheStoreSentDataProviderNotification()
+ verifyDiskCacheHasValue(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, DEFAULT_TEST_MESSAGE)
+ }
+
+ @Test
+ fun testPrime_badDiskCache_unloadedCache_updateIfNew_publish_withXform_initsMemDiskNotify() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ corruptFileCache(CACHE_NAME_1)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(UPDATE_IF_NEW_CACHE, PUBLISH_TO_IN_MEMORY_CACHE) {
+ it.addString(TEST_STR_V1)
+ }
+ primeDeferred.waitForSuccessfulResult()
+
+ // A corrupted disk cache is treated as a completely new cache.
+ val expectedMessage = createTestMessage(strValue = TEST_STR_V1)
+ verifyCacheStoreSentDataProviderNotification()
+ verifyDiskCacheHasValue(CACHE_NAME_1, expectedMessage)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, expectedMessage)
+ }
+
+ @Test
+ fun testPrime_badDiskCache_unloadedCache_updateIfNew_noPublish_noXform_initsMemDiskNotify() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ corruptFileCache(CACHE_NAME_1)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(
+ UPDATE_IF_NEW_CACHE, DO_NOT_PUBLISH_TO_IN_MEMORY_CACHE
+ )
+ primeDeferred.waitForSuccessfulResult()
+
+ // A corrupted disk cache is treated as a completely new cache. Because of that, a notification
+ // is actually sent in this case.
+ verifyCacheStoreSentDataProviderNotification()
+ verifyDiskCacheHasValue(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, DEFAULT_TEST_MESSAGE)
+ }
+
+ @Test
+ fun testPrime_badDiskCache_unloadedCache_updateIfNew_noPublish_withXform_initsMemDiskNotify() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ corruptFileCache(CACHE_NAME_1)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(
+ UPDATE_IF_NEW_CACHE, DO_NOT_PUBLISH_TO_IN_MEMORY_CACHE
+ ) { it.addString(TEST_STR_V1) }
+ primeDeferred.waitForSuccessfulResult()
+
+ // A corrupted disk cache is treated as a completely new cache. Because of that, a notification
+ // is actually sent in this case.
+ val expectedMessage = createTestMessage(strValue = TEST_STR_V1)
+ verifyCacheStoreSentDataProviderNotification()
+ verifyDiskCacheHasValue(CACHE_NAME_1, expectedMessage)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, expectedMessage)
+ }
+
+ @Test
+ fun testPrime_badDiskCache_unloadedCache_updateAlways_publish_noXform_initsMemDiskNotify() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ corruptFileCache(CACHE_NAME_1)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(UPDATE_ALWAYS, PUBLISH_TO_IN_MEMORY_CACHE)
+ primeDeferred.waitForSuccessfulResult()
+
+ verifyCacheStoreSentDataProviderNotification()
+ verifyDiskCacheHasValue(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, DEFAULT_TEST_MESSAGE)
+ }
+
+ @Test
+ fun testPrime_badDiskCache_unloadedCache_updateAlways_publish_withXform_initsMemDiskNotify() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ corruptFileCache(CACHE_NAME_1)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(UPDATE_ALWAYS, PUBLISH_TO_IN_MEMORY_CACHE) {
+ it.addString(TEST_STR_V1)
+ }
+ primeDeferred.waitForSuccessfulResult()
+
+ val expectedMessage = createTestMessage(strValue = TEST_STR_V1)
+ verifyCacheStoreSentDataProviderNotification()
+ verifyDiskCacheHasValue(CACHE_NAME_1, expectedMessage)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, expectedMessage)
+ }
+
+ @Test
+ fun testPrime_badDiskCache_unloadedCache_updateAlways_noPublish_noXform_initsMemDiskNotify() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ corruptFileCache(CACHE_NAME_1)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(UPDATE_ALWAYS, DO_NOT_PUBLISH_TO_IN_MEMORY_CACHE)
+ primeDeferred.waitForSuccessfulResult()
+
+ // A corrupted disk cache is treated as a completely new cache. Because of that, a notification
+ // is actually sent in this case.
+ verifyCacheStoreSentDataProviderNotification()
+ verifyDiskCacheHasValue(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, DEFAULT_TEST_MESSAGE)
+ }
+
+ @Test
+ fun testPrime_badDiskCache_unloadedCache_updateAlways_noPublish_withXform_initsMemDiskNotify() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ corruptFileCache(CACHE_NAME_1)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(UPDATE_ALWAYS, DO_NOT_PUBLISH_TO_IN_MEMORY_CACHE) {
+ it.addString(TEST_STR_V1)
+ }
+ primeDeferred.waitForSuccessfulResult()
+
+ // A corrupted disk cache is treated as a completely new cache. Because of that, a notification
+ // is actually sent in this case.
+ val expectedMessage = createTestMessage(strValue = TEST_STR_V1)
+ verifyCacheStoreSentDataProviderNotification()
+ verifyDiskCacheHasValue(CACHE_NAME_1, expectedMessage)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, expectedMessage)
+ }
+
+ @Test
+ fun testPrime_badDiskCache_cacheFromMem_updateIfNew_publish_noXform_initsDiskOnlyNoNotify() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ corruptFileCache(CACHE_NAME_1)
+ loadCacheIntoMemory(cacheStore)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(UPDATE_IF_NEW_CACHE, PUBLISH_TO_IN_MEMORY_CACHE)
+ primeDeferred.waitForSuccessfulResult()
+
+ // The corrupted cache should have failed to be read, so it will be treated as a new cache.
+ // However, only the disk cache actually needs to be updated since the in-memory one has already
+ // been established prior to priming (which is also why no notification is sent in this case).
+ verifyCacheStoreDidNotSendDataProviderNotification()
+ verifyDiskCacheHasValue(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, DEFAULT_TEST_MESSAGE)
+ }
+
+ @Test
+ fun testPrime_badDiskCache_cacheFromMem_updateIfNew_publish_withXform_initsMemDiskNotify() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ corruptFileCache(CACHE_NAME_1)
+ loadCacheIntoMemory(cacheStore)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(UPDATE_IF_NEW_CACHE, PUBLISH_TO_IN_MEMORY_CACHE) {
+ it.addString(TEST_STR_V1)
+ }
+ primeDeferred.waitForSuccessfulResult()
+
+ // The corrupted cache should have failed to be read, so it will be treated as a new cache.
+ val expectedMessage = createTestMessage(strValue = TEST_STR_V1)
+ verifyCacheStoreSentDataProviderNotification()
+ verifyDiskCacheHasValue(CACHE_NAME_1, expectedMessage)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, expectedMessage)
+ }
+
+ @Test
+ fun testPrime_badDiskCache_cacheFromMem_updateIfNew_noPublish_noXform_initsDiskOnlyNoNotify() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ corruptFileCache(CACHE_NAME_1)
+ loadCacheIntoMemory(cacheStore)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(
+ UPDATE_IF_NEW_CACHE, DO_NOT_PUBLISH_TO_IN_MEMORY_CACHE
+ )
+ primeDeferred.waitForSuccessfulResult()
+
+ // The corrupted cache should have failed to be read, so it will be treated as a new cache.
+ verifyCacheStoreDidNotSendDataProviderNotification()
+ verifyDiskCacheHasValue(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, DEFAULT_TEST_MESSAGE)
+ }
+
+ @Test
+ fun testPrime_badDiskCache_cacheFromMem_updateIfNew_noPublish_withXform_initsMemDiskNoNotify() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ corruptFileCache(CACHE_NAME_1)
+ loadCacheIntoMemory(cacheStore)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(
+ UPDATE_IF_NEW_CACHE, DO_NOT_PUBLISH_TO_IN_MEMORY_CACHE
+ ) { it.addString(TEST_STR_V1) }
+ primeDeferred.waitForSuccessfulResult()
+
+ // The corrupted cache should have failed to be read, so it will be treated as a new cache. Note
+ // though that the initial load operation will result in the in-memory cache becoming the
+ // default cache value (and thus different from the on-disk version) per the publish policy.
+ val expectedOnDiskMessage = createTestMessage(strValue = TEST_STR_V1)
+ verifyCacheStoreDidNotSendDataProviderNotification()
+ verifyDiskCacheHasValue(CACHE_NAME_1, expectedOnDiskMessage)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, DEFAULT_TEST_MESSAGE)
+ }
+
+ @Test
+ fun testPrime_badDiskCache_cacheFromMem_updateAlways_publish_noXform_initsDiskOnlyNoNotify() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ corruptFileCache(CACHE_NAME_1)
+ loadCacheIntoMemory(cacheStore)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(UPDATE_ALWAYS, PUBLISH_TO_IN_MEMORY_CACHE)
+ primeDeferred.waitForSuccessfulResult()
+
+ // Despite the update & publish policies, no notification will be sent here since priming
+ // doesn't change the cache store and the store has already be initialized into memory.
+ verifyCacheStoreDidNotSendDataProviderNotification()
+ verifyDiskCacheHasValue(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, DEFAULT_TEST_MESSAGE)
+ }
+
+ @Test
+ fun testPrime_badDiskCache_cacheFromMem_updateAlways_publish_withXform_initsMemDiskNotify() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ corruptFileCache(CACHE_NAME_1)
+ loadCacheIntoMemory(cacheStore)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(UPDATE_ALWAYS, PUBLISH_TO_IN_MEMORY_CACHE) {
+ it.addString(TEST_STR_V1)
+ }
+ primeDeferred.waitForSuccessfulResult()
+
+ val expectedMessage = createTestMessage(strValue = TEST_STR_V1)
+ verifyCacheStoreSentDataProviderNotification()
+ verifyDiskCacheHasValue(CACHE_NAME_1, expectedMessage)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, expectedMessage)
+ }
+
+ @Test
+ fun testPrime_badDiskCache_cacheFromMem_updateAlways_noPublish_noXform_initsDiskOnlyNoNotify() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ corruptFileCache(CACHE_NAME_1)
+ loadCacheIntoMemory(cacheStore)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(UPDATE_ALWAYS, DO_NOT_PUBLISH_TO_IN_MEMORY_CACHE)
+ primeDeferred.waitForSuccessfulResult()
+
+ verifyCacheStoreDidNotSendDataProviderNotification()
+ verifyDiskCacheHasValue(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, DEFAULT_TEST_MESSAGE)
+ }
+
+ @Test
+ fun testPrime_badDiskCache_cacheFromMem_updateAlways_noPublish_withXform_initsDiskOnlyNoNotify() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, DEFAULT_TEST_MESSAGE)
+ corruptFileCache(CACHE_NAME_1)
+ loadCacheIntoMemory(cacheStore)
+ subscribeToCacheStoreChanges(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(UPDATE_ALWAYS, DO_NOT_PUBLISH_TO_IN_MEMORY_CACHE) {
+ it.addString(TEST_STR_V1)
+ }
+ primeDeferred.waitForSuccessfulResult()
+
+ // The in-memory cache will not be updated in this situation since it was already loaded ahead
+ // of priming the cache (and thus established).
+ val expectedDiskMessage = createTestMessage(strValue = TEST_STR_V1)
+ verifyCacheStoreDidNotSendDataProviderNotification()
+ verifyDiskCacheHasValue(CACHE_NAME_1, expectedDiskMessage)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, DEFAULT_TEST_MESSAGE)
+ }
+
+ @Test
+ fun testPrime_badDiskCache_cacheFromMem_passesDefaultMessageInToTransform() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, TEST_INT_MESSAGE_V1)
+ corruptFileCache(CACHE_NAME_1)
+ loadCacheIntoMemory(cacheStore)
+
+ val primeDeferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(UPDATE_ALWAYS, DO_NOT_PUBLISH_TO_IN_MEMORY_CACHE) {
+ it
+ }
+ primeDeferred.waitForSuccessfulResult()
+
+ // Verify that the proto passed into prime's update method is the default in this case (since
+ // the disk cache is corrupted).
+ val expectedMessage = createTestMessage(intValue = TEST_INT_V1)
+ verifyDiskCacheHasValue(CACHE_NAME_1, expectedMessage)
+ verifyCacheStoreHasInMemoryValue(CACHE_NAME_1, cacheStore, expectedMessage)
+ }
+
+ @Test
+ fun testPrimeInMemoryAndOnDisk_newObject_updateNoMemThenRead_primed_receivesPrevVal() {
+ val cacheStore1 = cacheFactory.create(CACHE_NAME_1, TestMessage.getDefaultInstance())
+ val storeOp1 =
+ cacheStore1.storeDataAsync(updateInMemoryCache = false) { TEST_INT_MESSAGE_V1 }
+ testCoroutineDispatchers.advanceUntilIdle()
+
+ // Create a new cache with the same name and update it, then observe it. However, first prime
+ // it.
+ val cacheStore2 = cacheFactory.create(CACHE_NAME_1, TestMessage.getDefaultInstance())
+ val primeOp =
+ cacheStore2.primeInMemoryAndDiskCacheAsync(
+ updateMode = UPDATE_IF_NEW_CACHE, publishMode = DO_NOT_PUBLISH_TO_IN_MEMORY_CACHE
+ )
+ testCoroutineDispatchers.advanceUntilIdle()
+ val storeOp2 = cacheStore2.storeDataAsync(updateInMemoryCache = false) { TEST_INT_MESSAGE_V2 }
+ testCoroutineDispatchers.advanceUntilIdle()
+
+ // All operations should be complete, but the observer will receive the previous update rather
+ // than the latest since it wasn't updated in memory and the cache was pre-primed.
+ assertThat(storeOp1.isCompleted).isTrue()
+ assertThat(storeOp2.isCompleted).isTrue()
+ assertThat(primeOp.isCompleted).isTrue()
+ assertThat(monitorFactory.waitForNextSuccessfulResult(cacheStore2))
+ .isEqualTo(TEST_INT_MESSAGE_V1)
+ }
+
+ @Test
+ fun testPrimeInMemoryAndOnDisk_onDisk_newObject_updateMemThenRead_primed_receivesNewVal() {
+ val cacheStore1 = cacheFactory.create(CACHE_NAME_1, TestMessage.getDefaultInstance())
+ val storeOp1 =
+ cacheStore1.storeDataAsync(updateInMemoryCache = false) { TEST_INT_MESSAGE_V1 }
+ testCoroutineDispatchers.advanceUntilIdle()
+
+ // Create a new cache with the same name and update it, then observe it. However, first prime
+ // it.
+ val cacheStore2 = cacheFactory.create(CACHE_NAME_1, TestMessage.getDefaultInstance())
+ val primeOp =
+ cacheStore2.primeInMemoryAndDiskCacheAsync(
+ updateMode = UPDATE_IF_NEW_CACHE, publishMode = DO_NOT_PUBLISH_TO_IN_MEMORY_CACHE
+ )
+ testCoroutineDispatchers.advanceUntilIdle()
+ val storeOp2 = cacheStore2.storeDataAsync { TEST_INT_MESSAGE_V2 }
+ testCoroutineDispatchers.advanceUntilIdle()
+
+ // Similar to the previous test, except due to the in-memory update the observer will receive
+ // the latest result regardless of the cache priming.
+ assertThat(storeOp1.isCompleted).isTrue()
+ assertThat(storeOp2.isCompleted).isTrue()
+ assertThat(primeOp.isCompleted).isTrue()
+ assertThat(monitorFactory.waitForNextSuccessfulResult(cacheStore2))
+ .isEqualTo(TEST_INT_MESSAGE_V2)
+ }
+
+ @Test
+ fun testPrimeInMemoryAndOnDisk_afterStoreUpdateWithoutMemUpdate_observesOldValue() {
+ val cacheStore = cacheFactory.create(CACHE_NAME_1, TestMessage.getDefaultInstance())
+ // Force initializing the store's in-memory cache
+ monitorFactory.waitForNextSuccessfulResult(cacheStore)
+
+ val storeOp = cacheStore.storeDataAsync(updateInMemoryCache = false) { TEST_INT_MESSAGE_V1 }
+ testCoroutineDispatchers.advanceUntilIdle()
+ val primeOp =
+ cacheStore.primeInMemoryAndDiskCacheAsync(
+ updateMode = UPDATE_IF_NEW_CACHE,
+ publishMode = DO_NOT_PUBLISH_TO_IN_MEMORY_CACHE
+ )
+ testCoroutineDispatchers.advanceUntilIdle()
+
+ // Both ops will succeed, and the observer will receive the old value due to the update not
+ // changing the in-memory cache, and the prime no-oping due to the cache already being
+ // initialized.
+ assertThat(storeOp.isCompleted).isTrue()
+ assertThat(primeOp.isCompleted).isTrue()
+ assertThat(monitorFactory.waitForNextSuccessfulResult(cacheStore)).isEqualToDefaultInstance()
+ }
+
@Test
fun testPrimeInMemoryAndOnDisk_newCache_notOnDisk_notInMem_writesFileAndRetsNewVal() {
val cacheStore = cacheFactory.create(CACHE_NAME_1, TestMessage.getDefaultInstance())
- val deferred = cacheStore.primeInMemoryAndDiskCacheAsync {
- it.toBuilder().apply { strValue += " first transform" }.build()
- }
+ val deferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(
+ updateMode = UPDATE_IF_NEW_CACHE, publishMode = PUBLISH_TO_IN_MEMORY_CACHE
+ ) { it.toBuilder().apply { strValue += " first transform" }.build() }
// The on-disk and in-memory values should change.
deferred.waitForSuccessfulResult()
- val onDiskValue = readFileCache(CACHE_NAME_1, TestMessage.getDefaultInstance())
+ val onDiskValue = readFileCache(CACHE_NAME_1)
val cacheValue = monitorFactory.waitForNextSuccessfulResult(cacheStore)
assertThat(cacheValue).isEqualTo(onDiskValue)
assertThat(cacheValue.strValue.trim()).isEqualTo("first transform")
@@ -491,14 +1436,15 @@ class PersistentCacheStoreTest {
writeFileCache(CACHE_NAME_1, TestMessage.newBuilder().apply { strValue = "initial" }.build())
val cacheStore = cacheFactory.create(CACHE_NAME_1, TestMessage.getDefaultInstance())
- val deferred = cacheStore.primeInMemoryAndDiskCacheAsync {
- it.toBuilder().apply { strValue += " first transform" }.build()
- }
+ val deferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(
+ updateMode = UPDATE_IF_NEW_CACHE, publishMode = PUBLISH_TO_IN_MEMORY_CACHE
+ ) { it.toBuilder().apply { strValue += " first transform" }.build() }
// The on-disk value should be the same, and the in-memory value should become the on-disk
// value. The initializer shouldn't be used since the value is already on disk.
deferred.waitForSuccessfulResult()
- val onDiskValue = readFileCache(CACHE_NAME_1, TestMessage.getDefaultInstance())
+ val onDiskValue = readFileCache(CACHE_NAME_1)
val cacheValue = monitorFactory.waitForNextSuccessfulResult(cacheStore)
assertThat(cacheValue).isEqualTo(onDiskValue)
assertThat(cacheValue.strValue).isEqualTo("initial")
@@ -511,14 +1457,15 @@ class PersistentCacheStoreTest {
CACHE_NAME_1, TestMessage.newBuilder().apply { strValue = "different initial" }.build()
)
- val deferred = cacheStore.primeInMemoryAndDiskCacheAsync {
- it.toBuilder().apply { strValue += " first transform" }.build()
- }
+ val deferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(
+ updateMode = UPDATE_IF_NEW_CACHE, publishMode = PUBLISH_TO_IN_MEMORY_CACHE
+ ) { it.toBuilder().apply { strValue += " first transform" }.build() }
// Priming should ignore both the on-disk and in-memory values of the cache store since only the
// initial value matters.
deferred.waitForSuccessfulResult()
- val onDiskValue = readFileCache(CACHE_NAME_1, TestMessage.getDefaultInstance())
+ val onDiskValue = readFileCache(CACHE_NAME_1)
val cacheValue = monitorFactory.waitForNextSuccessfulResult(cacheStore)
assertThat(cacheValue).isEqualTo(onDiskValue)
assertThat(cacheValue.strValue).isEqualTo("initial")
@@ -533,14 +1480,15 @@ class PersistentCacheStoreTest {
it.toBuilder().apply { strValue = "different update" }.build()
}.waitForResult()
- val deferred = cacheStore.primeInMemoryAndDiskCacheAsync {
- it.toBuilder().apply { strValue += " first transform" }.build()
- }
+ val deferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(
+ updateMode = UPDATE_IF_NEW_CACHE, publishMode = PUBLISH_TO_IN_MEMORY_CACHE
+ ) { it.toBuilder().apply { strValue += " first transform" }.build() }
// Priming shouldn't really change much since the recent change to the cache store takes
// precedence.
deferred.waitForSuccessfulResult()
- val onDiskValue = readFileCache(CACHE_NAME_1, TestMessage.getDefaultInstance())
+ val onDiskValue = readFileCache(CACHE_NAME_1)
val cacheValue = monitorFactory.waitForNextSuccessfulResult(cacheStore)
assertThat(cacheValue).isEqualTo(onDiskValue)
assertThat(cacheValue.strValue).isEqualTo("different update")
@@ -556,14 +1504,15 @@ class PersistentCacheStoreTest {
it.toBuilder().apply { strValue = "different update" }.build()
}.waitForResult()
- val deferred = cacheStore.primeInMemoryAndDiskCacheAsync {
- it.toBuilder().apply { strValue += " first transform" }.build()
- }
+ val deferred =
+ cacheStore.primeInMemoryAndDiskCacheAsync(
+ updateMode = UPDATE_IF_NEW_CACHE, publishMode = PUBLISH_TO_IN_MEMORY_CACHE
+ ) { it.toBuilder().apply { strValue += " first transform" }.build() }
// Priming shouldn't really change much since the recent change to the cache store takes
// precedence.
deferred.waitForSuccessfulResult()
- val onDiskValue = readFileCache(CACHE_NAME_1, TestMessage.getDefaultInstance())
+ val onDiskValue = readFileCache(CACHE_NAME_1)
val cacheValue = monitorFactory.waitForNextSuccessfulResult(cacheStore)
assertThat(cacheValue).isEqualTo(onDiskValue)
assertThat(cacheValue.strValue).isEqualTo("different update")
@@ -578,26 +1527,62 @@ class PersistentCacheStoreTest {
val cacheStore2 = cacheFactory.create(CACHE_NAME_1, TestMessage.getDefaultInstance())
monitorFactory.ensureDataProviderExecutes(cacheStore1)
- val deferred = cacheStore1.primeInMemoryAndDiskCacheAsync {
- it.toBuilder().apply { strValue += " first transform" }.build()
- }
+ val deferred =
+ cacheStore1.primeInMemoryAndDiskCacheAsync(
+ updateMode = UPDATE_IF_NEW_CACHE, publishMode = PUBLISH_TO_IN_MEMORY_CACHE
+ ) { it.toBuilder().apply { strValue += " first transform" }.build() }
// The corrupted cache will trigger an in-memory only state that will lead to the cache being
// overwritten (since it can't be determined whether the on-disk cache matches the expected
- // value). Note that the cache will be in a bad state since it failed to read its original
- // state, but the on-disk copy will still be updated. Note also that the second instance of the
+ // value). Note the on-disk cache will still be updated, and that the second instance of the
// cache wasn't yet primed until this step, so it's being used to validate that the in-memory
// copy is also correct after the on-disk value has been updated.
deferred.waitForSuccessfulResult()
- monitorFactory.waitForNextFailureResult(cacheStore1)
- val onDiskValue = readFileCache(CACHE_NAME_1, TestMessage.getDefaultInstance())
+ val onDiskValue = readFileCache(CACHE_NAME_1)
val cacheValue = monitorFactory.waitForNextSuccessfulResult(cacheStore2)
assertThat(cacheValue).isEqualTo(onDiskValue)
assertThat(onDiskValue.strValue).isEqualTo("different initial first transform")
}
+ private fun subscribeToCacheStoreChanges(cacheStore: PersistentCacheStore) {
+ asyncDataSubscriptionManager.subscribe(
+ cacheStore.getId(), mockSubscriptionCallback.toAsyncChange()
+ )
+ }
+
+ private fun loadCacheIntoMemory(cacheStore: PersistentCacheStore) {
+ // Attempt to load the cache store from disk--this ensures that the cache store is at least
+ // loaded into memory.
+ monitorFactory.ensureDataProviderExecutes(cacheStore)
+ }
+
+ private fun verifyCacheStoreHasInMemoryValue(
+ cacheName: String,
+ cacheStore: PersistentCacheStore,
+ value: T
+ ) {
+ // Delete the cache before reading from the store to verify that the read value is actually
+ // in-memory and not being read from disk.
+ deleteCacheFile(cacheName)
+ assertThat(monitorFactory.waitForNextSuccessfulResult(cacheStore)).isEqualTo(value)
+ }
+
+ private fun verifyDiskCacheHasValue(cacheName: String, value: T) {
+ assertThat(readFileCache(cacheName)).isEqualTo(value)
+ }
+
+ private fun verifyCacheStoreSentDataProviderNotification() {
+ verify(mockSubscriptionCallback).onDataProviderChanged()
+ }
+
+ private fun verifyCacheStoreDidNotSendDataProviderNotification() {
+ verify(mockSubscriptionCallback, never()).onDataProviderChanged()
+ }
+
private fun getCacheFile(cacheName: String) = File(context.filesDir, "$cacheName.cache")
+ private fun deleteCacheFile(cacheName: String) = getCacheFile(cacheName).delete()
+
private fun corruptFileCache(cacheName: String) {
// NB: This is unfortunately tied to the implementation details of PersistentCacheStore. If this
// ends up being an issue, the store should be updated to call into a file path provider that
@@ -615,9 +1600,12 @@ class PersistentCacheStoreTest {
FileOutputStream(this).use { it.write(data) }
}
- private inline fun readFileCache(cacheName: String, baseMessage: T): T {
+ private inline fun readFileCache(cacheName: String): T {
+ // Use reflection to simplify the test API.
+ val defaultInstance =
+ T::class.staticFunctions.find { it.name == "getDefaultInstance" }?.call() as? T?
return FileInputStream(getCacheFile(cacheName)).use {
- baseMessage.newBuilderForType().mergeFrom(it).build()
+ checkNotNull(defaultInstance).newBuilderForType().mergeFrom(it).build()
} as T
}
@@ -694,4 +1682,12 @@ class PersistentCacheStoreTest {
override fun getDataProvidersInjector(): DataProvidersInjector = component
}
+
+ interface SubscriptionCallback {
+ fun onDataProviderChanged()
+
+ companion object {
+ fun SubscriptionCallback.toAsyncChange(): ObserveAsyncChange = { onDataProviderChanged() }
+ }
+ }
}
diff --git a/domain/BUILD.bazel b/domain/BUILD.bazel
index e13cc36c9a6..db2919a4ff8 100755
--- a/domain/BUILD.bazel
+++ b/domain/BUILD.bazel
@@ -158,6 +158,7 @@ TEST_DEPS = [
":interaction_object_test_builder",
"//app:crashlytics",
"//app:crashlytics_deps",
+ "//app/src/main/java/org/oppia/android/app/application/testing:testing_build_flavor_module",
"//data/src/main/java/org/oppia/android/data/backends/gae:network_config_prod_module",
"//data/src/main/java/org/oppia/android/data/backends/gae/model",
"//data/src/main/java/org/oppia/android/data/persistence:cache_store",
diff --git a/domain/src/main/java/org/oppia/android/domain/exploration/lightweightcheckpointing/ExplorationCheckpointController.kt b/domain/src/main/java/org/oppia/android/domain/exploration/lightweightcheckpointing/ExplorationCheckpointController.kt
index b69e949a859..84b74a71211 100644
--- a/domain/src/main/java/org/oppia/android/domain/exploration/lightweightcheckpointing/ExplorationCheckpointController.kt
+++ b/domain/src/main/java/org/oppia/android/domain/exploration/lightweightcheckpointing/ExplorationCheckpointController.kt
@@ -8,6 +8,8 @@ import org.oppia.android.app.model.ExplorationCheckpointDatabase
import org.oppia.android.app.model.ExplorationCheckpointDetails
import org.oppia.android.app.model.ProfileId
import org.oppia.android.data.persistence.PersistentCacheStore
+import org.oppia.android.data.persistence.PersistentCacheStore.PublishMode
+import org.oppia.android.data.persistence.PersistentCacheStore.UpdateMode
import org.oppia.android.domain.exploration.ExplorationRetriever
import org.oppia.android.domain.oppialogger.OppiaLogger
import org.oppia.android.util.data.AsyncResult
@@ -282,7 +284,10 @@ class ExplorationCheckpointController @Inject constructor(
cacheStore
}
- cacheStore.primeInMemoryCacheAsync().invokeOnCompletion { throwable ->
+ cacheStore.primeInMemoryAndDiskCacheAsync(
+ updateMode = UpdateMode.UPDATE_IF_NEW_CACHE,
+ publishMode = PublishMode.PUBLISH_TO_IN_MEMORY_CACHE
+ ).invokeOnCompletion { throwable ->
throwable?.let {
oppiaLogger.e(
"ExplorationCheckpointController",
diff --git a/domain/src/main/java/org/oppia/android/domain/onboarding/AppStartupStateController.kt b/domain/src/main/java/org/oppia/android/domain/onboarding/AppStartupStateController.kt
index e6196c6174e..31b6b203ba7 100644
--- a/domain/src/main/java/org/oppia/android/domain/onboarding/AppStartupStateController.kt
+++ b/domain/src/main/java/org/oppia/android/domain/onboarding/AppStartupStateController.kt
@@ -1,7 +1,9 @@
package org.oppia.android.domain.onboarding
import org.oppia.android.app.model.AppStartupState
+import org.oppia.android.app.model.AppStartupState.BuildFlavorNoticeMode
import org.oppia.android.app.model.AppStartupState.StartupMode
+import org.oppia.android.app.model.BuildFlavor
import org.oppia.android.app.model.OnboardingState
import org.oppia.android.data.persistence.PersistentCacheStore
import org.oppia.android.domain.oppialogger.OppiaLogger
@@ -12,7 +14,7 @@ import org.oppia.android.util.locale.OppiaLocale
import javax.inject.Inject
import javax.inject.Singleton
-private const val APP_STARTUP_STATE_DATA_PROVIDER_ID = "app_startup_state_data_provider_id"
+private const val APP_STARTUP_STATE_PROVIDER_ID = "app_startup_state_data_provider_id"
/** Controller for persisting and retrieving the user's initial app state upon opening the app. */
@Singleton
@@ -20,44 +22,65 @@ class AppStartupStateController @Inject constructor(
cacheStoreFactory: PersistentCacheStore.Factory,
private val oppiaLogger: OppiaLogger,
private val expirationMetaDataRetriever: ExpirationMetaDataRetriever,
- private val machineLocale: OppiaLocale.MachineLocale
+ private val machineLocale: OppiaLocale.MachineLocale,
+ private val currentBuildFlavor: BuildFlavor
) {
- private val onboardingFlowStore =
+ private val onboardingFlowStore by lazy {
cacheStoreFactory.create("on_boarding_flow", OnboardingState.getDefaultInstance())
-
- private val appStartupStateDataProvider by lazy {
- onboardingFlowStore.transform(APP_STARTUP_STATE_DATA_PROVIDER_ID) {
- AppStartupState.newBuilder().setStartupMode(computeAppStartupMode(it)).build()
- }
}
+ private val appStartupStateDataProvider by lazy { computeAppStartupStateProvider() }
+
init {
// Prime the cache ahead of time so that any existing history is read prior to any calls to
- // markOnboardingFlowCompleted().
- onboardingFlowStore.primeInMemoryCacheAsync().invokeOnCompletion {
- it?.let {
+ // markOnboardingFlowCompleted(). Note that this also ensures that the on-disk cache contains
+ // the last used build flavor (but it doesn't update the in-memory copy as it's the *last* used
+ // flavor, and thus requires an app restart in order to observe).
+ onboardingFlowStore.primeInMemoryAndDiskCacheAsync(
+ updateMode = PersistentCacheStore.UpdateMode.UPDATE_ALWAYS,
+ publishMode = PersistentCacheStore.PublishMode.DO_NOT_PUBLISH_TO_IN_MEMORY_CACHE
+ ) { state ->
+ state.toBuilder().apply { lastUsedBuildFlavor = currentBuildFlavor }.build()
+ }.invokeOnCompletion { primeFailure ->
+ if (primeFailure != null) {
oppiaLogger.e(
- "DOMAIN", "Failed to prime cache ahead of data retrieval for user onboarding data.", it
+ "StartupController",
+ "Failed to prime cache ahead of data retrieval for user onboarding data.",
+ primeFailure
)
}
}
}
/**
- * Saves that the user has completed the app onboarding flow. Note that this does not notify
- * existing subscribers of the changed state, nor can future subscribers observe this state until
- * the app restarts.
+ * Saves that the user has completed the app onboarding flow.
+ *
+ * Note that this does not notify existing subscribers of the changed state, nor can future
+ * subscribers observe this state until the app restarts.
*/
fun markOnboardingFlowCompleted() {
- onboardingFlowStore.storeDataAsync(updateInMemoryCache = false) {
- it.toBuilder().setAlreadyOnboardedApp(true).build()
- }.invokeOnCompletion {
- it?.let {
- oppiaLogger.e(
- "DOMAIN", "Failed when storing that the user already onboarded the app.", it
- )
- }
- }
+ updateOnboardingState { alreadyOnboardedApp = true }
+ }
+
+ /**
+ * Saves that the user never wants to see beta notices again.
+ *
+ * Note that this does not notify existing subscribers of the changed state, nor can future
+ * subscribers observe this state until the app restarts.
+ */
+ fun dismissBetaNoticesPermanently() {
+ updateOnboardingState { permanentlyDismissedBetaNotice = true }
+ }
+
+ /**
+ * Saves that the user never wants to notices for cases when their app has updated from a
+ * pre-release version of the app to the general availability version.
+ *
+ * Note that this does not notify existing subscribers of the changed state, nor can future
+ * subscribers observe this state until the app restarts.
+ */
+ fun dismissGaUpgradeNoticesPermanently() {
+ updateOnboardingState { permanentlyDismissedGaUpgradeNotice = true }
}
/**
@@ -66,6 +89,32 @@ class AppStartupStateController @Inject constructor(
*/
fun getAppStartupState(): DataProvider = appStartupStateDataProvider
+ private fun computeAppStartupStateProvider(): DataProvider {
+ return onboardingFlowStore.transform(APP_STARTUP_STATE_PROVIDER_ID) { onboardingState ->
+ AppStartupState.newBuilder().apply {
+ startupMode = computeAppStartupMode(onboardingState)
+ buildFlavorNoticeMode = computeBuildNoticeMode(onboardingState, startupMode)
+ }.build()
+ }
+ }
+
+ private fun updateOnboardingState(updateState: OnboardingState.Builder.() -> Unit) {
+ // Note that the flavor must be written here since it only gets updated on-disk and never
+ // in-memory (which means it will be inadvertently overwritten when updating onboarding state
+ // here).
+ val deferred = onboardingFlowStore.storeDataAsync(updateInMemoryCache = false) { state ->
+ state.toBuilder().apply {
+ updateState()
+ lastUsedBuildFlavor = currentBuildFlavor
+ }.build()
+ }
+ deferred.invokeOnCompletion { failure ->
+ if (failure != null) {
+ oppiaLogger.e("StartupController", "Failed to update onboarding state.", failure)
+ }
+ }
+ }
+
private fun computeAppStartupMode(onboardingState: OnboardingState): StartupMode {
return when {
hasAppExpired() -> StartupMode.APP_IS_DEPRECATED
@@ -74,6 +123,39 @@ class AppStartupStateController @Inject constructor(
}
}
+ private fun computeBuildNoticeMode(
+ onboardingState: OnboardingState,
+ startupMode: StartupMode
+ ): BuildFlavorNoticeMode {
+ return when (currentBuildFlavor) {
+ BuildFlavor.TESTING, BuildFlavor.BUILD_FLAVOR_UNSPECIFIED, BuildFlavor.UNRECOGNIZED ->
+ BuildFlavorNoticeMode.FLAVOR_NOTICE_MODE_UNSPECIFIED
+ // No notice is shown for developer & alpha builds.
+ BuildFlavor.DEVELOPER, BuildFlavor.ALPHA -> BuildFlavorNoticeMode.NO_NOTICE
+ BuildFlavor.BETA -> {
+ // Only show the beta notice if the user hasn't permanently dismissed it, and when it's
+ // appropriate to show (i.e. they've recently changed to the beta flavor, and their app is
+ // not force-deprecated).
+ if (!onboardingState.permanentlyDismissedBetaNotice &&
+ onboardingState.lastUsedBuildFlavor != BuildFlavor.BETA &&
+ startupMode != StartupMode.APP_IS_DEPRECATED
+ ) {
+ BuildFlavorNoticeMode.SHOW_BETA_NOTICE
+ } else BuildFlavorNoticeMode.NO_NOTICE
+ }
+ BuildFlavor.GENERAL_AVAILABILITY -> when (onboardingState.lastUsedBuildFlavor) {
+ BuildFlavor.ALPHA, BuildFlavor.BETA, null -> {
+ if (!onboardingState.permanentlyDismissedGaUpgradeNotice) {
+ BuildFlavorNoticeMode.SHOW_UPGRADE_TO_GENERAL_AVAILABILITY_NOTICE
+ } else BuildFlavorNoticeMode.NO_NOTICE // The user doesn't want to see the notice again.
+ }
+ // A brand new install should result in no notice, or an update from a developer build.
+ BuildFlavor.BUILD_FLAVOR_UNSPECIFIED, BuildFlavor.UNRECOGNIZED, BuildFlavor.TESTING,
+ BuildFlavor.DEVELOPER, BuildFlavor.GENERAL_AVAILABILITY -> BuildFlavorNoticeMode.NO_NOTICE
+ }
+ }
+ }
+
private fun hasAppExpired(): Boolean {
val applicationMetadata = expirationMetaDataRetriever.getMetaData()
val isAppExpirationEnabled =
diff --git a/domain/src/main/java/org/oppia/android/domain/oppialogger/LoggingIdentifierController.kt b/domain/src/main/java/org/oppia/android/domain/oppialogger/LoggingIdentifierController.kt
index 3440f62fe0f..ca4a741da2d 100644
--- a/domain/src/main/java/org/oppia/android/domain/oppialogger/LoggingIdentifierController.kt
+++ b/domain/src/main/java/org/oppia/android/domain/oppialogger/LoggingIdentifierController.kt
@@ -4,6 +4,8 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import org.oppia.android.app.model.DeviceContextDatabase
import org.oppia.android.data.persistence.PersistentCacheStore
+import org.oppia.android.data.persistence.PersistentCacheStore.PublishMode
+import org.oppia.android.data.persistence.PersistentCacheStore.UpdateMode
import org.oppia.android.util.data.DataProvider
import org.oppia.android.util.data.DataProviders
import org.oppia.android.util.data.DataProviders.Companion.transform
@@ -36,10 +38,11 @@ class LoggingIdentifierController @Inject constructor(
persistentCacheStoreFactory.create(
cacheName = "device_context_database", DeviceContextDatabase.getDefaultInstance()
).also {
- it.primeInMemoryAndDiskCacheAsync { database ->
- database.toBuilder().apply {
- installationId = computeInstallationId()
- }.build()
+ it.primeInMemoryAndDiskCacheAsync(
+ updateMode = UpdateMode.UPDATE_IF_NEW_CACHE,
+ publishMode = PublishMode.PUBLISH_TO_IN_MEMORY_CACHE
+ ) { database ->
+ database.toBuilder().apply { installationId = computeInstallationId() }.build()
}.invokeOnCompletion { failure ->
if (failure != null) {
oppiaLogger.e(
diff --git a/domain/src/main/java/org/oppia/android/domain/profile/ProfileManagementController.kt b/domain/src/main/java/org/oppia/android/domain/profile/ProfileManagementController.kt
index dac62b05666..e2c15df2253 100644
--- a/domain/src/main/java/org/oppia/android/domain/profile/ProfileManagementController.kt
+++ b/domain/src/main/java/org/oppia/android/domain/profile/ProfileManagementController.kt
@@ -17,6 +17,8 @@ import org.oppia.android.app.model.ProfileDatabase
import org.oppia.android.app.model.ProfileId
import org.oppia.android.app.model.ReadingTextSize
import org.oppia.android.data.persistence.PersistentCacheStore
+import org.oppia.android.data.persistence.PersistentCacheStore.PublishMode
+import org.oppia.android.data.persistence.PersistentCacheStore.UpdateMode
import org.oppia.android.domain.oppialogger.LoggingIdentifierController
import org.oppia.android.domain.oppialogger.OppiaLogger
import org.oppia.android.domain.oppialogger.analytics.LearnerAnalyticsLogger
@@ -129,7 +131,10 @@ class ProfileManagementController @Inject constructor(
// TODO(#272): Remove init block when storeDataAsync is fixed
init {
- profileDataStore.primeInMemoryCacheAsync().invokeOnCompletion {
+ profileDataStore.primeInMemoryAndDiskCacheAsync(
+ updateMode = UpdateMode.UPDATE_IF_NEW_CACHE,
+ publishMode = PublishMode.PUBLISH_TO_IN_MEMORY_CACHE
+ ).invokeOnCompletion {
it?.let {
oppiaLogger.e(
"ProfileManagementController",
diff --git a/domain/src/main/java/org/oppia/android/domain/topic/PrimeTopicAssetsControllerImpl.kt b/domain/src/main/java/org/oppia/android/domain/topic/PrimeTopicAssetsControllerImpl.kt
index b1eddc72ddc..fa25ee6f163 100644
--- a/domain/src/main/java/org/oppia/android/domain/topic/PrimeTopicAssetsControllerImpl.kt
+++ b/domain/src/main/java/org/oppia/android/domain/topic/PrimeTopicAssetsControllerImpl.kt
@@ -3,7 +3,6 @@ package org.oppia.android.domain.topic
import android.annotation.SuppressLint
import android.app.Activity
import android.app.Application
-import android.content.Context
import android.graphics.Typeface
import android.os.Bundle
import android.os.SystemClock
@@ -73,7 +72,7 @@ private const val REPLACE_IMG_FILE_PATH_ATTRIBUTE = "src"
*/
@Singleton
class PrimeTopicAssetsControllerImpl @Inject constructor(
- private val context: Context,
+ private val application: Application,
private val oppiaLogger: OppiaLogger,
private val assetRepository: AssetRepository,
private val topicController: TopicController,
@@ -197,7 +196,6 @@ class PrimeTopicAssetsControllerImpl @Inject constructor(
private fun prepareUiForDownloadStatusChanges(dialogStyleResId: Int) {
// Reference: https://stackoverflow.com/a/37713320.
- val application = context.applicationContext as Application
application.registerActivityLifecycleCallbacks(object : Application.ActivityLifecycleCallbacks {
override fun onActivityPaused(activity: Activity) {}
override fun onActivityResumed(activity: Activity) {}
diff --git a/domain/src/main/java/org/oppia/android/domain/topic/StoryProgressController.kt b/domain/src/main/java/org/oppia/android/domain/topic/StoryProgressController.kt
index bba4660a16f..81b9d28e8d8 100644
--- a/domain/src/main/java/org/oppia/android/domain/topic/StoryProgressController.kt
+++ b/domain/src/main/java/org/oppia/android/domain/topic/StoryProgressController.kt
@@ -8,6 +8,8 @@ import org.oppia.android.app.model.StoryProgress
import org.oppia.android.app.model.TopicProgress
import org.oppia.android.app.model.TopicProgressDatabase
import org.oppia.android.data.persistence.PersistentCacheStore
+import org.oppia.android.data.persistence.PersistentCacheStore.PublishMode
+import org.oppia.android.data.persistence.PersistentCacheStore.UpdateMode
import org.oppia.android.domain.oppialogger.OppiaLogger
import org.oppia.android.util.data.AsyncResult
import org.oppia.android.util.data.DataProvider
@@ -371,8 +373,11 @@ class StoryProgressController @Inject constructor(
cacheStore
}
- cacheStore.primeInMemoryCacheAsync().invokeOnCompletion {
- it?.let { it ->
+ cacheStore.primeInMemoryAndDiskCacheAsync(
+ updateMode = UpdateMode.UPDATE_IF_NEW_CACHE,
+ publishMode = PublishMode.PUBLISH_TO_IN_MEMORY_CACHE
+ ).invokeOnCompletion {
+ if (it != null) {
oppiaLogger.e(
"StoryProgressController",
"Failed to prime cache ahead of data retrieval for StoryProgressController.",
diff --git a/domain/src/test/java/org/oppia/android/domain/onboarding/AppStartupStateControllerTest.kt b/domain/src/test/java/org/oppia/android/domain/onboarding/AppStartupStateControllerTest.kt
index c77a04df305..9f924f394dd 100644
--- a/domain/src/test/java/org/oppia/android/domain/onboarding/AppStartupStateControllerTest.kt
+++ b/domain/src/test/java/org/oppia/android/domain/onboarding/AppStartupStateControllerTest.kt
@@ -6,17 +6,22 @@ import android.os.Bundle
import androidx.test.core.app.ApplicationProvider
import androidx.test.core.content.pm.ApplicationInfoBuilder
import androidx.test.core.content.pm.PackageInfoBuilder
-import androidx.test.ext.junit.runners.AndroidJUnit4
import com.google.common.truth.Truth.assertThat
import dagger.BindsInstance
import dagger.Component
import dagger.Module
import dagger.Provides
+import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
+import org.oppia.android.app.model.AppStartupState.BuildFlavorNoticeMode.FLAVOR_NOTICE_MODE_UNSPECIFIED
+import org.oppia.android.app.model.AppStartupState.BuildFlavorNoticeMode.NO_NOTICE
+import org.oppia.android.app.model.AppStartupState.BuildFlavorNoticeMode.SHOW_BETA_NOTICE
+import org.oppia.android.app.model.AppStartupState.BuildFlavorNoticeMode.SHOW_UPGRADE_TO_GENERAL_AVAILABILITY_NOTICE
import org.oppia.android.app.model.AppStartupState.StartupMode.APP_IS_DEPRECATED
import org.oppia.android.app.model.AppStartupState.StartupMode.USER_IS_ONBOARDED
import org.oppia.android.app.model.AppStartupState.StartupMode.USER_NOT_YET_ONBOARDED
+import org.oppia.android.app.model.BuildFlavor
import org.oppia.android.app.model.OnboardingState
import org.oppia.android.data.persistence.PersistentCacheStore
import org.oppia.android.domain.oppialogger.LogStorageModule
@@ -26,6 +31,12 @@ import org.oppia.android.domain.platformparameter.PlatformParameterModule
import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule
import org.oppia.android.testing.TestLogReportingModule
import org.oppia.android.testing.data.DataProviderTestMonitor
+import org.oppia.android.testing.junit.OppiaParameterizedTestRunner
+import org.oppia.android.testing.junit.OppiaParameterizedTestRunner.Iteration
+import org.oppia.android.testing.junit.OppiaParameterizedTestRunner.Parameter
+import org.oppia.android.testing.junit.OppiaParameterizedTestRunner.RunParameterized
+import org.oppia.android.testing.junit.OppiaParameterizedTestRunner.SelectRunnerPlatform
+import org.oppia.android.testing.junit.ParameterizedRobolectricTestRunner
import org.oppia.android.testing.robolectric.RobolectricModule
import org.oppia.android.testing.threading.TestCoroutineDispatchers
import org.oppia.android.testing.threading.TestDispatcherModule
@@ -52,18 +63,25 @@ import javax.inject.Singleton
/** Tests for [AppStartupStateController]. */
// FunctionName: test names are conventionally named with underscores.
@Suppress("FunctionName")
-@RunWith(AndroidJUnit4::class)
+@RunWith(OppiaParameterizedTestRunner::class)
+@SelectRunnerPlatform(ParameterizedRobolectricTestRunner::class)
@Config(application = AppStartupStateControllerTest.TestApplication::class)
class AppStartupStateControllerTest {
@Inject lateinit var context: Context
@Inject lateinit var appStartupStateController: AppStartupStateController
@Inject lateinit var testCoroutineDispatchers: TestCoroutineDispatchers
@Inject lateinit var monitorFactory: DataProviderTestMonitor.Factory
+ @Parameter lateinit var initialFlavorName: String
// TODO(#3792): Remove this usage of Locale (probably by introducing a test utility in the locale
// package to generate these strings).
private val expirationDateFormat by lazy { SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()) }
+ @Before
+ fun setUp() {
+ TestModule.buildFlavor = BuildFlavor.BUILD_FLAVOR_UNSPECIFIED
+ }
+
@Test
fun testController_providesInitialState_indicatesUserHasNotOnboardedTheApp() {
setUpDefaultTestApplicationComponent()
@@ -91,7 +109,7 @@ class AppStartupStateControllerTest {
@Test
fun testController_settingAppOnboarded_observedNewController_userOnboardedApp() {
// Simulate the previous app already having completed onboarding.
- executeInPreviousApp { testComponent ->
+ executeInPreviousAppInstance { testComponent ->
testComponent.getAppStartupStateController().markOnboardingFlowCompleted()
testComponent.getTestCoroutineDispatchers().runCurrent()
}
@@ -100,8 +118,8 @@ class AppStartupStateControllerTest {
setUpDefaultTestApplicationComponent()
val appStartupState = appStartupStateController.getAppStartupState()
- // The app should be considered onboarded since a new DataProvider instance was observed after
- // marking the app as onboarded.
+ // The user should be considered onboarded since a new DataProvider instance was observed after
+ // marking the user as onboarded.
val mode = monitorFactory.waitForNextSuccessfulResult(appStartupState)
assertThat(mode.startupMode).isEqualTo(USER_IS_ONBOARDED)
}
@@ -110,7 +128,7 @@ class AppStartupStateControllerTest {
@Suppress("DeferredResultUnused")
fun testController_onboardedApp_cleared_observeNewController_userDidNotOnboardApp() {
// Simulate the previous app already having completed onboarding, then cleared.
- executeInPreviousApp { testComponent ->
+ executeInPreviousAppInstance { testComponent ->
testComponent.getAppStartupStateController().markOnboardingFlowCompleted()
testComponent.getTestCoroutineDispatchers().runCurrent()
@@ -180,7 +198,7 @@ class AppStartupStateControllerTest {
@Test
fun testSecondAppOpen_onboardingFlowNotDone_deprecationEnabled_beforeDepDate_appNotDeprecated() {
- executeInPreviousApp { testComponent ->
+ executeInPreviousAppInstance { testComponent ->
setUpOppiaApplicationForContext(
context = testComponent.getContext(),
expirationEnabled = true,
@@ -198,7 +216,7 @@ class AppStartupStateControllerTest {
@Test
fun testSecondAppOpen_onboardingFlowNotDone_deprecationEnabled_afterDepDate_appIsDeprecated() {
- executeInPreviousApp { testComponent ->
+ executeInPreviousAppInstance { testComponent ->
setUpOppiaApplicationForContext(
context = testComponent.getContext(),
expirationEnabled = true,
@@ -216,7 +234,7 @@ class AppStartupStateControllerTest {
@Test
fun testSecondAppOpen_onboardingFlowCompleted_depEnabled_beforeDepDate_appNotDeprecated() {
- executeInPreviousApp { testComponent ->
+ executeInPreviousAppInstance { testComponent ->
setUpOppiaApplicationForContext(
context = testComponent.getContext(),
expirationEnabled = true,
@@ -238,7 +256,7 @@ class AppStartupStateControllerTest {
@Test
fun testSecondAppOpen_onboardingFlowCompleted_deprecationEnabled_afterDepDate_appIsDeprecated() {
- executeInPreviousApp { testComponent ->
+ executeInPreviousAppInstance { testComponent ->
setUpOppiaApplicationForContext(
context = testComponent.getContext(),
expirationEnabled = true,
@@ -258,6 +276,495 @@ class AppStartupStateControllerTest {
assertThat(mode.startupMode).isEqualTo(APP_IS_DEPRECATED)
}
+ /* Tests to verify that beta & no notices are shown at the expected times. */
+
+ @Test
+ fun testController_initialState_testingBuild_showsUnspecifiedNotice() {
+ TestModule.buildFlavor = BuildFlavor.TESTING
+ setUpDefaultTestApplicationComponent()
+
+ val appStartupState = appStartupStateController.getAppStartupState()
+
+ // Testing mode is specially handled as it's generally not expected to be encountered (but is
+ // still possible).
+ val mode = monitorFactory.waitForNextSuccessfulResult(appStartupState)
+ assertThat(mode.buildFlavorNoticeMode).isEqualTo(FLAVOR_NOTICE_MODE_UNSPECIFIED)
+ }
+
+ @Test
+ fun testController_initialState_developerBuild_showNoNotice() {
+ TestModule.buildFlavor = BuildFlavor.DEVELOPER
+ setUpDefaultTestApplicationComponent()
+
+ val appStartupState = appStartupStateController.getAppStartupState()
+
+ val mode = monitorFactory.waitForNextSuccessfulResult(appStartupState)
+ assertThat(mode.buildFlavorNoticeMode).isEqualTo(NO_NOTICE)
+ }
+
+ @Test
+ fun testController_initialState_alphaBuild_showNoNotice() {
+ TestModule.buildFlavor = BuildFlavor.ALPHA
+ setUpDefaultTestApplicationComponent()
+
+ val appStartupState = appStartupStateController.getAppStartupState()
+
+ val mode = monitorFactory.waitForNextSuccessfulResult(appStartupState)
+ assertThat(mode.buildFlavorNoticeMode).isEqualTo(NO_NOTICE)
+ }
+
+ @Test
+ fun testController_initialState_betaBuild_showNoNotice() {
+ TestModule.buildFlavor = BuildFlavor.BETA
+ setUpDefaultTestApplicationComponent()
+
+ val appStartupState = appStartupStateController.getAppStartupState()
+
+ // No notice is shown here since the 'prior' version is beta, and the notice is only shown if
+ // the build flavor changes for the user.
+ val mode = monitorFactory.waitForNextSuccessfulResult(appStartupState)
+ assertThat(mode.buildFlavorNoticeMode).isEqualTo(NO_NOTICE)
+ }
+
+ @Test
+ fun testController_initialState_gaBuild_showNoNotice() {
+ TestModule.buildFlavor = BuildFlavor.GENERAL_AVAILABILITY
+ setUpDefaultTestApplicationComponent()
+
+ val appStartupState = appStartupStateController.getAppStartupState()
+
+ val mode = monitorFactory.waitForNextSuccessfulResult(appStartupState)
+ assertThat(mode.buildFlavorNoticeMode).isEqualTo(NO_NOTICE)
+ }
+
+ @Test
+ fun testController_appDeprecated_testingBuild_showsUnspecifiedNotice() {
+ TestModule.buildFlavor = BuildFlavor.TESTING
+ setUpDefaultTestApplicationComponent()
+ setUpOppiaApplication(expirationEnabled = true, expDate = dateStringForToday())
+
+ val appStartupState = appStartupStateController.getAppStartupState()
+
+ // Testing mode is specially handled as it's generally not expected to be encountered (but is
+ // still possible).
+ val mode = monitorFactory.waitForNextSuccessfulResult(appStartupState)
+ assertThat(mode.buildFlavorNoticeMode).isEqualTo(FLAVOR_NOTICE_MODE_UNSPECIFIED)
+ }
+
+ @Test
+ fun testController_appDeprecated_developerBuild_showNoNotice() {
+ TestModule.buildFlavor = BuildFlavor.DEVELOPER
+ setUpDefaultTestApplicationComponent()
+ setUpOppiaApplication(expirationEnabled = true, expDate = dateStringForToday())
+
+ val appStartupState = appStartupStateController.getAppStartupState()
+
+ val mode = monitorFactory.waitForNextSuccessfulResult(appStartupState)
+ assertThat(mode.buildFlavorNoticeMode).isEqualTo(NO_NOTICE)
+ }
+
+ @Test
+ fun testController_appDeprecated_alphaBuild_showNoNotice() {
+ TestModule.buildFlavor = BuildFlavor.ALPHA
+ setUpDefaultTestApplicationComponent()
+ setUpOppiaApplication(expirationEnabled = true, expDate = dateStringForToday())
+
+ val appStartupState = appStartupStateController.getAppStartupState()
+
+ val mode = monitorFactory.waitForNextSuccessfulResult(appStartupState)
+ assertThat(mode.buildFlavorNoticeMode).isEqualTo(NO_NOTICE)
+ }
+
+ @Test
+ fun testController_appDeprecated_betaBuild_showNoNotice() {
+ TestModule.buildFlavor = BuildFlavor.BETA
+ setUpDefaultTestApplicationComponent()
+ setUpOppiaApplication(expirationEnabled = true, expDate = dateStringForToday())
+
+ val appStartupState = appStartupStateController.getAppStartupState()
+
+ // The beta notice is not shown in cases when the app is deprecated (since there's no point in
+ // showing it; the user can't actually use the app).
+ val mode = monitorFactory.waitForNextSuccessfulResult(appStartupState)
+ assertThat(mode.buildFlavorNoticeMode).isEqualTo(NO_NOTICE)
+ }
+
+ @Test
+ fun testController_appDeprecated_gaBuild_showNoNotice() {
+ TestModule.buildFlavor = BuildFlavor.GENERAL_AVAILABILITY
+ setUpDefaultTestApplicationComponent()
+ setUpOppiaApplication(expirationEnabled = true, expDate = dateStringForToday())
+
+ val appStartupState = appStartupStateController.getAppStartupState()
+
+ val mode = monitorFactory.waitForNextSuccessfulResult(appStartupState)
+ assertThat(mode.buildFlavorNoticeMode).isEqualTo(NO_NOTICE)
+ }
+
+ @Test
+ fun testController_userOnboarded_testingBuild_showsUnspecifiedNotice() {
+ // Simulate the previous app already having completed onboarding.
+ executeInPreviousAppInstance { testComponent ->
+ testComponent.getAppStartupStateController().markOnboardingFlowCompleted()
+ testComponent.getTestCoroutineDispatchers().runCurrent()
+ }
+ TestModule.buildFlavor = BuildFlavor.TESTING
+ setUpDefaultTestApplicationComponent()
+
+ val appStartupState = appStartupStateController.getAppStartupState()
+
+ // Testing mode is specially handled as it's generally not expected to be encountered (but is
+ // still possible).
+ val mode = monitorFactory.waitForNextSuccessfulResult(appStartupState)
+ assertThat(mode.buildFlavorNoticeMode).isEqualTo(FLAVOR_NOTICE_MODE_UNSPECIFIED)
+ }
+
+ @Test
+ fun testController_userOnboarded_developerBuild_showNoNotice() {
+ // Simulate the previous app already having completed onboarding.
+ executeInPreviousAppInstance { testComponent ->
+ testComponent.getAppStartupStateController().markOnboardingFlowCompleted()
+ testComponent.getTestCoroutineDispatchers().runCurrent()
+ }
+ TestModule.buildFlavor = BuildFlavor.DEVELOPER
+ setUpDefaultTestApplicationComponent()
+
+ val appStartupState = appStartupStateController.getAppStartupState()
+
+ val mode = monitorFactory.waitForNextSuccessfulResult(appStartupState)
+ assertThat(mode.buildFlavorNoticeMode).isEqualTo(NO_NOTICE)
+ }
+
+ @Test
+ fun testController_userOnboarded_alphaBuild_showNoNotice() {
+ // Simulate the previous app already having completed onboarding.
+ executeInPreviousAppInstance { testComponent ->
+ testComponent.getAppStartupStateController().markOnboardingFlowCompleted()
+ testComponent.getTestCoroutineDispatchers().runCurrent()
+ }
+ TestModule.buildFlavor = BuildFlavor.ALPHA
+ setUpDefaultTestApplicationComponent()
+
+ val appStartupState = appStartupStateController.getAppStartupState()
+
+ val mode = monitorFactory.waitForNextSuccessfulResult(appStartupState)
+ assertThat(mode.buildFlavorNoticeMode).isEqualTo(NO_NOTICE)
+ }
+
+ @Test
+ fun testController_userOnboarded_betaBuild_showBetaNotice() {
+ // Simulate the previous app already having completed onboarding.
+ executeInPreviousAppInstance { testComponent ->
+ testComponent.getAppStartupStateController().markOnboardingFlowCompleted()
+ testComponent.getTestCoroutineDispatchers().runCurrent()
+ }
+ TestModule.buildFlavor = BuildFlavor.BETA
+ setUpDefaultTestApplicationComponent()
+
+ val appStartupState = appStartupStateController.getAppStartupState()
+
+ // Beta is shown when using beta mode.
+ val mode = monitorFactory.waitForNextSuccessfulResult(appStartupState)
+ assertThat(mode.buildFlavorNoticeMode).isEqualTo(SHOW_BETA_NOTICE)
+ }
+
+ @Test
+ fun testController_userOnboarded_gaBuild_showNoNotice() {
+ // Simulate the previous app already having completed onboarding.
+ executeInPreviousAppInstance { testComponent ->
+ testComponent.getAppStartupStateController().markOnboardingFlowCompleted()
+ testComponent.getTestCoroutineDispatchers().runCurrent()
+ }
+ TestModule.buildFlavor = BuildFlavor.GENERAL_AVAILABILITY
+ setUpDefaultTestApplicationComponent()
+
+ val appStartupState = appStartupStateController.getAppStartupState()
+
+ val mode = monitorFactory.waitForNextSuccessfulResult(appStartupState)
+ assertThat(mode.buildFlavorNoticeMode).isEqualTo(NO_NOTICE)
+ }
+
+ /* Tests to verify that changing from one build flavor to another can cause notices to show. */
+
+ @Test
+ fun testController_userOnboarded_changeToTestingBuild_showsUnspecifiedNotice() {
+ // Simulate the previous app already having completed onboarding in a non-testing build.
+ executeInPreviousAppInstance { testComponent ->
+ TestModule.buildFlavor = BuildFlavor.DEVELOPER
+ testComponent.getAppStartupStateController().markOnboardingFlowCompleted()
+ testComponent.getTestCoroutineDispatchers().runCurrent()
+ }
+ TestModule.buildFlavor = BuildFlavor.TESTING
+ setUpDefaultTestApplicationComponent()
+
+ val appStartupState = appStartupStateController.getAppStartupState()
+
+ val mode = monitorFactory.waitForNextSuccessfulResult(appStartupState)
+ assertThat(mode.buildFlavorNoticeMode).isEqualTo(FLAVOR_NOTICE_MODE_UNSPECIFIED)
+ }
+
+ @Test
+ fun testController_userOnboarded_changeToDevBuild_showNoNotice() {
+ // Simulate the previous app already having completed onboarding in a non-dev build.
+ executeInPreviousAppInstance { testComponent ->
+ TestModule.buildFlavor = BuildFlavor.TESTING
+ testComponent.getAppStartupStateController().markOnboardingFlowCompleted()
+ testComponent.getTestCoroutineDispatchers().runCurrent()
+ }
+ TestModule.buildFlavor = BuildFlavor.DEVELOPER
+ setUpDefaultTestApplicationComponent()
+
+ val appStartupState = appStartupStateController.getAppStartupState()
+
+ val mode = monitorFactory.waitForNextSuccessfulResult(appStartupState)
+ assertThat(mode.buildFlavorNoticeMode).isEqualTo(NO_NOTICE)
+ }
+
+ @Test
+ fun testController_userOnboarded_changeToAlphaBuild_showNoNotice() {
+ // Simulate the previous app already having completed onboarding in a non-alpha build.
+ executeInPreviousAppInstance { testComponent ->
+ TestModule.buildFlavor = BuildFlavor.DEVELOPER
+ testComponent.getAppStartupStateController().markOnboardingFlowCompleted()
+ testComponent.getTestCoroutineDispatchers().runCurrent()
+ }
+ TestModule.buildFlavor = BuildFlavor.ALPHA
+ setUpDefaultTestApplicationComponent()
+
+ val appStartupState = appStartupStateController.getAppStartupState()
+
+ val mode = monitorFactory.waitForNextSuccessfulResult(appStartupState)
+ assertThat(mode.buildFlavorNoticeMode).isEqualTo(NO_NOTICE)
+ }
+
+ @Test
+ fun testController_userOnboarded_changeToBetaBuild_fromAlpha_showBetaNotice() {
+ // Simulate the previous app already having completed onboarding in an alpha build.
+ executeInPreviousAppInstance { testComponent ->
+ TestModule.buildFlavor = BuildFlavor.ALPHA
+ testComponent.getAppStartupStateController().markOnboardingFlowCompleted()
+ testComponent.getTestCoroutineDispatchers().runCurrent()
+ }
+ TestModule.buildFlavor = BuildFlavor.BETA
+ setUpDefaultTestApplicationComponent()
+
+ val appStartupState = appStartupStateController.getAppStartupState()
+
+ // Changing from alpha to beta should result in the notice showing.
+ val mode = monitorFactory.waitForNextSuccessfulResult(appStartupState)
+ assertThat(mode.buildFlavorNoticeMode).isEqualTo(SHOW_BETA_NOTICE)
+ }
+
+ @Test
+ fun testController_userOnboarded_changeToBetaBuild_fromBetaAgain_showNoNotice() {
+ // Simulate the previous app already having completed onboarding in a beta build.
+ executeInPreviousAppInstance { testComponent ->
+ TestModule.buildFlavor = BuildFlavor.BETA
+ testComponent.getAppStartupStateController().markOnboardingFlowCompleted()
+ testComponent.getTestCoroutineDispatchers().runCurrent()
+ }
+ TestModule.buildFlavor = BuildFlavor.BETA
+ setUpDefaultTestApplicationComponent()
+
+ val appStartupState = appStartupStateController.getAppStartupState()
+
+ // The beta notice was shown on the last run; don't show it again.
+ val mode = monitorFactory.waitForNextSuccessfulResult(appStartupState)
+ assertThat(mode.buildFlavorNoticeMode).isEqualTo(NO_NOTICE)
+ }
+
+ @Test
+ fun testController_userOnboarded_changeToBetaBuild_fromGa_showBetaNotice() {
+ // Simulate the previous app already having completed onboarding in a generally available build.
+ executeInPreviousAppInstance { testComponent ->
+ TestModule.buildFlavor = BuildFlavor.GENERAL_AVAILABILITY
+ testComponent.getAppStartupStateController().markOnboardingFlowCompleted()
+ testComponent.getTestCoroutineDispatchers().runCurrent()
+ }
+ TestModule.buildFlavor = BuildFlavor.BETA
+ setUpDefaultTestApplicationComponent()
+
+ val appStartupState = appStartupStateController.getAppStartupState()
+
+ // Changing from GA to beta should result in the notice showing.
+ val mode = monitorFactory.waitForNextSuccessfulResult(appStartupState)
+ assertThat(mode.buildFlavorNoticeMode).isEqualTo(SHOW_BETA_NOTICE)
+ }
+
+ @Test
+ fun testController_userOnboarded_changeToGaBuild_fromDeveloperBuild_showNoNotice() {
+ // Simulate the previous app already having completed onboarding in an developer-only build.
+ executeInPreviousAppInstance { testComponent ->
+ TestModule.buildFlavor = BuildFlavor.DEVELOPER
+ testComponent.getAppStartupStateController().markOnboardingFlowCompleted()
+ testComponent.getTestCoroutineDispatchers().runCurrent()
+ }
+ TestModule.buildFlavor = BuildFlavor.GENERAL_AVAILABILITY
+ setUpDefaultTestApplicationComponent()
+
+ val appStartupState = appStartupStateController.getAppStartupState()
+
+ // The GA upgrade notice is only shown when changing from alpha or beta.
+ val mode = monitorFactory.waitForNextSuccessfulResult(appStartupState)
+ assertThat(mode.buildFlavorNoticeMode).isEqualTo(NO_NOTICE)
+ }
+
+ @Test
+ fun testController_userOnboarded_changeToGaBuild_fromAlpha_showGaNotice() {
+ // Simulate the previous app already having completed onboarding in an alpha build.
+ executeInPreviousAppInstance { testComponent ->
+ TestModule.buildFlavor = BuildFlavor.ALPHA
+ testComponent.getAppStartupStateController().markOnboardingFlowCompleted()
+ testComponent.getTestCoroutineDispatchers().runCurrent()
+ }
+ TestModule.buildFlavor = BuildFlavor.GENERAL_AVAILABILITY
+ setUpDefaultTestApplicationComponent()
+
+ val appStartupState = appStartupStateController.getAppStartupState()
+
+ // Changing from alpha to GA should result in the GA upgrade notice showing.
+ val mode = monitorFactory.waitForNextSuccessfulResult(appStartupState)
+ assertThat(mode.buildFlavorNoticeMode).isEqualTo(SHOW_UPGRADE_TO_GENERAL_AVAILABILITY_NOTICE)
+ }
+
+ @Test
+ fun testController_userOnboarded_changeToGaBuild_fromBeta_showGaNotice() {
+ // Simulate the previous app already having completed onboarding in a beta build.
+ executeInPreviousAppInstance { testComponent ->
+ TestModule.buildFlavor = BuildFlavor.BETA
+ testComponent.getAppStartupStateController().markOnboardingFlowCompleted()
+ testComponent.getTestCoroutineDispatchers().runCurrent()
+ }
+ TestModule.buildFlavor = BuildFlavor.GENERAL_AVAILABILITY
+ setUpDefaultTestApplicationComponent()
+
+ val appStartupState = appStartupStateController.getAppStartupState()
+
+ // Changing from beta to GA should result in the GA upgrade notice showing.
+ val mode = monitorFactory.waitForNextSuccessfulResult(appStartupState)
+ assertThat(mode.buildFlavorNoticeMode).isEqualTo(SHOW_UPGRADE_TO_GENERAL_AVAILABILITY_NOTICE)
+ }
+
+ @Test
+ fun testController_userOnboarded_changeToGaBuild_fromGaAgain_showNoNotice() {
+ // Simulate the previous app already having completed onboarding in a generally available build.
+ executeInPreviousAppInstance { testComponent ->
+ TestModule.buildFlavor = BuildFlavor.GENERAL_AVAILABILITY
+ testComponent.getAppStartupStateController().markOnboardingFlowCompleted()
+ testComponent.getTestCoroutineDispatchers().runCurrent()
+ }
+ TestModule.buildFlavor = BuildFlavor.GENERAL_AVAILABILITY
+ setUpDefaultTestApplicationComponent()
+
+ val appStartupState = appStartupStateController.getAppStartupState()
+
+ // The GA upgrade notice is only shown when changing from beta.
+ val mode = monitorFactory.waitForNextSuccessfulResult(appStartupState)
+ assertThat(mode.buildFlavorNoticeMode).isEqualTo(NO_NOTICE)
+ }
+
+ /* Tests to verify that notices can be permanently dismissed. */
+
+ @Test
+ fun testController_dismissBetaNoticePermanently_scenariosWithoutBetaNotice_showNoNotice() {
+ executeInPreviousAppInstance { testComponent ->
+ TestModule.buildFlavor = BuildFlavor.BETA
+ testComponent.getAppStartupStateController().apply {
+ markOnboardingFlowCompleted()
+ // While this is technically impossible for this exact configuration, it could be done by
+ // permanently dismissing during an earlier time when the notice was shown before the user
+ // returned to the beta flavor of the app.
+ dismissBetaNoticesPermanently()
+ }
+ testComponent.getTestCoroutineDispatchers().runCurrent()
+ }
+ TestModule.buildFlavor = BuildFlavor.BETA
+ setUpDefaultTestApplicationComponent()
+
+ val appStartupState = appStartupStateController.getAppStartupState()
+
+ // No notice is shown in this case (beta -> beta).
+ val mode = monitorFactory.waitForNextSuccessfulResult(appStartupState)
+ assertThat(mode.buildFlavorNoticeMode).isEqualTo(NO_NOTICE)
+ }
+
+ @Test
+ @RunParameterized(
+ Iteration("testing_to_beta", "initialFlavorName=TESTING"),
+ Iteration("dev_to_beta", "initialFlavorName=DEVELOPER"),
+ Iteration("alpha_to_beta", "initialFlavorName=ALPHA"),
+ Iteration("ga_to_beta", "initialFlavorName=GENERAL_AVAILABILITY")
+ )
+ fun testController_dismissBetaNoticePermanently_scenariosWhenBetaNoticeDoesShow_showNoNotice() {
+ executeInPreviousAppInstance { testComponent ->
+ TestModule.buildFlavor = BuildFlavor.valueOf(initialFlavorName)
+ testComponent.getAppStartupStateController().apply {
+ markOnboardingFlowCompleted()
+ dismissBetaNoticesPermanently()
+ }
+ testComponent.getTestCoroutineDispatchers().runCurrent()
+ }
+ TestModule.buildFlavor = BuildFlavor.BETA
+ setUpDefaultTestApplicationComponent()
+
+ val appStartupState = appStartupStateController.getAppStartupState()
+
+ // Despite a notice normally showing in this circumstance, it doesn't here since the beta notice
+ // was permanently disabled.
+ val mode = monitorFactory.waitForNextSuccessfulResult(appStartupState)
+ assertThat(mode.buildFlavorNoticeMode).isEqualTo(NO_NOTICE)
+ }
+
+ @Test
+ @RunParameterized(
+ Iteration("testing_to_ga", "initialFlavorName=TESTING"),
+ Iteration("dev_to_ga", "initialFlavorName=DEVELOPER")
+ )
+ fun testController_dismissGaNoticePermanently_scenariosWhenGaNoticeDoesNotShow_showNoNotice() {
+ executeInPreviousAppInstance { testComponent ->
+ TestModule.buildFlavor = BuildFlavor.valueOf(initialFlavorName)
+ testComponent.getAppStartupStateController().apply {
+ markOnboardingFlowCompleted()
+ dismissGaUpgradeNoticesPermanently()
+ }
+ testComponent.getTestCoroutineDispatchers().runCurrent()
+ }
+ TestModule.buildFlavor = BuildFlavor.GENERAL_AVAILABILITY
+ setUpDefaultTestApplicationComponent()
+
+ val appStartupState = appStartupStateController.getAppStartupState()
+
+ // A notice does not show in these circumstances (though, it wouldn't be expected to regardless
+ // of whether the GA notice was permanently disabled).
+ val mode = monitorFactory.waitForNextSuccessfulResult(appStartupState)
+ assertThat(mode.buildFlavorNoticeMode).isEqualTo(NO_NOTICE)
+ }
+
+ @Test
+ @RunParameterized(
+ Iteration("alpha_to_ga", "initialFlavorName=ALPHA"),
+ Iteration("beta_to_ga", "initialFlavorName=BETA")
+ )
+ fun testController_dismissGaNoticePermanently_scenariosWhenGaNoticeDoesShow_showNoNotice() {
+ executeInPreviousAppInstance { testComponent ->
+ TestModule.buildFlavor = BuildFlavor.valueOf(initialFlavorName)
+ testComponent.getAppStartupStateController().apply {
+ markOnboardingFlowCompleted()
+ dismissGaUpgradeNoticesPermanently()
+ }
+ testComponent.getTestCoroutineDispatchers().runCurrent()
+ }
+ TestModule.buildFlavor = BuildFlavor.GENERAL_AVAILABILITY
+ setUpDefaultTestApplicationComponent()
+
+ val appStartupState = appStartupStateController.getAppStartupState()
+
+ // Despite a notice normally showing in this circumstance, it doesn't here since the GA upgrade
+ // notice was permanently disabled.
+ val mode = monitorFactory.waitForNextSuccessfulResult(appStartupState)
+ assertThat(mode.buildFlavorNoticeMode).isEqualTo(NO_NOTICE)
+ }
+
private fun setUpTestApplicationComponent() {
ApplicationProvider.getApplicationContext().inject(this)
}
@@ -277,7 +784,7 @@ class AppStartupStateControllerTest {
* Note that only dependencies fetched from the specified [TestApplicationComponent] should be
* used, not any class-level injected dependencies.
*/
- private fun executeInPreviousApp(block: (TestApplicationComponent) -> Unit) {
+ private fun executeInPreviousAppInstance(block: (TestApplicationComponent) -> Unit) {
val testApplication = TestApplication()
// The true application is hooked as a base context. This is to make sure the new application
// can behave like a real Android application class (per Robolectric) without having a shared
@@ -341,6 +848,10 @@ class AppStartupStateControllerTest {
// TODO(#89): Move this to a common test application component.
@Module
class TestModule {
+ companion object {
+ var buildFlavor = BuildFlavor.BUILD_FLAVOR_UNSPECIFIED
+ }
+
@Provides
@Singleton
fun provideContext(application: Application): Context {
@@ -360,6 +871,9 @@ class AppStartupStateControllerTest {
@GlobalLogLevel
@Provides
fun provideGlobalLogLevel(): LogLevel = LogLevel.VERBOSE
+
+ @Provides
+ fun provideTestingBuildFlavor(): BuildFlavor = buildFlavor
}
// TODO(#89): Move this to a common test application component.
diff --git a/domain/src/test/java/org/oppia/android/domain/onboarding/BUILD.bazel b/domain/src/test/java/org/oppia/android/domain/onboarding/BUILD.bazel
new file mode 100644
index 00000000000..85124495fd0
--- /dev/null
+++ b/domain/src/test/java/org/oppia/android/domain/onboarding/BUILD.bazel
@@ -0,0 +1,39 @@
+"""
+Tests for domain components pertaining to onboarding the user to the app.
+"""
+
+load("@dagger//:workspace_defs.bzl", "dagger_rules")
+load("//:oppia_android_test.bzl", "oppia_android_test")
+
+oppia_android_test(
+ name = "AppStartupStateControllerTest",
+ srcs = ["AppStartupStateControllerTest.kt"],
+ custom_package = "org.oppia.android.domain.onboarding",
+ test_class = "org.oppia.android.domain.onboarding.AppStartupStateControllerTest",
+ test_manifest = "//domain:test_manifest",
+ deps = [
+ ":dagger",
+ "//domain",
+ "//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",
+ "//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()
diff --git a/instrumentation/src/java/org/oppia/android/instrumentation/application/BUILD.bazel b/instrumentation/src/java/org/oppia/android/instrumentation/application/BUILD.bazel
index 10e816007b1..78c15038969 100644
--- a/instrumentation/src/java/org/oppia/android/instrumentation/application/BUILD.bazel
+++ b/instrumentation/src/java/org/oppia/android/instrumentation/application/BUILD.bazel
@@ -22,6 +22,7 @@ kt_android_library(
"//app/src/main/java/org/oppia/android/app/application:abstract_application",
"//app/src/main/java/org/oppia/android/app/application:application_component",
"//app/src/main/java/org/oppia/android/app/application:common_application_modules",
+ "//app/src/main/java/org/oppia/android/app/application/testing:testing_build_flavor_module",
"//data/src/main/java/org/oppia/android/data/backends/gae:network_config_annotations",
"//domain",
"//utility",
diff --git a/instrumentation/src/java/org/oppia/android/instrumentation/application/TestApplicationComponent.kt b/instrumentation/src/java/org/oppia/android/instrumentation/application/TestApplicationComponent.kt
index b8f2ba6422a..7a95bcc6990 100644
--- a/instrumentation/src/java/org/oppia/android/instrumentation/application/TestApplicationComponent.kt
+++ b/instrumentation/src/java/org/oppia/android/instrumentation/application/TestApplicationComponent.kt
@@ -4,6 +4,7 @@ import dagger.Component
import org.oppia.android.app.application.ApplicationComponent
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -96,7 +97,8 @@ import javax.inject.Singleton
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
SyncStatusModule::class, NetworkConnectionDebugUtilModule::class,
MetricLogSchedulerModule::class, PerformanceMetricsLoggerModule::class,
- PerformanceMetricsAssessorModule::class, PerformanceMetricsConfigurationsModule::class
+ PerformanceMetricsAssessorModule::class, PerformanceMetricsConfigurationsModule::class,
+ TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/model/src/main/proto/BUILD.bazel b/model/src/main/proto/BUILD.bazel
index c6d19966e44..94372b448ff 100644
--- a/model/src/main/proto/BUILD.bazel
+++ b/model/src/main/proto/BUILD.bazel
@@ -112,6 +112,7 @@ java_lite_proto_library(
oppia_proto_library(
name = "onboarding_proto",
srcs = ["onboarding.proto"],
+ deps = [":version_proto"],
)
java_lite_proto_library(
@@ -191,6 +192,18 @@ java_lite_proto_library(
deps = [":translation_proto"],
)
+oppia_proto_library(
+ name = "version_proto",
+ srcs = ["version.proto"],
+ visibility = ["//:oppia_api_visibility"],
+)
+
+java_lite_proto_library(
+ name = "version_java_proto_lite",
+ visibility = ["//:oppia_api_visibility"],
+ deps = [":version_proto"],
+)
+
oppia_proto_library(
name = "voiceover_proto",
srcs = ["voiceover.proto"],
diff --git a/model/src/main/proto/onboarding.proto b/model/src/main/proto/onboarding.proto
index ca2027922ec..3ed97a65062 100644
--- a/model/src/main/proto/onboarding.proto
+++ b/model/src/main/proto/onboarding.proto
@@ -2,6 +2,8 @@ syntax = "proto3";
package model;
+import "version.proto";
+
option java_package = "org.oppia.android.app.model";
option java_multiple_files = true;
@@ -24,15 +26,51 @@ message AppStartupState {
APP_IS_DEPRECATED = 3;
}
+ // Describes different notices that may be shown to the user on startup depending on whether
+ // they're using or have used a pre-release version of the app.
+ enum BuildFlavorNoticeMode {
+ // Indicates that the current build flavor notice mode is unknown.
+ FLAVOR_NOTICE_MODE_UNSPECIFIED = 0;
+
+ // Indicates that the user is not in a situation where a notice should be shown (either because
+ // they aren't or haven't recently used a pre-release version of the app, or they've asked to
+ // not see those notices again).
+ NO_NOTICE = 1;
+
+ // Indicates that the user should be a shown a notice mentioning that they're currently using a
+ // beta version of the app.
+ SHOW_BETA_NOTICE = 2;
+
+ // Indicates that the user should be shown a notice mentioning that they've recently upgraded to
+ // the general availability version of the app.
+ SHOW_UPGRADE_TO_GENERAL_AVAILABILITY_NOTICE = 3;
+ }
+
// Contains the user's startup state upon opening the app. This may change from app open to app
// open, but should remain constant throughout the lifetime of a single process.
StartupMode startup_mode = 1;
+
// Indicates if the app is starting up again immediately after a crash has occurred.
bool is_from_crash = 2;
+
+ // Indicates whether the user should be shown a startup notice based on their recent usage of
+ // different build flavors of the app.
+ BuildFlavorNoticeMode build_flavor_notice_mode = 3;
}
// Stores the completion state of the user's progress through the app onboarding flow.
message OnboardingState {
// Indicates whether user has fully completed the onboarding flow.
bool already_onboarded_app = 1;
+
+ // Represents the build flavor of the app the last time the user used it.
+ BuildFlavor last_used_build_flavor = 2;
+
+ // Represents whether the user has seen, and asked to not see again, the notice that they're using
+ // a beta version of the app.
+ bool permanently_dismissed_beta_notice = 3;
+
+ // Represents whether the user has seen, and asked to not see again, the notice that they're using
+ // the general availability version of the app after having previously used a pre-release version.
+ bool permanently_dismissed_ga_upgrade_notice = 4;
}
diff --git a/model/src/main/proto/version.proto b/model/src/main/proto/version.proto
new file mode 100644
index 00000000000..a0878579e57
--- /dev/null
+++ b/model/src/main/proto/version.proto
@@ -0,0 +1,32 @@
+syntax = "proto3";
+
+package model;
+
+option java_package = "org.oppia.android.app.model";
+option java_multiple_files = true;
+
+// Represents different compile-time build flavors that the app may be built under.
+enum BuildFlavor {
+ // Indicates an unknown build flavor (in these situations, client code should fall back to a
+ // reasonable default).
+ BUILD_FLAVOR_UNSPECIFIED = 0;
+
+ // Corresponds to a testing environment-specific build of the app. Note that this is different
+ // than a 'test version' of the app for the purpose of quality assurance testing. The QA team will
+ // always be testing one of the user-facing flavors of the app (generally alpha, beta, and GA, but
+ // potentially the developer flavor on occasion). This flavor is never expected to be used for a
+ // version of the app used directly by a human.
+ TESTING = 1;
+
+ // Corresponds to a developer-only build of the app.
+ DEVELOPER = 2;
+
+ // Corresponds to an alpha (closed testing track) pre-release build of the app.
+ ALPHA = 3;
+
+ // Corresponds to a beta (open testing track) pre-release/early access build of the app.
+ BETA = 4;
+
+ // Corresponds to a generally available production build of the app.
+ GENERAL_AVAILABILITY = 5;
+}
diff --git a/scripts/assets/file_content_validation_checks.textproto b/scripts/assets/file_content_validation_checks.textproto
index ab76d9e3ddf..0c585bad36b 100644
--- a/scripts/assets/file_content_validation_checks.textproto
+++ b/scripts/assets/file_content_validation_checks.textproto
@@ -291,6 +291,7 @@ file_content_checks {
prohibited_content_regex: "OppiaParameterizedTestRunner"
failure_message: "To use OppiaParameterizedTestRunner, please add an exemption to file_content_validation_checks.textproto and add an explanation for your use case in your PR description. Note that parameterized tests should only be used in special circumstances where a single behavior can be tested across multiple inputs, or for especially large test suites that can be trivially reduced."
exempted_file_name: "app/src/sharedTest/java/org/oppia/android/app/customview/interaction/MathExpressionInteractionsViewTest.kt"
+ exempted_file_name: "app/src/sharedTest/java/org/oppia/android/app/splash/SplashActivityTest.kt"
exempted_file_name: "app/src/test/java/org/oppia/android/app/utility/math/MathExpressionAccessibilityUtilTest.kt"
exempted_file_name: "domain/src/test/java/org/oppia/android/domain/classify/rules/algebraicexpressioninput/AlgebraicExpressionInputIsEquivalentToRuleClassifierProviderTest.kt"
exempted_file_name: "domain/src/test/java/org/oppia/android/domain/classify/rules/algebraicexpressioninput/AlgebraicExpressionInputMatchesExactlyWithRuleClassifierProviderTest.kt"
@@ -301,6 +302,7 @@ file_content_checks {
exempted_file_name: "domain/src/test/java/org/oppia/android/domain/classify/rules/numericexpressioninput/NumericExpressionInputIsEquivalentToRuleClassifierProviderTest.kt"
exempted_file_name: "domain/src/test/java/org/oppia/android/domain/classify/rules/numericexpressioninput/NumericExpressionInputMatchesExactlyWithRuleClassifierProviderTest.kt"
exempted_file_name: "domain/src/test/java/org/oppia/android/domain/classify/rules/numericexpressioninput/NumericExpressionInputMatchesUpToTrivialManipulationsRuleClassifierProviderTest.kt"
+ exempted_file_name: "domain/src/test/java/org/oppia/android/domain/onboarding/AppStartupStateControllerTest.kt"
exempted_file_name: "domain/src/test/java/org/oppia/android/domain/oppialogger/analytics/LearnerAnalyticsLoggerTest.kt"
exempted_file_name: "scripts/src/javatests/org/oppia/android/scripts/regex/RegexPatternValidationCheckTest.kt"
exempted_file_name: "utility/src/test/java/org/oppia/android/util/math/ExpressionToComparableOperationConverterTest.kt"
diff --git a/scripts/assets/kdoc_validity_exemptions.textproto b/scripts/assets/kdoc_validity_exemptions.textproto
index edae7eeecd5..eb430e59c77 100644
--- a/scripts/assets/kdoc_validity_exemptions.textproto
+++ b/scripts/assets/kdoc_validity_exemptions.textproto
@@ -23,7 +23,7 @@ exempted_file_path: "app/src/main/java/org/oppia/android/app/completedstorylist/
exempted_file_path: "app/src/main/java/org/oppia/android/app/completedstorylist/CompletedStoryListViewModel.kt"
exempted_file_path: "app/src/main/java/org/oppia/android/app/customview/LessonThumbnailImageView.kt"
exempted_file_path: "app/src/main/java/org/oppia/android/app/customview/SegmentedCircularProgressView.kt"
-exempted_file_path: "app/src/main/java/org/oppia/android/app/deprecation/AutomaticAppDeprecationNoticeDialogFragmentPresenter.kt"
+exempted_file_path: "app/src/main/java/org/oppia/android/app/notice/AutomaticAppDeprecationNoticeDialogFragmentPresenter.kt"
exempted_file_path: "app/src/main/java/org/oppia/android/app/devoptions/DeveloperOptionsActivity.kt"
exempted_file_path: "app/src/main/java/org/oppia/android/app/devoptions/DeveloperOptionsActivityPresenter.kt"
exempted_file_path: "app/src/main/java/org/oppia/android/app/devoptions/DeveloperOptionsFragment.kt"
diff --git a/scripts/assets/test_file_exemptions.textproto b/scripts/assets/test_file_exemptions.textproto
index 24119196db3..8018118b950 100644
--- a/scripts/assets/test_file_exemptions.textproto
+++ b/scripts/assets/test_file_exemptions.textproto
@@ -51,8 +51,12 @@ exempted_file_path: "app/src/main/java/org/oppia/android/app/application/alpha/A
exempted_file_path: "app/src/main/java/org/oppia/android/app/application/alphakenya/AlphaKenyaApplicationComponent.kt"
exempted_file_path: "app/src/main/java/org/oppia/android/app/application/alphakenya/AlphaKenyaBuildFlavorModule.kt"
exempted_file_path: "app/src/main/java/org/oppia/android/app/application/alphakenya/AlphaKenyaOppiaApplication.kt"
+exempted_file_path: "app/src/main/java/org/oppia/android/app/application/beta/BetaOppiaApplication.kt"
+exempted_file_path: "app/src/main/java/org/oppia/android/app/application/beta/BetaApplicationComponent.kt"
exempted_file_path: "app/src/main/java/org/oppia/android/app/application/dev/DeveloperOppiaApplication.kt"
exempted_file_path: "app/src/main/java/org/oppia/android/app/application/dev/DeveloperApplicationComponent.kt"
+exempted_file_path: "app/src/main/java/org/oppia/android/app/application/ga/GaOppiaApplication.kt"
+exempted_file_path: "app/src/main/java/org/oppia/android/app/application/ga/GaApplicationComponent.kt"
exempted_file_path: "app/src/main/java/org/oppia/android/app/completedstorylist/CompletedStoryItemViewModel.kt"
exempted_file_path: "app/src/main/java/org/oppia/android/app/completedstorylist/CompletedStoryListActivityPresenter.kt"
exempted_file_path: "app/src/main/java/org/oppia/android/app/completedstorylist/CompletedStoryListFragment.kt"
@@ -64,9 +68,13 @@ exempted_file_path: "app/src/main/java/org/oppia/android/app/customview/interact
exempted_file_path: "app/src/main/java/org/oppia/android/app/customview/interaction/NumericInputInteractionView.kt"
exempted_file_path: "app/src/main/java/org/oppia/android/app/customview/interaction/RatioInputInteractionView.kt"
exempted_file_path: "app/src/main/java/org/oppia/android/app/customview/interaction/TextInputInteractionView.kt"
-exempted_file_path: "app/src/main/java/org/oppia/android/app/deprecation/AutomaticAppDeprecationNoticeDialogFragment.kt"
-exempted_file_path: "app/src/main/java/org/oppia/android/app/deprecation/AutomaticAppDeprecationNoticeDialogFragmentPresenter.kt"
-exempted_file_path: "app/src/main/java/org/oppia/android/app/deprecation/DeprecationNoticeExitAppListener.kt"
+exempted_file_path: "app/src/main/java/org/oppia/android/app/notice/AutomaticAppDeprecationNoticeDialogFragment.kt"
+exempted_file_path: "app/src/main/java/org/oppia/android/app/notice/AutomaticAppDeprecationNoticeDialogFragmentPresenter.kt"
+exempted_file_path: "app/src/main/java/org/oppia/android/app/notice/BetaNoticeClosedListener.kt"
+exempted_file_path: "app/src/main/java/org/oppia/android/app/notice/BetaNoticeDialogFragmentPresenter.kt"
+exempted_file_path: "app/src/main/java/org/oppia/android/app/notice/DeprecationNoticeExitAppListener.kt"
+exempted_file_path: "app/src/main/java/org/oppia/android/app/notice/GeneralAvailabilityUpgradeNoticeClosedListener.kt"
+exempted_file_path: "app/src/main/java/org/oppia/android/app/notice/GeneralAvailabilityUpgradeNoticeDialogFragmentPresenter.kt"
exempted_file_path: "app/src/main/java/org/oppia/android/app/devoptions/DeveloperOptionsActivityPresenter.kt"
exempted_file_path: "app/src/main/java/org/oppia/android/app/devoptions/DeveloperOptionsFragmentPresenter.kt"
exempted_file_path: "app/src/main/java/org/oppia/android/app/devoptions/DeveloperOptionsModule.kt"
@@ -215,6 +223,8 @@ exempted_file_path: "app/src/main/java/org/oppia/android/app/mydownloads/MyDownl
exempted_file_path: "app/src/main/java/org/oppia/android/app/mydownloads/MyDownloadsViewPagerAdapter.kt"
exempted_file_path: "app/src/main/java/org/oppia/android/app/mydownloads/UpdatesTabFragment.kt"
exempted_file_path: "app/src/main/java/org/oppia/android/app/mydownloads/UpdatesTabFragmentPresenter.kt"
+exempted_file_path: "app/src/main/java/org/oppia/android/app/notice/testing/BetaNoticeDialogFragmentTestActivity.kt"
+exempted_file_path: "app/src/main/java/org/oppia/android/app/notice/testing/GeneralAvailabilityUpgradeNoticeDialogFragmentTestActivity.kt"
exempted_file_path: "app/src/main/java/org/oppia/android/app/onboarding/OnboadingSlideViewModel.kt"
exempted_file_path: "app/src/main/java/org/oppia/android/app/onboarding/OnboardingActivityPresenter.kt"
exempted_file_path: "app/src/main/java/org/oppia/android/app/onboarding/OnboardingFragmentPresenter.kt"
diff --git a/testing/src/main/java/org/oppia/android/testing/OppiaTestRunner.kt b/testing/src/main/java/org/oppia/android/testing/OppiaTestRunner.kt
index 30a9a81d934..8ac79646368 100644
--- a/testing/src/main/java/org/oppia/android/testing/OppiaTestRunner.kt
+++ b/testing/src/main/java/org/oppia/android/testing/OppiaTestRunner.kt
@@ -27,7 +27,7 @@ class OppiaTestRunner : AndroidJUnitRunner() {
// Load a new application if it's different than the original.
val bindApplication = retrieveTestApplicationName(arguments?.getString("class"))?.let {
newApplication(applicationClassLoader, it, targetContext)
- } ?: targetContext.applicationContext as Application
+ } ?: targetContext as Application
// Ensure the bound application is forcibly overwritten in the target context, and used
// subsequently throughout the runner since it's replacing the previous application.
diff --git a/testing/src/test/java/org/oppia/android/testing/junit/BUILD.bazel b/testing/src/test/java/org/oppia/android/testing/junit/BUILD.bazel
index 6dcc99d23a8..cde8eeeb69a 100644
--- a/testing/src/test/java/org/oppia/android/testing/junit/BUILD.bazel
+++ b/testing/src/test/java/org/oppia/android/testing/junit/BUILD.bazel
@@ -18,6 +18,7 @@ oppia_android_test(
"//app/src/main/java/org/oppia/android/app/application:application_injector",
"//app/src/main/java/org/oppia/android/app/application:application_injector_provider",
"//app/src/main/java/org/oppia/android/app/application:common_application_modules",
+ "//app/src/main/java/org/oppia/android/app/application/testing:testing_build_flavor_module",
"//app/src/main/java/org/oppia/android/app/translation:app_language_locale_handler",
"//app/src/main/java/org/oppia/android/app/translation/testing:test_module",
"//domain",
@@ -71,6 +72,7 @@ oppia_android_test(
"//app/src/main/java/org/oppia/android/app/application:application_injector",
"//app/src/main/java/org/oppia/android/app/application:application_injector_provider",
"//app/src/main/java/org/oppia/android/app/application:common_application_modules",
+ "//app/src/main/java/org/oppia/android/app/application/testing:testing_build_flavor_module",
"//app/src/main/java/org/oppia/android/app/translation:app_language_locale_handler",
"//app/src/main/java/org/oppia/android/app/translation/testing:test_module",
"//domain",
@@ -123,6 +125,7 @@ oppia_android_test(
"//app/src/main/java/org/oppia/android/app/application:application_injector",
"//app/src/main/java/org/oppia/android/app/application:application_injector_provider",
"//app/src/main/java/org/oppia/android/app/application:common_application_modules",
+ "//app/src/main/java/org/oppia/android/app/application/testing:testing_build_flavor_module",
"//app/src/main/java/org/oppia/android/app/translation:app_language_locale_handler",
"//app/src/main/java/org/oppia/android/app/translation/testing:test_module",
"//domain",
diff --git a/testing/src/test/java/org/oppia/android/testing/junit/InitializeDefaultLocaleRuleCustomContextTest.kt b/testing/src/test/java/org/oppia/android/testing/junit/InitializeDefaultLocaleRuleCustomContextTest.kt
index 51e520fb94b..0064df9d8cc 100644
--- a/testing/src/test/java/org/oppia/android/testing/junit/InitializeDefaultLocaleRuleCustomContextTest.kt
+++ b/testing/src/test/java/org/oppia/android/testing/junit/InitializeDefaultLocaleRuleCustomContextTest.kt
@@ -18,6 +18,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.model.OppiaLanguage
@@ -265,7 +266,7 @@ class InitializeDefaultLocaleRuleCustomContextTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/testing/src/test/java/org/oppia/android/testing/junit/InitializeDefaultLocaleRuleOmissionTest.kt b/testing/src/test/java/org/oppia/android/testing/junit/InitializeDefaultLocaleRuleOmissionTest.kt
index 65b3bc82a08..4eeb5333f5c 100644
--- a/testing/src/test/java/org/oppia/android/testing/junit/InitializeDefaultLocaleRuleOmissionTest.kt
+++ b/testing/src/test/java/org/oppia/android/testing/junit/InitializeDefaultLocaleRuleOmissionTest.kt
@@ -17,6 +17,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule
@@ -141,7 +142,7 @@ class InitializeDefaultLocaleRuleOmissionTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/testing/src/test/java/org/oppia/android/testing/junit/InitializeDefaultLocaleRuleTest.kt b/testing/src/test/java/org/oppia/android/testing/junit/InitializeDefaultLocaleRuleTest.kt
index a53e4b716e0..4cb60a9367a 100644
--- a/testing/src/test/java/org/oppia/android/testing/junit/InitializeDefaultLocaleRuleTest.kt
+++ b/testing/src/test/java/org/oppia/android/testing/junit/InitializeDefaultLocaleRuleTest.kt
@@ -18,6 +18,7 @@ import org.oppia.android.app.application.ApplicationInjector
import org.oppia.android.app.application.ApplicationInjectorProvider
import org.oppia.android.app.application.ApplicationModule
import org.oppia.android.app.application.ApplicationStartupListenerModule
+import org.oppia.android.app.application.testing.TestingBuildFlavorModule
import org.oppia.android.app.devoptions.DeveloperOptionsModule
import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule
import org.oppia.android.app.model.OppiaLanguage
@@ -145,7 +146,7 @@ class InitializeDefaultLocaleRuleTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/utility/src/main/java/org/oppia/android/util/data/DataProvider.kt b/utility/src/main/java/org/oppia/android/util/data/DataProvider.kt
index 5b940afa095..0cb2e1b97dd 100644
--- a/utility/src/main/java/org/oppia/android/util/data/DataProvider.kt
+++ b/utility/src/main/java/org/oppia/android/util/data/DataProvider.kt
@@ -1,14 +1,13 @@
package org.oppia.android.util.data
-import android.content.Context
+import android.app.Application
/**
* Represents a provider of data that can be delivered and changed asynchronously.
*
* @param The type of data being provided.
*/
-abstract class DataProvider(val context: Context) {
-
+abstract class DataProvider(val application: Application) {
/**
* Returns a unique identifier that corresponds to this data provider. This should be a trivially
* copyable and immutable object. This ID is used to determine which data provider subscribers
diff --git a/utility/src/main/java/org/oppia/android/util/data/DataProviders.kt b/utility/src/main/java/org/oppia/android/util/data/DataProviders.kt
index e86c139c122..93049848c3c 100644
--- a/utility/src/main/java/org/oppia/android/util/data/DataProviders.kt
+++ b/utility/src/main/java/org/oppia/android/util/data/DataProviders.kt
@@ -1,6 +1,6 @@
package org.oppia.android.util.data
-import android.content.Context
+import android.app.Application
import androidx.lifecycle.LiveData
import dagger.Reusable
import kotlinx.coroutines.CoroutineDispatcher
@@ -26,7 +26,7 @@ import javax.inject.Inject
*/
@Reusable // Since otherwise a new provider will be created for each companion object call.
class DataProviders @Inject constructor(
- private val context: Context,
+ private val application: Application,
@BackgroundDispatcher private val backgroundDispatcher: CoroutineDispatcher,
private val asyncDataSubscriptionManager: AsyncDataSubscriptionManager,
private val exceptionLogger: ExceptionLogger
@@ -46,7 +46,7 @@ class DataProviders @Inject constructor(
fun DataProvider.transform(newId: Any, function: (I) -> O): DataProvider {
val dataProviders = getDataProviders()
dataProviders.asyncDataSubscriptionManager.associateIds(newId, getId())
- return object : DataProvider(context) {
+ return object : DataProvider(application) {
override fun getId(): Any = newId
override suspend fun retrieveData(): AsyncResult {
@@ -70,7 +70,7 @@ class DataProviders @Inject constructor(
): DataProvider {
val dataProviders = getDataProviders()
dataProviders.asyncDataSubscriptionManager.associateIds(newId, getId())
- return object : DataProvider(context) {
+ return object : DataProvider(application) {
override fun getId(): Any = newId
override suspend fun retrieveData(): AsyncResult {
@@ -90,7 +90,7 @@ class DataProviders @Inject constructor(
function: suspend (I) -> AsyncResult
): NestedTransformedDataProvider {
return NestedTransformedDataProvider.createNestedTransformedDataProvider(
- context, newId, this, function, getDataProviders().asyncDataSubscriptionManager
+ application, newId, this, function, getDataProviders().asyncDataSubscriptionManager
)
}
@@ -113,7 +113,7 @@ class DataProviders @Inject constructor(
val dataProviders = getDataProviders()
dataProviders.asyncDataSubscriptionManager.associateIds(newId, getId())
dataProviders.asyncDataSubscriptionManager.associateIds(newId, dataProvider.getId())
- return object : DataProvider(context) {
+ return object : DataProvider(application) {
override fun getId(): Any {
return newId
}
@@ -141,7 +141,7 @@ class DataProviders @Inject constructor(
val dataProviders = getDataProviders()
dataProviders.asyncDataSubscriptionManager.associateIds(newId, getId())
dataProviders.asyncDataSubscriptionManager.associateIds(newId, dataProvider.getId())
- return object : DataProvider(context) {
+ return object : DataProvider(application) {
override fun getId(): Any {
return newId
}
@@ -167,7 +167,7 @@ class DataProviders @Inject constructor(
}
private fun DataProvider.getDataProviders(): DataProviders {
- val injectorProvider = context.applicationContext as DataProvidersInjectorProvider
+ val injectorProvider = application as DataProvidersInjectorProvider
return injectorProvider.getDataProvidersInjector().getDataProviders()
}
}
@@ -184,7 +184,7 @@ class DataProviders @Inject constructor(
* [AsyncDataSubscriptionManager.notifyChange] with the in-memory provider's identifier.
*/
fun createInMemoryDataProvider(id: Any, loadFromMemory: () -> T): DataProvider {
- return object : DataProvider(context) {
+ return object : DataProvider(application) {
override fun getId(): Any {
return id
}
@@ -208,7 +208,7 @@ class DataProviders @Inject constructor(
id: Any,
loadFromMemoryAsync: suspend () -> AsyncResult
): DataProvider {
- return object : DataProvider(context) {
+ return object : DataProvider(application) {
override fun getId(): Any {
return id
}
@@ -277,12 +277,12 @@ class DataProviders @Inject constructor(
* provider can change.
*/
class NestedTransformedDataProvider private constructor(
- context: Context,
+ application: Application,
private val id: Any,
private var baseId: Any,
private val asyncDataSubscriptionManager: AsyncDataSubscriptionManager,
private var retrieveTransformedData: suspend () -> AsyncResult
- ) : DataProvider(context) {
+ ) : DataProvider(application) {
init {
initializeTransformer()
}
@@ -320,14 +320,14 @@ class DataProviders @Inject constructor(
companion object {
/** Returns a new [NestedTransformedDataProvider]. */
internal fun createNestedTransformedDataProvider(
- context: Context,
+ application: Application,
id: Any,
baseDataProvider: DataProvider,
transform: suspend (I) -> AsyncResult,
asyncDataSubscriptionManager: AsyncDataSubscriptionManager
): NestedTransformedDataProvider {
return NestedTransformedDataProvider(
- context, id, baseDataProvider.getId(), asyncDataSubscriptionManager
+ application, id, baseDataProvider.getId(), asyncDataSubscriptionManager
) {
baseDataProvider.retrieveData().transformAsync(transform)
}
diff --git a/utility/src/main/java/org/oppia/android/util/data/InMemoryBlockingCache.kt b/utility/src/main/java/org/oppia/android/util/data/InMemoryBlockingCache.kt
index 0229c013ea7..289a63b5324 100644
--- a/utility/src/main/java/org/oppia/android/util/data/InMemoryBlockingCache.kt
+++ b/utility/src/main/java/org/oppia/android/util/data/InMemoryBlockingCache.kt
@@ -28,10 +28,10 @@ class InMemoryBlockingCache private constructor(
*/
private var value: T? = initialValue
- private var changeObserver: suspend () -> Unit = {}
+ private var changeObserver: suspend (T?, T?) -> Unit = { _, _ -> }
/** Registers an observer that is called synchronously whenever this cache's contents are changed. */
- fun observeChanges(changeObserver: suspend () -> Unit) {
+ fun observeChanges(changeObserver: suspend (T?, T?) -> Unit) {
this.changeObserver = changeObserver
}
@@ -168,14 +168,16 @@ class InMemoryBlockingCache private constructor(
}
private suspend fun setCache(newValue: T): T {
+ val oldValue = value
value = newValue
- changeObserver()
+ changeObserver(oldValue, newValue)
return newValue
}
private suspend fun clearCache() {
+ val oldValue = value
value = null
- changeObserver()
+ changeObserver(oldValue, null)
}
/** An injectable factory for [InMemoryBlockingCache]es. */
diff --git a/utility/src/main/java/org/oppia/android/util/logging/firebase/FirebaseEventLogger.kt b/utility/src/main/java/org/oppia/android/util/logging/firebase/FirebaseEventLogger.kt
index eb285ed8864..93704c12dd6 100644
--- a/utility/src/main/java/org/oppia/android/util/logging/firebase/FirebaseEventLogger.kt
+++ b/utility/src/main/java/org/oppia/android/util/logging/firebase/FirebaseEventLogger.kt
@@ -1,7 +1,7 @@
package org.oppia.android.util.logging.firebase
import android.annotation.SuppressLint
-import android.content.Context
+import android.app.Application
import android.os.Bundle
import com.google.firebase.analytics.FirebaseAnalytics
import org.oppia.android.app.model.EventLog
@@ -65,13 +65,11 @@ class FirebaseEventLogger private constructor(
/** Application-scoped injectable factory for creating new [FirebaseEventLogger]s. */
@SuppressLint("MissingPermission") // This is a false warning probably due to the IJwB plugin.
class Factory @Inject constructor(
- private val context: Context,
+ private val application: Application,
private val networkConnectionUtil: NetworkConnectionUtil,
private val eventBundleCreator: EventBundleCreator
) {
- private val firebaseAnalytics by lazy {
- FirebaseAnalytics.getInstance(context.applicationContext)
- }
+ private val firebaseAnalytics by lazy { FirebaseAnalytics.getInstance(application) }
/**
* Returns a new [FirebaseEventLogger] for the current application context.
diff --git a/utility/src/main/java/org/oppia/android/util/parser/image/RepositoryGlideModule.kt b/utility/src/main/java/org/oppia/android/util/parser/image/RepositoryGlideModule.kt
index d2349ab3eec..bd6bcbb52e0 100644
--- a/utility/src/main/java/org/oppia/android/util/parser/image/RepositoryGlideModule.kt
+++ b/utility/src/main/java/org/oppia/android/util/parser/image/RepositoryGlideModule.kt
@@ -1,5 +1,6 @@
package org.oppia.android.util.parser.image
+import android.app.Application
import android.content.Context
import com.bumptech.glide.Glide
import com.bumptech.glide.Registry
@@ -44,7 +45,9 @@ class RepositoryGlideModule : AppGlideModule() {
registry.append(
MathModel::class.java,
ByteBuffer::class.java,
- MathBitmapModelLoader.Factory(context.applicationContext)
+ MathBitmapModelLoader.Factory(
+ context as? Application ?: context.applicationContext as Application
+ )
)
}
}
diff --git a/utility/src/main/java/org/oppia/android/util/parser/math/MathBitmapModelLoader.kt b/utility/src/main/java/org/oppia/android/util/parser/math/MathBitmapModelLoader.kt
index e53cd82e71b..73100116aea 100644
--- a/utility/src/main/java/org/oppia/android/util/parser/math/MathBitmapModelLoader.kt
+++ b/utility/src/main/java/org/oppia/android/util/parser/math/MathBitmapModelLoader.kt
@@ -1,6 +1,6 @@
package org.oppia.android.util.parser.math
-import android.content.Context
+import android.app.Application
import android.graphics.Bitmap
import android.graphics.Bitmap.Config.ARGB_8888
import android.graphics.Canvas
@@ -46,24 +46,24 @@ import kotlin.math.roundToInt
* and blocks the main thread).
*/
class MathBitmapModelLoader private constructor(
- private val applicationContext: Context
+ private val application: Application
) : ModelLoader {
// Ref: https://bumptech.github.io/glide/tut/custom-modelloader.html#writing-the-modelloader.
private val backgroundDispatcher by lazy {
- val injectorProvider = applicationContext.applicationContext as DispatcherInjectorProvider
+ val injectorProvider = application as DispatcherInjectorProvider
val injector = injectorProvider.getDispatcherInjector()
injector.getBackgroundDispatcher()
}
private val blockingDispatcher by lazy {
- val injectorProvider = applicationContext.applicationContext as DispatcherInjectorProvider
+ val injectorProvider = application as DispatcherInjectorProvider
val injector = injectorProvider.getDispatcherInjector()
injector.getBlockingDispatcher()
}
private val consoleLogger by lazy {
- val injectorProvider = applicationContext as ConsoleLoggerInjectorProvider
+ val injectorProvider = application as ConsoleLoggerInjectorProvider
val injector = injectorProvider.getConsoleLoggerInjector()
injector.getConsoleLogger()
}
@@ -77,7 +77,7 @@ class MathBitmapModelLoader private constructor(
return ModelLoader.LoadData(
model.toKeySignature(),
LatexModelDataFetcher(
- applicationContext,
+ application,
model,
width,
height,
@@ -91,7 +91,7 @@ class MathBitmapModelLoader private constructor(
override fun handles(model: MathModel): Boolean = true
private class LatexModelDataFetcher(
- private val applicationContext: Context,
+ private val application: Application,
private val model: MathModel,
private val targetWidth: Int,
private val targetHeight: Int,
@@ -109,7 +109,7 @@ class MathBitmapModelLoader private constructor(
// creation can still happen in parallel, and those are the more expensive steps.
val span = withContext(CoroutineScope(blockingDispatcher).coroutineContext) {
MathExpressionSpan(
- model.rawLatex, model.lineHeight, applicationContext.assets, !model.useInlineRendering
+ model.rawLatex, model.lineHeight, application.assets, !model.useInlineRendering
).also { it.ensureDrawable() }
}
val renderableText = SpannableStringBuilder("\uFFFC").apply {
@@ -385,10 +385,10 @@ class MathBitmapModelLoader private constructor(
/** [ModelLoaderFactory] for creating new [MathBitmapModelLoader]s. */
class Factory(
- private val applicationContext: Context
+ private val application: Application
) : ModelLoaderFactory {
override fun build(factory: MultiModelLoaderFactory): ModelLoader {
- return MathBitmapModelLoader(applicationContext)
+ return MathBitmapModelLoader(application)
}
override fun teardown() {}
diff --git a/utility/src/test/java/org/oppia/android/util/data/DataProvidersTest.kt b/utility/src/test/java/org/oppia/android/util/data/DataProvidersTest.kt
index b7b4832a180..d4697e891b7 100644
--- a/utility/src/test/java/org/oppia/android/util/data/DataProvidersTest.kt
+++ b/utility/src/test/java/org/oppia/android/util/data/DataProvidersTest.kt
@@ -74,7 +74,7 @@ private const val COMBINED_STR_VALUE_02 = "I used to be indecisive. At least I t
class DataProvidersTest {
@field:[Rule JvmField] val mockitoRule: MockitoRule = MockitoJUnit.rule()
- @Inject lateinit var context: Context
+ @Inject lateinit var application: Application
@Inject lateinit var dataProviders: DataProviders
@Inject lateinit var asyncDataSubscriptionManager: AsyncDataSubscriptionManager
@Inject lateinit var fakeExceptionLogger: FakeExceptionLogger
@@ -111,7 +111,7 @@ class DataProvidersTest {
@Test
fun testConvertToLiveData_fakeDataProvider_noObserver_doesNotCallRetrieve() {
- val fakeDataProvider = object : DataProvider(context) {
+ val fakeDataProvider = object : DataProvider(application) {
var hasRetrieveBeenCalled = false
override fun getId(): Any = "fake_data_provider"
@@ -130,7 +130,7 @@ class DataProvidersTest {
@Test
fun testConvertToLiveData_fakeDataProvider_withObserver_callsRetrieve() {
- val fakeDataProvider = object : DataProvider(context) {
+ val fakeDataProvider = object : DataProvider(application) {
var hasRetrieveBeenCalled = false
override fun getId(): Any = "fake_data_provider"
@@ -149,7 +149,7 @@ class DataProvidersTest {
@Test
fun testConvertToLiveData_trivialDataProvider_withObserver_observerReceivesValue() {
- val simpleDataProvider = object : DataProvider(context) {
+ val simpleDataProvider = object : DataProvider(application) {
override fun getId(): Any = "simple_data_provider"
override suspend fun retrieveData(): AsyncResult = AsyncResult.Success(123)
@@ -165,7 +165,7 @@ class DataProvidersTest {
@Test
fun testConvertToLiveData_dataProviderChanges_withObserver_observerReceivesUpdatedValue() {
var providerValue = 123
- val simpleDataProvider = object : DataProvider(context) {
+ val simpleDataProvider = object : DataProvider(application) {
override fun getId(): Any = "simple_data_provider"
override suspend fun retrieveData(): AsyncResult = AsyncResult.Success(providerValue)
@@ -183,7 +183,7 @@ class DataProvidersTest {
@Test
fun testConvertToLiveData_providerChanges_withoutObserver_newObserver_newObserverReceivesValue() {
var providerValue = 123
- val simpleDataProvider = object : DataProvider(context) {
+ val simpleDataProvider = object : DataProvider(application) {
override fun getId(): Any = "simple_data_provider"
override suspend fun retrieveData(): AsyncResult = AsyncResult.Success(providerValue)
@@ -203,7 +203,7 @@ class DataProvidersTest {
@Test
fun testConvertToLiveData_dataProviderNotified_sameValue_withObserver_observerNotCalledAgain() {
- val simpleDataProvider = object : DataProvider(context) {
+ val simpleDataProvider = object : DataProvider(application) {
override fun getId(): Any = "simple_data_provider"
override suspend fun retrieveData(): AsyncResult = AsyncResult.Success(123)
@@ -225,7 +225,7 @@ class DataProvidersTest {
val providerOldResult = AsyncResult.Success(123)
testCoroutineDispatchers.advanceTimeBy(10)
val providerNewResult = AsyncResult.Success(456)
- val simpleDataProvider = object : DataProvider(context) {
+ val simpleDataProvider = object : DataProvider(application) {
var callCount = 0
override fun getId(): Any = "simple_data_provider"
@@ -257,7 +257,7 @@ class DataProvidersTest {
@Test
fun testConvertToLiveData_dataProvider_providesPendingResultTwice_doesNotRedeliver() {
- val simpleDataProvider = object : DataProvider(context) {
+ val simpleDataProvider = object : DataProvider(application) {
override fun getId(): Any = "simple_data_provider"
// Return a new pending result for each call.
diff --git a/version.bzl b/version.bzl
index 51dba48bd38..06510b95a88 100644
--- a/version.bzl
+++ b/version.bzl
@@ -16,3 +16,5 @@ OPPIA_DEV_VERSION_CODE = 28
OPPIA_ALPHA_KITKAT_VERSION_CODE = 29
OPPIA_ALPHA_VERSION_CODE = 30
OPPIA_ALPHA_KENYA_VERSION_CODE = 31
+OPPIA_BETA_VERSION_CODE = 32
+OPPIA_GA_VERSION_CODE = 33
From 34f9b16a430551ed7c769ed112c4038dd40500fd Mon Sep 17 00:00:00 2001
From: Ben Henning
Date: Wed, 7 Sep 2022 23:59:51 -0700
Subject: [PATCH 35/57] Fix part of #4562: Add string consistency tool & CI
check (#4563)
## Explanation
Fixes part of #4562.
This PR introduces two new scripts:
- One for computing how many strings are not yet translated for Arabic, Brazilian Portuguese, and Swahili (as compared to the base English strings)
- One for verifying newline consistency between the English & non-English strings (based on number of lines)
The latter was also added as one of the jobs to be run during the static checks CI workflow, and is specifically useful to ensure newlines weren't inadvertently added by translators (see the updated translation strings for an idea on how often this has happened). Note that, as part of fixing these strings, the source string for lets_get_started was updated to no longer include a newline. This seems reasonable given that we should never use newlines for spacing/styling unless it's for logical splits (like paragraphs). However, I can't verify whether actual style changes are needed since this string is used as part of the unreleased app walkthrough feature. I expect that we'll re-audit the UI of that feature when we revisit it.
This PR also includes a major performance fix for RepositoryFile that will benefit all checks that use it. Kotlin's built-in file tree walker is built to implicitly follow symlinks on the filesystem. For Bazel builds, this expands the codebase to >1M files (since directory filtering happens *after* the files are known). Since scripts don't actually need to follow symlinks, the utility was updated to specifically not follow them (using Java NIO's file tree walk routine) which led to an observed ~10x performance improvement. Further optimizations could be done by building our own tree-walker and filtering directories during search (which will probably be necessary if we ever _do_ need to follow symlinks, but it probably won't be needed for a long time since the current performance is quite solid).
The former script is useful when manually auditing the translation progress using the codebase as the source of truth rather than Translatewiki. For now, it's been helpful in beta MR1 planning but longer-term it may also be useful as a badge on the repo's README.
Finally, the Kotlin stdlib dependency was updated to point to jdk8 instead of jdk7 (since a specific feature was needed from the former, and the codebase can rely on higher Java SDK versions than 7 given that the minimum Java version is 1.8).
## Essential Checklist
- [x] The PR title and explanation each start with "Fix #bugnum: " (If this PR fixes part of an issue, prefix the title with "Fix part of #bugnum: ...".)
- [x] Any changes to [scripts/assets](https://github.com/oppia/oppia-android/tree/develop/scripts/assets) files have their rationale included in the PR explanation.
- [x] The PR follows the [style guide](https://github.com/oppia/oppia-android/wiki/Coding-style-guide).
- [x] The PR does not contain any unnecessary code changes from Android Studio ([reference](https://github.com/oppia/oppia-android/wiki/Guidance-on-submitting-a-PR#undo-unnecessary-changes)).
- [x] The PR is made from a branch that's **not** called "develop" and is up-to-date with "develop".
- [x] The PR is **assigned** to the appropriate reviewers ([reference](https://github.com/oppia/oppia-android/wiki/Guidance-on-submitting-a-PR#clarification-regarding-assignees-and-reviewers-section)).
## For UI-specific PRs only
N/A -- this is a developer infrastructure-only PR, except for all of the string newline fixes (which just result in a more correct UI for non-English), and the changed English string (which is inaccessible to demonstrate). Screenshots could be uploaded, but the newlines need to be removed regardless so it doesn't seem specifically useful here (plus those languages may not be obvious to verify for reviewers).
Commits:
* Create dedicated alpha application component.
This simplifies application component management significantly and
allows individual build flavors to have their own unique module lists.
* Add beta & GA update notices.
This also introduces dedicated beta & GA build flavors which is a
necessary prerequisite.
It also introduces an extra beta, alpha, and dev mode labels for the splash
screen (the latter 2 were extra) with 2 second minimum wait timers for
beta and alpha to ensure they are seen. A 5-second safety timer was
added to ensure the splash screen can always be passed even if something
goes wrong at the domain level (since there are now quite a few moving
pieces to determine the user's current onboarding state).
* Add build tests for the new beta & GA flavors.
* Fix broken test per earlier changes.
* Fix general broken tests & builds.
Tests broken due to changes to the app startup experience haven't yet
been fixed.
* Lint fixes.
* First part of adding tests for GA notices.
There's a bunch left to do here, this is mainly needed so that I can
transfer changes to a different machine.
* Update TransformAndroidManifestTest.kt
Correct typos.
* Fix tests & static checks.
This also removes temporary debug code and TODOs, and finishes the tests
for SplashActivity.
* Post-merge fixes.
* Test fixes.
* Fix Gradle test.
* Add some string resource checks/tools.
Also, fixes major performance issue with all file-based CI checks.
* Ensure newline consistency in translated strings.
Also, fix reporting in new validation check script.
* Add tests & fix static checks.
* Follow-up adjustments after self-review.
---
.github/workflows/static_checks.yml | 5 +
app/src/main/res/values-ar/strings.xml | 10 +-
app/src/main/res/values-sw/strings.xml | 238 +++++++--------
app/src/main/res/values/strings.xml | 2 +-
scripts/BUILD.bazel | 14 +
.../oppia/android/scripts/common/BUILD.bazel | 3 +
.../android/scripts/common/RepositoryFile.kt | 8 +-
.../org/oppia/android/scripts/xml/BUILD.bazel | 32 +-
.../xml/StringLanguageTranslationCheck.kt | 45 +++
.../scripts/xml/StringResourceParser.kt | 109 +++++++
.../xml/StringResourceValidationCheck.kt | 76 +++++
.../org/oppia/android/scripts/xml/BUILD.bazel | 35 ++-
.../xml/StringLanguageTranslationCheckTest.kt | 270 +++++++++++++++++
.../scripts/xml/StringResourceParserTest.kt | 279 ++++++++++++++++++
.../xml/StringResourceValidationCheckTest.kt | 259 ++++++++++++++++
third_party/maven_install.json | 12 +-
third_party/versions.bzl | 2 +-
17 files changed, 1266 insertions(+), 133 deletions(-)
create mode 100644 scripts/src/java/org/oppia/android/scripts/xml/StringLanguageTranslationCheck.kt
create mode 100644 scripts/src/java/org/oppia/android/scripts/xml/StringResourceParser.kt
create mode 100644 scripts/src/java/org/oppia/android/scripts/xml/StringResourceValidationCheck.kt
create mode 100644 scripts/src/javatests/org/oppia/android/scripts/xml/StringLanguageTranslationCheckTest.kt
create mode 100644 scripts/src/javatests/org/oppia/android/scripts/xml/StringResourceParserTest.kt
create mode 100644 scripts/src/javatests/org/oppia/android/scripts/xml/StringResourceValidationCheckTest.kt
diff --git a/.github/workflows/static_checks.yml b/.github/workflows/static_checks.yml
index ff531ffbebb..f9dfbaa86fb 100644
--- a/.github/workflows/static_checks.yml
+++ b/.github/workflows/static_checks.yml
@@ -180,6 +180,11 @@ jobs:
gh issue list --limit 2000 --repo oppia/oppia-android --json number > $(pwd)/open_issues.json
bazel run //scripts:todo_open_check -- $(pwd) scripts/assets/todo_open_exemptions.pb open_issues.json
+ - name: String Resource Validation Check
+ if: always()
+ run: |
+ bazel run //scripts:string_resource_validation_check -- $(pwd)
+
# Note that caching is intentionally not enabled for this check since licenses should always be
# verified without any potential influence from earlier builds (i.e. always from a clean build to
# ensure the results exactly match the current state of the repository).
diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml
index 087958c60f5..fc9d006d5ea 100644
--- a/app/src/main/res/values-ar/strings.xml
+++ b/app/src/main/res/values-ar/strings.xml
@@ -443,13 +443,13 @@
لماذا لا يتم تشغيل الصوت الخاص بي؟كيف يمكنني تنزيل موضوع؟لا أجد سؤالي هنا. ماذا الان؟
- <p>إذا كانت هذه هي المرة الأولى التي تنشئ فيها ملفًا شخصيًا وليس لديك رقم تعريف شخصي: </p> \n<p> 1. من منتقي الملف الشخصي ، اضغط على\n<strong> قم بإعداد ملفات تعريف متعددة</strong>\n</p>\n<p> 2. قم بإنشاء رقم تعريف شخصي و\n<strong>احفظ</strong>\n</p> \n<p> 3. املأ جميع البيانات للملف الشخصي.</p> \n<ol> \n<li>(اختياري) قم بتحميل صورة.</li> \n<li>إدخال اسم.</li> \n<li>(اختياري) قم بتعيين رقم تعريف شخصي مكون من 3 أرقام.</li> \n</ol> \n<p> 4. اضغط\n<strong>إنشاء</strong> . تمت إضافة هذا الملف الشخصي إلى منتقي ملف التعريف الخاص بك!\n<br/> \n<br/> إذا قمت بإنشاء ملف تعريف من قبل ولديك رقم تعريف شخصي:\n</p>\n<p> 1. من منتقي الملف الشخصي ، اضغط على\n<strong>إضافة الملف الشخصي</strong>\n</p> \n<p> 2. أدخل رقم التعريف الشخصي الخاص بك وانقر فوق\n<strong>إرسال</strong>\n</p> \n<p>3. املأ جميع الحقول للملف الشخصي.</p> \n<ol> \n<li>(اختياري) قم بتحميل صورة.</li> \n<li>إدخال اسم.</li> \n<li>(اختياري) قم بتعيين رقم تعريف شخصي مكون من 3 أرقام.</li> \n</ol> \n<p> 4. اضغط\n<strong>إنشاء</strong> . تمت إضافة هذا الملف الشخصي إلى منتقي ملف التعريف الخاص بك!\n<br/><br/> ملاحظة: فقط ال\n<u>مدير</u> قادر على إدارة الملفات الشخصية.\n</p>
- <p>بمجرد حذف ملف التعريف:</p>\n<p><br></p> \n<p>\n<li>لا يمكن استعادة ملف التعريف.</li>\n</p>\n<p><li>سيتم حذف معلومات الملف الشخصي مثل الاسم والصور والتقدم بشكل دائم.</li></p>\n<p><br></p>\n<p>لحذف ملف تعريف (باستثناء<u>المسؤول</u></p>\n<p>1. من الصفحة الرئيسية للمسؤول ، اضغط على زر القائمة أعلى اليسار.</p>\n<p>2. اضغط على<strong>ضوابط المسؤول</strong></p>\n<p>3. اضغط على<strong>تحرير ملفات التعريف</strong></p>\n<p>4. اضغط على الملف الشخصي الذي ترغب في حذفه.</p>\n<p>5. في الجزء السفلي من الشاشة ، انقر فوق<strong>حذف الملف الشخصي</strong></p>\n<p>6. اضغط<strong>حذف</strong>لتأكيد الحذف.</p>\n<p><br></p>\n<p>ملاحظة:<u>المسؤول</u>فقط هو القادر على إدارة الملفات الشخصية.</p>
+ <p>إذا كانت هذه هي المرة الأولى التي تنشئ فيها ملفًا شخصيًا وليس لديك رقم تعريف شخصي: </p> <p> 1. من منتقي الملف الشخصي ، اضغط على<strong> قم بإعداد ملفات تعريف متعددة</strong></p><p> 2. قم بإنشاء رقم تعريف شخصي و<strong>احفظ</strong></p> <p> 3. املأ جميع البيانات للملف الشخصي.</p> <ol> <li>(اختياري) قم بتحميل صورة.</li> <li>إدخال اسم.</li> <li>(اختياري) قم بتعيين رقم تعريف شخصي مكون من 3 أرقام.</li> </ol> <p> 4. اضغط<strong>إنشاء</strong> . تمت إضافة هذا الملف الشخصي إلى منتقي ملف التعريف الخاص بك!<br/> <br/> إذا قمت بإنشاء ملف تعريف من قبل ولديك رقم تعريف شخصي:</p><p> 1. من منتقي الملف الشخصي ، اضغط على<strong>إضافة الملف الشخصي</strong></p> <p> 2. أدخل رقم التعريف الشخصي الخاص بك وانقر فوق<strong>إرسال</strong></p> <p>3. املأ جميع الحقول للملف الشخصي.</p> <ol> <li>(اختياري) قم بتحميل صورة.</li> <li>إدخال اسم.</li> <li>(اختياري) قم بتعيين رقم تعريف شخصي مكون من 3 أرقام.</li> </ol> <p> 4. اضغط<strong>إنشاء</strong> . تمت إضافة هذا الملف الشخصي إلى منتقي ملف التعريف الخاص بك!<br/><br/> ملاحظة: فقط ال<u>مدير</u> قادر على إدارة الملفات الشخصية.</p>
+ <p>بمجرد حذف ملف التعريف:</p><p><br></p> <p><li>لا يمكن استعادة ملف التعريف.</li></p><p><li>سيتم حذف معلومات الملف الشخصي مثل الاسم والصور والتقدم بشكل دائم.</li></p><p><br></p><p>لحذف ملف تعريف (باستثناء<u>المسؤول</u></p><p>1. من الصفحة الرئيسية للمسؤول ، اضغط على زر القائمة أعلى اليسار.</p><p>2. اضغط على<strong>ضوابط المسؤول</strong></p><p>3. اضغط على<strong>تحرير ملفات التعريف</strong></p><p>4. اضغط على الملف الشخصي الذي ترغب في حذفه.</p><p>5. في الجزء السفلي من الشاشة ، انقر فوق<strong>حذف الملف الشخصي</strong></p><p>6. اضغط<strong>حذف</strong>لتأكيد الحذف.</p><p><br></p><p>ملاحظة:<u>المسؤول</u>فقط هو القادر على إدارة الملفات الشخصية.</p><p>لتغيير بريدك الإلكتروني / رقم هاتفك:</p> <p>1. من الصفحة الرئيسية للمشرف ، اضغط على زر القائمة أعلى اليسار.</p> <p>2. اضغط على <strong> عناصر تحكم المسؤول </ strong>.</p> <p>3. اضغط على <strong> تعديل الحساب </ strong>.</p> <p><br></p> <p>إذا كنت تريد تغيير بريدك الإلكتروني:</p> <p>4. أدخل بريدك الإلكتروني الجديد وانقر على <strong> حفظ </ strong>.</p> <p>5. يتم إرسال رابط التأكيد لتأكيد بريدك الإلكتروني الجديد. ستنتهي صلاحية الرابط بعد 24 ساعة ويجب النقر عليه لربطه بحسابك.</p> <p><br></p> <p>في حالة تغيير رقم هاتفك: </ p> <p> 4. أدخل رقم هاتفك الجديد وانقر على <strong> تحقق </ strong>.</p> <p>5. يتم إرسال رمز لتأكيد رقمك الجديد. ستنتهي صلاحية الرمز بعد 5 دقائق ويجب إدخاله في الشاشة الجديدة لربطه بحسابك.</p>
- <p>%1$s \n<i>\"أو-بي-يا\"</i>(فنلندية) - \"للتعلم\"</p>\n<p><br></p><p>%1$sمهمتنا هي مساعدة أي شخص على تعلم أي شيء يريده بطريقة فعالة وممتعة.</p><p><br></p><p>من خلال إنشاء مجموعة من الدروس المجانية عالية الجودة والفعالة بشكل واضح بمساعدة معلمين من جميع أنحاء العالم ، تهدف %1$s إلى تزويد الطلاب بتعليم جيد - بغض النظر عن مكان وجودهم أو الموارد التقليدية التي يمكنهم الوصول إليها.</p><p><br></p><p>كطالب ، يمكنك أن تبدأ مغامرتك التعليمية من خلال تصفح الموضوعات المدرجة في الصفحة الرئيسية!</p>
+ <p>%1$s <i>\"أو-بي-يا\"</i>(فنلندية) - \"للتعلم\"</p><p><br></p><p>%1$sمهمتنا هي مساعدة أي شخص على تعلم أي شيء يريده بطريقة فعالة وممتعة.</p><p><br></p><p>من خلال إنشاء مجموعة من الدروس المجانية عالية الجودة والفعالة بشكل واضح بمساعدة معلمين من جميع أنحاء العالم ، تهدف %1$s إلى تزويد الطلاب بتعليم جيد - بغض النظر عن مكان وجودهم أو الموارد التقليدية التي يمكنهم الوصول إليها.</p><p><br></p><p>كطالب ، يمكنك أن تبدأ مغامرتك التعليمية من خلال تصفح الموضوعات المدرجة في الصفحة الرئيسية!</p><p>المشرف هو المستخدم الرئيسي الذي يدير ملفات التعريف والإعدادات لكل ملف تعريف على حسابه. هم على الأرجح والدك أو معلمك أو وصي عليك الذي أنشأ هذا الملف الشخصي لك.</p><p><br></p><p>يمكن للمسؤولين إدارة الملفات الشخصية وتعيين أرقام التعريف الشخصية وتغيير الإعدادات الأخرى ضمن حساباتهم. بناءً على ملف التعريف الخاص بك ، قد تكون أذونات المسؤول مطلوبة لبعض الميزات مثل تنزيل الموضوعات وتغيير رقم التعريف الشخصي وغير ذلك.</p><p><br></p><p>لمعرفة من هو المسؤول لديك ، انتقل إلى منتقي الملف الشخصي. الملف الشخصي الأول المدرج ولديه \"المسؤول\" مكتوب باسمه هو المسؤول.</p><p>إذا لم يتم تحميل مشغل الاستكشاف</p><p><br></p><p>تحقق لمعرفة ما إذا كان التطبيق محدثًا أم لا:</p><p> <ol> <li> انتقل إلى متجر Play وتأكد من تحديث التطبيق إلى أحدث إصدار </li> </ol> </p><p><br></p><p>تحقق من اتصالك بالإنترنت:</p><p> <li> إذا كان اتصالك بالإنترنت بطيئًا ، فحاول إعادة الاتصال بشبكة Wi-Fi أو الاتصال بشبكة أخرى. </li> </p><p><br></p><p>اطلب من المشرف التحقق من أجهزتهم واتصال الإنترنت:</p><p> <li> اطلب من المشرف استكشاف الأخطاء وإصلاحها باستخدام الخطوات المذكورة أعلاه </li> </p><p><br></p><p>أخبرنا إذا كنت لا تزال تواجه مشكلات في التحميل:</p><p> <li> أبلغ عن مشكلة عن طريق الاتصال بنا على admin@oppia.org. </li> </p>
- <p>إذا لم يتم تشغيل الصوت الخاص بك</p><p><br></p>\n<p>تحقق لمعرفة ما إذا كان التطبيق محدثًا أم لا:</p>\n<p> <li>انتقل إلى متجر Play وتأكد من تحديث التطبيق إلى أحدث إصدار</li> </p><p><br></p>\n<p>تحقق من اتصالك بالإنترنت:</p><p> <li>إذا كان اتصالك بالإنترنت بطيئًا ، فحاول إعادة الاتصال بشبكة Wi-Fi أو الاتصال بشبكة أخرى. قد يتسبب الإنترنت البطيء في تحميل الصوت بشكل غير منتظم ، مما يجعل من الصعب تشغيله.</li> </p><p><br></p>\n<p>اطلب من المسؤول التحقق من أجهزتهم واتصال الإنترنت:</p><p> \n<li>اطلب من المسؤول استكشاف الأخطاء وإصلاحها باستخدام الخطوات المذكورة أعلاه</li> </p><p><br></p>\n<p>أخبرنا إذا كنت لا تزال تواجه مشكلات في التحميل:</p><p> <li>أبلغ عن مشكلة عن طريق الاتصال بنا على admin@oppia.org.</li></p>
- <p>لتنزيل استكشاف:</p>\n<p>1. من الصفحة الرئيسية ، انقر فوق موضوع أو استكشاف.</p>\n<p>2. من صفحة الموضوع هذه ، انقر على علامة التبويب <strong> معلومات </ strong>.</p>\n<p>3. اضغط على <strong> تنزيل الموضوع </ strong>.</p>\n<p>4. اعتمادًا على إعدادات التطبيق ، قد تحتاج إلى موافقة المسؤول أو اتصال Wifi ثابتًا لإكمال التنزيل. إذا لزم الأمر ، بمجرد استيفاء هذه المتطلبات ، يتم تنزيل الموضوع على الجهاز ويمكن استخدامه في وضع عدم الاتصال بواسطة جميع ملفات التعريف. <p>
+ <p>إذا لم يتم تشغيل الصوت الخاص بك</p><p><br></p><p>تحقق لمعرفة ما إذا كان التطبيق محدثًا أم لا:</p><p> <li>انتقل إلى متجر Play وتأكد من تحديث التطبيق إلى أحدث إصدار</li> </p><p><br></p><p>تحقق من اتصالك بالإنترنت:</p><p> <li>إذا كان اتصالك بالإنترنت بطيئًا ، فحاول إعادة الاتصال بشبكة Wi-Fi أو الاتصال بشبكة أخرى. قد يتسبب الإنترنت البطيء في تحميل الصوت بشكل غير منتظم ، مما يجعل من الصعب تشغيله.</li> </p><p><br></p><p>اطلب من المسؤول التحقق من أجهزتهم واتصال الإنترنت:</p><p> <li>اطلب من المسؤول استكشاف الأخطاء وإصلاحها باستخدام الخطوات المذكورة أعلاه</li> </p><p><br></p><p>أخبرنا إذا كنت لا تزال تواجه مشكلات في التحميل:</p><p> <li>أبلغ عن مشكلة عن طريق الاتصال بنا على admin@oppia.org.</li></p>
+ <p>لتنزيل استكشاف:</p><p>1. من الصفحة الرئيسية ، انقر فوق موضوع أو استكشاف.</p><p>2. من صفحة الموضوع هذه ، انقر على علامة التبويب <strong> معلومات </ strong>.</p><p>3. اضغط على <strong> تنزيل الموضوع </ strong>.</p><p>4. اعتمادًا على إعدادات التطبيق ، قد تحتاج إلى موافقة المسؤول أو اتصال Wifi ثابتًا لإكمال التنزيل. إذا لزم الأمر ، بمجرد استيفاء هذه المتطلبات ، يتم تنزيل الموضوع على الجهاز ويمكن استخدامه في وضع عدم الاتصال بواسطة جميع ملفات التعريف. <p><p> إذا لم تتمكن من العثور على سؤالك أو كنت ترغب في الإبلاغ عن خطأ ، فاتصل بنا على admin@oppia.org. </p>
diff --git a/app/src/main/res/values-sw/strings.xml b/app/src/main/res/values-sw/strings.xml
index e258e430b69..140af141b6b 100644
--- a/app/src/main/res/values-sw/strings.xml
+++ b/app/src/main/res/values-sw/strings.xml
@@ -109,15 +109,15 @@
Samahani,vipeo vingi havitumiki na programu.Tafadhali rekebisha jibu lako.Samahani, nguvu za juu zaidi ya 5 haiungwi mkono na programu. Tafadhali rekebisha jibu lako.Samahani, nguvu zinazorudiwa/vielezo hazihimiliwi na programu. Tafadhali punguza jibu lako kwa nguvu moja.
- \nPembejeo haipo kwa mzizi wa mraba.
- \nKugawanya kwa sufuri si halali. Tafadhali rekebisha jibu lako.
+ Pembejeo haipo kwa mzizi wa mraba.
+ Kugawanya kwa sufuri si halali. Tafadhali rekebisha jibu lako.Inaonekana umeingiza baadhi ya vigezo. Tafadhali hakikisha kuwa jibu lako lina nambari pekee na uondoe vigezo vyovyote kutoka kwa jibu lako.
- \nTafadhali tumia vigezo vilivyobainishwa katika swali na si %s.
+ Tafadhali tumia vigezo vilivyobainishwa katika swali na si %s.Mlinganyo yako inakosa ishara \'=\'.
- \nMlinganyo wako una ishara nyingi sana \'=\'. Inapaswa kuwa na moja tu.
- \nMoja ya pande za \'=\' katika mlinganyo wako ni tupu.
- \nChaguo la kukokotoa \'%s\' haitumiki. Tafadhali rekebisha jibu lako.
- \nUlimaanisha sqrt? Ikiwa sivyo, tafadhali tenganisha vigeu kwa kutumia alama za kuzidisha.
+ Mlinganyo wako una ishara nyingi sana \'=\'. Inapaswa kuwa na moja tu.
+ Moja ya pande za \'=\' katika mlinganyo wako ni tupu.
+ Chaguo la kukokotoa \'%s\' haitumiki. Tafadhali rekebisha jibu lako.
+ Ulimaanisha sqrt? Ikiwa sivyo, tafadhali tenganisha vigeu kwa kutumia alama za kuzidisha.Samahani, hatukuweza kuelewa jibu lako. Tafadhali iangalie ili kuhakikisha kuwa hakuna hitilafu zozote.Washa sauti kwa somo hili.Hadithi Zilizochezwa hivi karibuni
@@ -157,21 +157,21 @@
Jibu lako lina koloni mbili (:) karibu na kila moja.Idadi ya masharti si sawa na masharti yanayohitajika.Uwiano hauwezi kuwa na 0 kama kipengele.
- \nUkubwa usiojulikana
- \n Baiti %s
+ Ukubwa usiojulikana
+ Baiti %s%s KB%s MB%s GB
- \nSahihi!
- \nMada: %s
- \n%1$s katika %2$s
+ Sahihi!
+ Mada: %s
+ %1$s katika %2$sSura 1\n
- \n\n Sura %s \n
+ \n Sura %s \n Hadithi 1\n
- \n Hadithi %s\n
+ Hadithi %s\n %s kati ya Sura %s Imekamilika
@@ -179,104 +179,104 @@
Somo 1\n
- \n Masomo %s \n
+ Masomo %s \n
- \nUkurasa wa kuchagua wasifu
- \nMsimamizi
- \nChagua wasifu wako
- \nOngeza Wasifu
+ Ukurasa wa kuchagua wasifu
+ Msimamizi
+ Chagua wasifu wako
+ Ongeza WasifuWeka Wasifu Nyingi
- \nOngeza hadi watumiaji 10 kwenye akaunti yako. Nzuri sana kwa familia na madarasa.
- \nUdhibiti vya Msimamizi
+ Ongeza hadi watumiaji 10 kwenye akaunti yako. Nzuri sana kwa familia na madarasa.
+ Udhibiti vya MsimamiziLughaVidhibiti vya Msimamizi
- \nIdhinisha kuongeza wasifu
+ Idhinisha kuongeza wasifuIdhinisha kufikia Vidhibiti vya Msimamizi
- \nIdhini ya Msimamizi Inahitajika
+ Idhini ya Msimamizi InahitajikaWeka Nambari ya Siri ya Msimamizi ili kuunda akaunti mpya.Weka Nambari ya Siri ya Msimamizi ili kufikia Vidhibiti vya Msimamizi.
- \nNambari ya Siri ya Msimamizi
+ Nambari ya Siri ya MsimamiziNambari ya Siri ya Msimamizi si Sahihi. Tafadhali jaribu tena.
- \nTafadhali weka Nambari ya Siri ya Msimamizi.
- \nWasilisha
+ Tafadhali weka Nambari ya Siri ya Msimamizi.
+ WasilishaFunga
- \nKabla ya kuongeza wasifu, tunahitaji kulinda akaunti yako kwa kuunda Nambari ya Siri. Hii hukupa uwezo wa kuidhinisha upakuaji na kudhibiti wasifu kwenye kifaa.
- \nTumia Nambari yako ya siri uliyoweka kwa akaunti za kibinafsi kama vile benki au usalama wa kijamii.
- \nNambari mpya ya Siri ya tarakimu 5
+ Kabla ya kuongeza wasifu, tunahitaji kulinda akaunti yako kwa kuunda Nambari ya Siri. Hii hukupa uwezo wa kuidhinisha upakuaji na kudhibiti wasifu kwenye kifaa.
+ Tumia Nambari yako ya siri uliyoweka kwa akaunti za kibinafsi kama vile benki au usalama wa kijamii.
+ Nambari mpya ya Siri ya tarakimu 5Thibitisha Nambari ya Siri ya tarakimu 5
- \nNambari yako ya Siri inapaswa kuwa na urefu wa tarakimu 5.
- \nTafadhali hakikisha kwamba Nambari za Siri zote mbili zinalingana.
+ Nambari yako ya Siri inapaswa kuwa na urefu wa tarakimu 5.
+ Tafadhali hakikisha kwamba Nambari za Siri zote mbili zinalingana.Hifadhi
- \nIdhinisha kuongeza wasifu
- \nOngeza Wasifu
- \nOngeza Wasifu
+ Idhinisha kuongeza wasifu
+ Ongeza Wasifu
+ Ongeza WasifuJina*
- \nNambari ya Siri ya tarakimu 3*
+ Nambari ya Siri ya tarakimu 3*Thibitisha Nambari ya Siri ya tarakimu 3*
- \nRuhusu Upakuaji wa Ufikiaji
- \nMtumiaji anaweza kupakua na kufuta maudhui bila Nambari ya Siri ya Msimamizi.
+ Ruhusu Upakuaji wa Ufikiaji
+ Mtumiaji anaweza kupakua na kufuta maudhui bila Nambari ya Siri ya Msimamizi.AnzishaFunga
- \nUkiwa na Nambari ya Siri, hakuna mtu mwingine anayeweza kufikia wasifu kando na mtumiaji huyu aliyekabidhiwa.
- \nTumeshindwa kuhifadhi picha yako. Tafadhali jaribu tena.
+ Ukiwa na Nambari ya Siri, hakuna mtu mwingine anayeweza kufikia wasifu kando na mtumiaji huyu aliyekabidhiwa.
+ Tumeshindwa kuhifadhi picha yako. Tafadhali jaribu tena.Jina hili tayari linatumiwa na wasifu mwingine.Tafadhali weka jina la wasifu huu.
- \nMajina yanaweza kuwa na herufi pekee. Jaribu jina lingine?
- \nNambari yako ya Siri inapaswa kuwa na urefu wa tarakimu 3.
- \nTafadhali hakikisha kwamba Nambari za Siri zote mbili zinalingana.
- \nMaelezo zaidi kuhusu Nambari za Siri zenye tarakimu 3.
- \nSehemu zilizo na alama ya * zinahitajika.
+ Majina yanaweza kuwa na herufi pekee. Jaribu jina lingine?
+ Nambari yako ya Siri inapaswa kuwa na urefu wa tarakimu 3.
+ Tafadhali hakikisha kwamba Nambari za Siri zote mbili zinalingana.
+ Maelezo zaidi kuhusu Nambari za Siri zenye tarakimu 3.
+ Sehemu zilizo na alama ya * zinahitajika.Picha ya sasa ya wasifu
- \nHariri picha ya wasifu
- \nKaribu kwa %s!
+ Hariri picha ya wasifu
+ Karibu kwa %s!Jifunze chochote unachotaka kwa njia bora na ya kufurahisha.Ongeza watumiaji kwenye akaunti yako.Elezea uzoefu na uunde hadi wasifu 10.
- \nPakua ya nje ya mtandao.
+ Pakua ya nje ya mtandao.Endelea kujifunza masomo yako bila muunganisho wa mtandao.
- \nFurahia!
+ Furahia!Furahia matukio yako ya kujifunza kwa masomo yetu ya bure na ya ufanisi.RukaInayofuataAnza
- \nSlaidi %s ya %s
- \nHabari, %s!
+ Slaidi %s ya %s
+ Habari, %s!Tafadhali weka Nambari yako ya Siri ya Msimamizi.
- \nTafadhali weka Nambari yako ya Siri.
- \nNambari ya Siri ya Tarakimu 5 ya Msimamizi.
- \nNambari ya Siri ya Tarakimu 3 ya Mtumiaji.
+ Tafadhali weka Nambari yako ya Siri.
+ Nambari ya Siri ya Tarakimu 5 ya Msimamizi.
+ Nambari ya Siri ya Tarakimu 3 ya Mtumiaji.Nilisahau nambari yangu.Nambari ya Siri si sahihi.OnyeshafichaFunga
- \nMabadiliko ya Nambari ya Siri yamefaulu
+ Mabadiliko ya Nambari ya Siri yamefauluJe, umesahau Nambari ya Siri?Ili kuweka upya Nambari yako ya Siri, tafadhali ondoa %s kisha uisakinishe upya.\n\nKumbuka kwamba ikiwa kifaa hakijakuwa mtandaoni, unaweza kupoteza maendeleo ya mtumiaji kwenye akaunti nyingi.Nenda kwenye hifadhi ya Google play.
- \nOnyesha/Ficha ishara ya nenosiri
- \nIshara ya nenosiri iliyoonyeshwa
- \nIshara ya nenosiri iliyofichwa
- \nWeka Nambari yako ya Siri
- \nWeka Nambari ya Siri
+ Onyesha/Ficha ishara ya nenosiri
+ Ishara ya nenosiri iliyoonyeshwa
+ Ishara ya nenosiri iliyofichwa
+ Weka Nambari yako ya Siri
+ Weka Nambari ya SiriNambari ya Siri ya MsimamiziUfikiaji wa mipangilio ya msimamizi
- \nNambari ya Siri ya Msimamizi inahitajika ili kubadilisha Nambari ya Siri ya mtumiaji
+ Nambari ya Siri ya Msimamizi inahitajika ili kubadilisha Nambari ya Siri ya mtumiajiGhairiWasilishaNambari ya Siri ya msimamizi si Sahihi. Tafadhali jaribu tena.
- \nNambari ya Siri mpya ya %1$s.
- \nWeka Nambari mpya ya Siri
- \nVipakuliwa Vyangu
- \nVipakuliwa
+ Nambari ya Siri mpya ya %1$s.
+ Weka Nambari mpya ya Siri
+ Vipakuliwa Vyangu
+ VipakuliwaSasisho (2)Je, ungependa kuondoka kwenye wasifu wako?GhairiTokaMwanzo
- \nWasifu
+ WasifuIlitengenezwa kwa %s
- \nMara ya mwisho kutumika
+ Mara ya mwisho kutumikaBadilisha jinaWeka upya Nambari ya SiriUfutaji wa Wasifu
@@ -284,8 +284,8 @@
Maendeleo yote yatafutwa na hayawezi kurejeshwa.FutaGhairi
- \nRuhusu Ufikiaji wa Upakuaji
- \nMtumiaji anaweza kupakua na kufuta maudhui bila Nambari ya Siri ya msimamizi.
+ Ruhusu Ufikiaji wa Upakuaji
+ Mtumiaji anaweza kupakua na kufuta maudhui bila Nambari ya Siri ya msimamizi.Picha ya WasifuPicha ya WasifuGhairi
@@ -296,51 +296,51 @@
HifadhiWeka upya Nambari ya SiriWeka Nambari mpya ya Siri ili mtumiaji aiweke anapofikia wasifu wake.
- \nNambari ya Siri ya tarakimu 3*
- \nNambari ya Siri ya tarakimu 5*
+ Nambari ya Siri ya tarakimu 3*
+ Nambari ya Siri ya tarakimu 5*Thibitisha Nambari ya Siri ya tarakimu 3*Thibitisha Nambari ya Siri ya tarakimu 5
- \nNambari yako ya Siri inapaswa kuwa na urefu wa tarakimu 3.
- \nNambari yako ya Siri inapaswa kuwa na urefu wa tarakimu 5.
+ Nambari yako ya Siri inapaswa kuwa na urefu wa tarakimu 3.
+ Nambari yako ya Siri inapaswa kuwa na urefu wa tarakimu 5.Unda Nambari ya Siri ya tarakimu 3
- \nInahitajika
- \nKitufe cha Nyuma
+ Inahitajika
+ Kitufe cha NyumaInayofuataJumla
- \nHariri akaunti
- \nUsimamizi wa Wasifu
+ Hariri akaunti
+ Usimamizi wa WasifuHariri wasifu
- \nRuhusa ya kupakua
+ Ruhusa ya kupakuaPakua na usasishe kwenye Wi-fi pekeeMada zitapakuliwa na kusasishwa kwenye Wi-fi pekee. Vipakuliwa au masasisho yoyote ya data ya mtandao wa simu yatawekwa kwenye foleni.Sasisha mada moja kwa moja
- \nMada zilizopakuliwa ambazo zina maudhui mapya zinazopatikana zitasasishwa moja kwa moja.
+ Mada zilizopakuliwa ambazo zina maudhui mapya zinazopatikana zitasasishwa moja kwa moja.Maelezo ya programu.Toleo la Programu
- \nVitendo vya akaunti
+ Vitendo vya akauntiTokaGhairiSawaJe,una uhakika unataka kutoka kwenye wasifu wako?
- \nToleo la Programu %s
+ Toleo la Programu %sSasisho la mwisho lilisakinishwa kwenye %s. Tumia nambari ya toleo iliyo hapo juu kutuma maoni kuhusu hitilafu.Toleo la ProgramuLugha ya ProgramuLugha chaguomsingi ya SautiUkubwa wa Maandishi ya KusomaUkubwa wa Maandishi ya Kusoma
- \nNakala ya hadithi itaonekana hivi.
+ Nakala ya hadithi itaonekana hivi.A
- \nSauti Chaguomsingi
+ Sauti ChaguomsingiLugha ya ProgramuUkubwa wa Maandishi ya KusomaNdogoKatiKubwa
- \nKubwa Zaidi
- \nTelezesha upau wa utafutaji ili kudhibiti ukubwa wa maandishi.
- \nWasifu
- \nHadithi 2
+ Kubwa Zaidi
+ Telezesha upau wa utafutaji ili kudhibiti ukubwa wa maandishi.
+ Wasifu
+ Hadithi 2Mada zinazoendeleaMada zinazoendeleaHadithi Zimekamilika
@@ -348,39 +348,39 @@
ChaguziHadithi ZimekamilikaMwongozo wa programu
- \nJifunze ujuzi mpya wa hesabu katika hadithi zinazokuonyesha jinsi ya kuzitumia katika maisha yako ya kila siku
- \n\"Karibu %s!\"
+ Jifunze ujuzi mpya wa hesabu katika hadithi zinazokuonyesha jinsi ya kuzitumia katika maisha yako ya kila siku
+ \"Karibu %s!\"Unataka kujifunza nini?
- \nMakuu
- Hebu \ntuanze.
+ Makuu
+ Hebu tuanze.Ndiyo
- \nHapana…
- \nChagua \nmada tofauti.
+ Hapana…
+ Chagua \nmada tofauti.Je, unavutiwa na:\n%s?Kidokezo kipya kinapatikana
- \nOnyesha vidokezo na suluhisho
+ Onyesha vidokezo na suluhishoNenda juuVidokezoFichua Suluhisho
- \nFichua Kidokezo
+ Fichua KidokezoOnyesha/Ficha orodha ya vidokezo ya %s
- \nOnyesha/Ficha suluhisho
+ Onyesha/Ficha suluhishoSuluhisho pekee ni:Hii itafichua suluhisho. Una uhakika?Fichuasasa hivi
- \nhivi karibuni
+ hivi karibuni%s iliyopita
- \njana
+ janaRudi kwenye madaUfafanuzi:
- \nIkiwa vitu viwili ni sawa, viunganishe.
+ Ikiwa vitu viwili ni sawa, viunganishe.Unganisha na kipengee %sTenganisha vipengee katika %sHamisha kipengee chini hadi %s
- \nHamisha kipengee juu hadi %s
+ Hamisha kipengee juu hadi %sJuu
- \nChini
+ Chini%s %sdakika
@@ -395,16 +395,16 @@
siku %smada_marudio_mtazamo wa kuchakata tena_tag
- \nInaendelea_kuchakata tena_mtazamo_tag
- \nTafadhali chagua angalau chaguo moja.
- \nToleo la programu lisilotumika
+ Inaendelea_kuchakata tena_mtazamo_tag
+ Tafadhali chagua angalau chaguo moja.
+ Toleo la programu lisilotumikaToleo hili la programu halitumiki tena. Tafadhali isasishe kupitia hifadhi ya michezo.Funga programu
- \nkwa
- \nWeka uwiano katika fomu x:y.
+ kwa
+ Weka uwiano katika fomu x:y.Maandishi madogo zaidiMaandishi kubwa zaidi
- \nInakuja Hivi Karibuni
+ Inakuja Hivi KaribuniHadithi ZinazopendekezwaHadithi Kwa Ajili YakoHali ya Mazoezi
@@ -416,28 +416,28 @@
Jibu sahihi lililowasilishwaJibu sahihi lililowasilishwa: %sJibu lililowasilishwa lisilo sahihi
- \nJibu lililowasilishwa lisilo sahihi: %s
+ Jibu lililowasilishwa lisilo sahihi: %sTegemeo ya mhusika wa tatutoleo %sLeseni za Hakimiliki
- \nMtazamo wa Leseni ya Hakimiliki
- \nNenda nyuma hadi %s
- \norodha ya tegemezi ya mhusika wa tatu
+ Mtazamo wa Leseni ya Hakimiliki
+ Nenda nyuma hadi %s
+ orodha ya tegemezi ya mhusika wa tatuorodha ya leseni za hakimiliki
- \nRejesha Somo
+ Rejesha SomoEndelea
- \nAnza tena
- \nHabari ya asubuhi,
- \nHabari ya mchana,
+ Anza tena
+ Habari ya asubuhi,
+ Habari ya mchana,Habari ya jioni,
- \nNinawezaje kuunda wasifu mpya?
- \nNinawezaje kufuta wasifu?
+ Ninawezaje kuunda wasifu mpya?
+ Ninawezaje kufuta wasifu?Nitabadilisha aje barua pepe/nambari yangu ya simu?
- \n%s ni nini?
+ %s ni nini?Msimamizi ni nani?
- \nKwa nini kicheza Uchunguzi hakipakii?
+ Kwa nini kicheza Uchunguzi hakipakii?Kwa nini sauti yangu haichezwi?
- \nNitapakua aje Mada?
+ Nitapakua aje Mada?Sijapata swali langu hapa. Nini sasa?<p>Ikiwa ni mara yako ya kwanza kuunda wasifu na huna Nambari ya Siri: </p> <p> 1. Kutoka kwa Kichagua Wasifu, gusa <strong>Weka Wasifu Nyingi</strong>. </p> <p> 2. Unda Nambari ya Siri na <strong>Hifadhi</strong>. </p> <p> 3. Jaza sehemu zote za wasifu. </p> <ol> <li> (Si lazima) Pakia picha. </li> <li> Weka jina. </li> <li> (Si lazima) Weka Nambari ya Siri yenye tarakimu 3. </li> </ol> <p> 4. Gusa <strong>Unda</strong>. Wasifu huu umeongezwa kwa Kichagua Wasifu wako! <br/> <br/> Ikiwa umeunda wasifu hapo awali na una Nambari ya Siri: </p> <p> 1. Kutoka kwa Kichagua Wasifu, gusa <strong>Ongeza Wasifu</strong>. </p> <p> 2. Weka Nambari yako ya Siri na uguse <strong>Wasilisha</strong>. </p> <p> 3. Jaza sehemu zote za wasifu. </p> <ol> <li> (Si lazima) Pakia picha. </li> <li> Weka jina. </li> <li> (Si lazima) Weka Nambari ya Siri yenye tarakimu 3. </li> </ol> <p> 4. Gusa <strong>Unda</strong>. Wasifu huu umeongezwa kwa Kichagua Wasifu wako! <br/> <br/> Kumbuka: <u>Msimamizi pekee</u> ndiye anayeweza kudhibiti wasifu.</p><p>Wasifu unapofutwa:</p> <p><br></p> <p> <li> Wasifu hauwezi kurejeshwa. </li> </p> <p> <li> Taarifa ya wasifu kama vile jina, picha na maendeleo yatafutwa kabisa. </li> </p> <p><br></p> <p>Ili kufuta wasifu (bila kujumuisha <u>Msimamizi</u>):</p> <p>1. Kutoka kwa Ukurasa wa Mwanzo wa Msimamizi, gusa kitufe cha menyu kilicho upande wa juu kushoto.</p> <p>2. Gusa <strong>Vidhibiti vya Msimamizi</strong>.</p> <p>3. Gusa <strong>Hariri Wasifu</strong>.</p> <p>4. Gonga Wasifu ambao ungependa kufuta.</p> <p>5. Katika sehemu ya chini ya skrini, gusa <strong>Ufutaji wa Wasifu</strong>.</p> <p>6. Gusa <strong>Futa</strong> ili kuthibitisha kufuta.</p><p><br></p><p>Kumbuka: <u>Msimamizi</u> pekee ndiye anayeweza kudhibiti wasifu.</ p>
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 145c532470f..fcc62d45eb4 100755
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -426,7 +426,7 @@
What do you want to learn?Great
- Let’s get \nstarted.
+ Let’s get started.YesNo…Pick a \ndifferent topic.
diff --git a/scripts/BUILD.bazel b/scripts/BUILD.bazel
index 2fcfb81eba5..4e8fca5d41e 100644
--- a/scripts/BUILD.bazel
+++ b/scripts/BUILD.bazel
@@ -92,6 +92,20 @@ kt_jvm_binary(
runtime_deps = ["//scripts/src/java/org/oppia/android/scripts/xml:xml_syntax_check_lib"],
)
+kt_jvm_binary(
+ name = "string_language_translation_check",
+ testonly = True,
+ main_class = "org.oppia.android.scripts.xml.StringLanguageTranslationCheckKt",
+ runtime_deps = ["//scripts/src/java/org/oppia/android/scripts/xml:string_language_translation_check_lib"],
+)
+
+kt_jvm_binary(
+ name = "string_resource_validation_check",
+ testonly = True,
+ main_class = "org.oppia.android.scripts.xml.StringResourceValidationCheckKt",
+ runtime_deps = ["//scripts/src/java/org/oppia/android/scripts/xml:string_resource_validation_check_lib"],
+)
+
TEST_FILE_EXEMPTION_ASSETS = generate_test_file_assets_list_from_text_protos(
name = "test_file_exemption_assets",
test_file_exemptions_name = ["test_file_exemptions"],
diff --git a/scripts/src/java/org/oppia/android/scripts/common/BUILD.bazel b/scripts/src/java/org/oppia/android/scripts/common/BUILD.bazel
index 1b3b76ec17b..3a94254e9fc 100644
--- a/scripts/src/java/org/oppia/android/scripts/common/BUILD.bazel
+++ b/scripts/src/java/org/oppia/android/scripts/common/BUILD.bazel
@@ -53,4 +53,7 @@ kt_jvm_library(
testonly = True,
srcs = ["RepositoryFile.kt"],
visibility = ["//scripts:oppia_script_library_visibility"],
+ deps = [
+ "//third_party:org_jetbrains_kotlin_kotlin-stdlib-jdk8_jar",
+ ],
)
diff --git a/scripts/src/java/org/oppia/android/scripts/common/RepositoryFile.kt b/scripts/src/java/org/oppia/android/scripts/common/RepositoryFile.kt
index 1e0565e1dbd..14962f3ee0b 100644
--- a/scripts/src/java/org/oppia/android/scripts/common/RepositoryFile.kt
+++ b/scripts/src/java/org/oppia/android/scripts/common/RepositoryFile.kt
@@ -1,6 +1,9 @@
package org.oppia.android.scripts.common
import java.io.File
+import java.nio.file.Files
+import java.nio.file.Path
+import kotlin.streams.asSequence
/** Helper class for managing & accessing files within the project repository. */
class RepositoryFile() {
@@ -41,7 +44,10 @@ class RepositoryFile() {
expectedExtension: String = "",
exemptionsList: List = listOf()
): List {
- return File(repoPath).walk().filter { file ->
+ // Note that Files.walk() is used instead of Kotlin's walk() function since the latter follows
+ // symbolic links which is almost 10x slower than not following them (due to very deep Bazel
+ // build directories), and it's not necessary to follow the symlinks.
+ return Files.walk(File(repoPath).toPath()).asSequence().map(Path::toFile).filter { file ->
val isProhibited = checkIfProhibitedFile(retrieveRelativeFilePath(file, repoPath))
!isProhibited &&
file.isFile &&
diff --git a/scripts/src/java/org/oppia/android/scripts/xml/BUILD.bazel b/scripts/src/java/org/oppia/android/scripts/xml/BUILD.bazel
index 56dc1789827..e31ea659e02 100644
--- a/scripts/src/java/org/oppia/android/scripts/xml/BUILD.bazel
+++ b/scripts/src/java/org/oppia/android/scripts/xml/BUILD.bazel
@@ -1,10 +1,40 @@
"""
Libraries corresponding to XML syntax based check to ensure that all the XML files in the codebase
-are syntactically correct.
+are syntactically correct and consistent.
"""
load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_jvm_library")
+kt_jvm_library(
+ name = "string_language_translation_check_lib",
+ testonly = True,
+ srcs = ["StringLanguageTranslationCheck.kt"],
+ visibility = ["//scripts:oppia_script_binary_visibility"],
+ deps = [
+ ":string_resource_parser",
+ ],
+)
+
+kt_jvm_library(
+ name = "string_resource_parser",
+ testonly = True,
+ srcs = ["StringResourceParser.kt"],
+ visibility = ["//scripts:oppia_script_test_visibility"],
+ deps = [
+ "//scripts/src/java/org/oppia/android/scripts/common:repository_file",
+ ],
+)
+
+kt_jvm_library(
+ name = "string_resource_validation_check_lib",
+ testonly = True,
+ srcs = ["StringResourceValidationCheck.kt"],
+ visibility = ["//scripts:oppia_script_binary_visibility"],
+ deps = [
+ ":string_resource_parser",
+ ],
+)
+
kt_jvm_library(
name = "xml_syntax_error_handler",
testonly = True,
diff --git a/scripts/src/java/org/oppia/android/scripts/xml/StringLanguageTranslationCheck.kt b/scripts/src/java/org/oppia/android/scripts/xml/StringLanguageTranslationCheck.kt
new file mode 100644
index 00000000000..35f7e41514b
--- /dev/null
+++ b/scripts/src/java/org/oppia/android/scripts/xml/StringLanguageTranslationCheck.kt
@@ -0,0 +1,45 @@
+package org.oppia.android.scripts.xml
+
+import java.io.File
+
+/**
+ * Script for checking if all strings have been translated across all supported languages.
+ *
+ * Usage:
+ * bazel run //scripts:string_language_translation_check --
+ *
+ * Arguments:
+ * - path_to_directory_root: directory path to the root of the Oppia Android repository.
+ *
+ * Example:
+ * bazel run //scripts:string_language_translation_check -- $(pwd)
+ */
+fun main(vararg args: String) {
+ require(args.isNotEmpty()) {
+ "Expected: bazel run //scripts:string_language_translation_check -- "
+ }
+
+ // Path of the repo to be analyzed.
+ val repoPath = "${args[0]}/"
+
+ val parser = StringResourceParser(File(repoPath))
+ val baseTranslations = parser.retrieveBaseStringNames()
+ val missingTranslations = parser.retrieveAllNonEnglishTranslations().mapValues { (_, xlations) ->
+ baseTranslations - xlations.strings.keys
+ }
+ val missingTranslationCount = missingTranslations.values.sumOf { it.size }
+ println("$missingTranslationCount translation(s) were found missing.")
+ if (missingTranslationCount > 0) {
+ println()
+ println("Missing translations:")
+ missingTranslations.forEach { (language, translations) ->
+ if (translations.isNotEmpty()) {
+ println("${language.name} (${translations.size}/$missingTranslationCount):")
+ translations.forEach { translation ->
+ println("- $translation")
+ }
+ println()
+ }
+ }
+ }
+}
diff --git a/scripts/src/java/org/oppia/android/scripts/xml/StringResourceParser.kt b/scripts/src/java/org/oppia/android/scripts/xml/StringResourceParser.kt
new file mode 100644
index 00000000000..955138b337b
--- /dev/null
+++ b/scripts/src/java/org/oppia/android/scripts/xml/StringResourceParser.kt
@@ -0,0 +1,109 @@
+package org.oppia.android.scripts.xml
+
+import org.oppia.android.scripts.common.RepositoryFile
+import org.w3c.dom.Node
+import org.w3c.dom.NodeList
+import java.io.File
+import javax.xml.parsers.DocumentBuilderFactory
+
+/**
+ * Parser and processor for all UI-facing string resources, for use in validation and analysis
+ * scripts.
+ *
+ * @property repoRoot the root of the Oppia Android repository being processed
+ */
+class StringResourceParser(private val repoRoot: File) {
+ private val translations by lazy { parseTranslations() }
+ private val documentBuilderFactory by lazy { DocumentBuilderFactory.newInstance() }
+
+ /** Returns the [StringFile] corresponding to the base (i.e. untranslated English) strings. */
+ fun retrieveBaseStringFile(): StringFile = translations.getValue(TranslationLanguage.ENGLISH)
+
+ /** Returns the [Set] of all string keys contained within the base strings file. */
+ fun retrieveBaseStringNames(): Set = retrieveBaseStringFile().strings.keys
+
+ /**
+ * Returns a map of all [StringFile]s (keyed by their [StringFile.language]) which represent
+ * actual translations (i.e. all non-base files--see [retrieveBaseStringFile] for the base
+ * strings).
+ */
+ fun retrieveAllNonEnglishTranslations(): Map =
+ translations.filter { (language, _) -> language != TranslationLanguage.ENGLISH }
+
+ private fun parseTranslations(): Map {
+ // A list of all XML files in the repo to be analyzed.
+ val stringFiles = RepositoryFile.collectSearchFiles(
+ repoPath = repoRoot.absolutePath,
+ expectedExtension = ".xml"
+ ).filter {
+ it.toRelativeString(repoRoot).startsWith("app/") && it.nameWithoutExtension == "strings"
+ }.associateBy {
+ checkNotNull(it.parentFile?.name?.let(::findTranslationLanguage)) {
+ "Strings file '${it.toRelativeString(repoRoot)}' does not correspond to a known language:" +
+ " ${it.parentFile?.name}"
+ }
+ }.toSortedMap() // Sorted for consistent output.
+ val expectedLanguages = TranslationLanguage.values().toSet()
+ check(expectedLanguages == stringFiles.keys) {
+ "Missing translation strings for language(s):" +
+ " ${(expectedLanguages - stringFiles.keys).joinToString() }"
+ }
+ return stringFiles.map { (language, file) ->
+ language to StringFile(language, file, file.parseStrings())
+ }.toMap()
+ }
+
+ private fun File.parseStrings(): Map {
+ val manifestDocument = documentBuilderFactory.parseXmlFile(this)
+ val stringsElem = manifestDocument.getChildSequence().single { it.nodeName == "resources" }
+ val stringElems = stringsElem.getChildSequence().filter { it.nodeName == "string" }
+ return stringElems.associate {
+ checkNotNull(it.attributes.getNamedItem("name")?.nodeValue) to checkNotNull(it.textContent)
+ }
+ }
+
+ /**
+ * The language given strings have been translated to/are being represented in.
+ *
+ * @property valuesDirectoryName the name of the resource values directory that is expected to
+ * contain a strings.xml file for strings related to this language
+ */
+ enum class TranslationLanguage(val valuesDirectoryName: String) {
+ /** Corresponds to Arabic (ar) translations. */
+ ARABIC(valuesDirectoryName = "values-ar"),
+
+ /** Corresponds to Brazilian Portuguese (pt-rBR) translations. */
+ BRAZILIAN_PORTUGUESE(valuesDirectoryName = "values-pt-rBR"),
+
+ /** Corresponds to English (en) translations. */
+ ENGLISH(valuesDirectoryName = "values"),
+
+ /** Corresponds to Swahili (sw) translations. */
+ SWAHILI(valuesDirectoryName = "values-sw");
+ }
+
+ /**
+ * A record of a specific set of translations corresponding to one language.
+ *
+ * @property language the language of this string file
+ * @property file the direct [File] to the strings.xml containing the translations
+ * @property strings a map with keys of string names and values of the actual strings retrieved
+ * from the strings.xml file
+ */
+ data class StringFile(
+ val language: TranslationLanguage,
+ val file: File,
+ val strings: Map
+ )
+
+ private companion object {
+ private fun DocumentBuilderFactory.parseXmlFile(file: File) = newDocumentBuilder().parse(file)
+
+ private fun Node.getChildSequence() = childNodes.asSequence()
+
+ private fun NodeList.asSequence() = (0 until length).asSequence().map(this::item)
+
+ private fun findTranslationLanguage(valuesDirectoryName: String) =
+ TranslationLanguage.values().find { it.valuesDirectoryName == valuesDirectoryName }
+ }
+}
diff --git a/scripts/src/java/org/oppia/android/scripts/xml/StringResourceValidationCheck.kt b/scripts/src/java/org/oppia/android/scripts/xml/StringResourceValidationCheck.kt
new file mode 100644
index 00000000000..5619474b23a
--- /dev/null
+++ b/scripts/src/java/org/oppia/android/scripts/xml/StringResourceValidationCheck.kt
@@ -0,0 +1,76 @@
+package org.oppia.android.scripts.xml
+
+import org.oppia.android.scripts.xml.StringResourceParser.StringFile
+import org.oppia.android.scripts.xml.StringResourceParser.TranslationLanguage
+import java.io.File
+
+/**
+ * Script for validating consistency between translated and base string resources.
+ *
+ * Usage:
+ * bazel run //scripts:string_resource_validation_check --
+ *
+ * Arguments:
+ * - path_to_directory_root: directory path to the root of the Oppia Android repository.
+ *
+ * Example:
+ * bazel run //scripts:string_resource_validation_check -- $(pwd)
+ */
+fun main(vararg args: String) {
+ require(args.isNotEmpty()) {
+ "Expected: bazel run //scripts:string_resource_validation_check -- "
+ }
+
+ // Path of the repo to be analyzed.
+ val repoPath = "${args[0]}/"
+ val repoRoot = File(repoPath)
+
+ data class Finding(val language: TranslationLanguage, val file: File, val errorLine: String)
+ val parser = StringResourceParser(repoRoot)
+ val baseFile = parser.retrieveBaseStringFile()
+ val otherTranslations = parser.retrieveAllNonEnglishTranslations()
+ val inconsistencies = otherTranslations.entries.fold(listOf()) { errors, entry ->
+ val (_, translatedFile) = entry
+ errors + computeInconsistenciesBetween(baseFile, translatedFile).map { line ->
+ Finding(translatedFile.language, translatedFile.file, line)
+ }
+ }.groupBy(keySelector = { it.language to it.file }, valueTransform = { it.errorLine })
+
+ if (inconsistencies.isNotEmpty()) {
+ println("${inconsistencies.size} language(s) were found with string consistency errors.")
+ println()
+
+ inconsistencies.forEach { (context, errorLines) ->
+ val (language, file) = context
+ println(
+ "${errorLines.size} consistency error(s) were found for ${language.name} strings (file:" +
+ " ${file.toRelativeString(repoRoot)}):"
+ )
+ errorLines.forEach { println("- $it") }
+ println()
+ }
+ throw Exception("STRING RESOURCE VALIDATION CHECKS FAILED")
+ } else println("STRING RESOURCE VALIDATION CHECKS PASSED")
+}
+
+private fun computeInconsistenciesBetween(
+ baseFile: StringFile,
+ translatedFile: StringFile
+): List {
+ val commonTranslations = baseFile.strings.intersectWith(translatedFile.strings)
+
+ // Check for inconsistent newlines post-translation.
+ return commonTranslations.mapNotNull { (stringName, stringPair) ->
+ val (baseString, translatedString) = stringPair
+ val baseLines = baseString.split("\\n")
+ val translatedLines = translatedString.split("\\n")
+ return@mapNotNull if (baseLines.size != translatedLines.size) {
+ "string $stringName: original translation uses ${baseLines.size} line(s) but translation" +
+ " uses ${translatedLines.size} line(s). Please remove any extra lines or add any that are" +
+ " missing."
+ } else null // The number of lines match.
+ }
+}
+
+private fun Map.intersectWith(other: Map) =
+ keys.intersect(other.keys).associateWith { getValue(it) to other.getValue(it) }
diff --git a/scripts/src/javatests/org/oppia/android/scripts/xml/BUILD.bazel b/scripts/src/javatests/org/oppia/android/scripts/xml/BUILD.bazel
index 445e7b6d76d..d1170300f87 100644
--- a/scripts/src/javatests/org/oppia/android/scripts/xml/BUILD.bazel
+++ b/scripts/src/javatests/org/oppia/android/scripts/xml/BUILD.bazel
@@ -1,10 +1,43 @@
"""
Tests corresponding to XML syntax based check to ensure that all the XML files in the codebase are
-syntactically correct.
+syntactically correct and consistent.
"""
load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_jvm_test")
+kt_jvm_test(
+ name = "StringLanguageTranslationCheckTest",
+ srcs = ["StringLanguageTranslationCheckTest.kt"],
+ deps = [
+ "//scripts/src/java/org/oppia/android/scripts/xml:string_language_translation_check_lib",
+ "//testing:assertion_helpers",
+ "//third_party:com_google_truth_truth",
+ "//third_party:org_jetbrains_kotlin_kotlin-test-junit",
+ ],
+)
+
+kt_jvm_test(
+ name = "StringResourceParserTest",
+ srcs = ["StringResourceParserTest.kt"],
+ deps = [
+ "//scripts/src/java/org/oppia/android/scripts/xml:string_resource_parser",
+ "//testing:assertion_helpers",
+ "//third_party:com_google_truth_truth",
+ "//third_party:org_jetbrains_kotlin_kotlin-test-junit",
+ ],
+)
+
+kt_jvm_test(
+ name = "StringResourceValidationCheckTest",
+ srcs = ["StringResourceValidationCheckTest.kt"],
+ deps = [
+ "//scripts/src/java/org/oppia/android/scripts/xml:string_resource_validation_check_lib",
+ "//testing:assertion_helpers",
+ "//third_party:com_google_truth_truth",
+ "//third_party:org_jetbrains_kotlin_kotlin-test-junit",
+ ],
+)
+
kt_jvm_test(
name = "XmlSyntaxCheckTest",
srcs = ["XmlSyntaxCheckTest.kt"],
diff --git a/scripts/src/javatests/org/oppia/android/scripts/xml/StringLanguageTranslationCheckTest.kt b/scripts/src/javatests/org/oppia/android/scripts/xml/StringLanguageTranslationCheckTest.kt
new file mode 100644
index 00000000000..ebf36a61a72
--- /dev/null
+++ b/scripts/src/javatests/org/oppia/android/scripts/xml/StringLanguageTranslationCheckTest.kt
@@ -0,0 +1,270 @@
+package org.oppia.android.scripts.xml
+
+import com.google.common.truth.Truth.assertThat
+import org.junit.After
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.rules.TemporaryFolder
+import org.oppia.android.testing.assertThrows
+import org.w3c.dom.Document
+import java.io.ByteArrayOutputStream
+import java.io.File
+import java.io.PrintStream
+import java.io.StringWriter
+import java.lang.IllegalArgumentException
+import javax.xml.parsers.DocumentBuilderFactory
+import javax.xml.transform.TransformerFactory
+import javax.xml.transform.dom.DOMSource
+import javax.xml.transform.stream.StreamResult
+
+/** Tests for the string_language_translation_check test. */
+// FunctionName: test names are conventionally named with underscores.
+@Suppress("FunctionName")
+class StringLanguageTranslationCheckTest {
+ private companion object {
+ private val ARABIC_STRINGS_SHARED = mapOf("shared_string" to "مشغل رحلة الاستكشاف")
+ private val ARABIC_STRINGS_EXTRAS = mapOf("arabic_only_string" to "خيارات")
+
+ private val BRAZILIAN_PORTUGUESE_STRINGS_SHARED = mapOf("shared_string" to "Meus Downloads")
+ private val BRAZILIAN_PORTUGUESE_STRINGS_EXTRAS = mapOf(
+ "brazilian_portuguese_only_string" to "Reprodutor de Exploração"
+ )
+
+ private val ENGLISH_STRINGS_SHARED = mapOf("shared_string" to "Exploration Player")
+ private val ENGLISH_STRINGS_EXTRAS = mapOf("english_only_string" to "Help")
+
+ private val SWAHILI_STRINGS_SHARED = mapOf("shared_string" to "Kicheza Ugunduzi")
+ private val SWAHILI_STRINGS_EXTRAS = mapOf("swahili_only_string" to "Badili Wasifu")
+ }
+
+ @field:[Rule JvmField] var tempFolder = TemporaryFolder()
+
+ private val originalOut: PrintStream = System.out
+ private val documentBuilderFactory by lazy { DocumentBuilderFactory.newInstance() }
+ private val transformerFactory by lazy { TransformerFactory.newInstance() }
+
+ private lateinit var outContent: ByteArrayOutputStream
+ private lateinit var appResources: File
+
+ @Before
+ fun setUp() {
+ outContent = ByteArrayOutputStream()
+ appResources = tempFolder.newFolder("app", "src", "main", "res")
+ System.setOut(PrintStream(outContent))
+ }
+
+ @After
+ fun restoreStreams() {
+ System.setOut(originalOut)
+ }
+
+ @Test
+ fun testScript_missingPath_throwsException() {
+ val exception = assertThrows(IllegalArgumentException::class) { runScript(/* With no path. */) }
+
+ assertThat(exception)
+ .hasMessageThat()
+ .contains("Expected: bazel run //scripts:string_language_translation_check -- ")
+ }
+
+ @Test
+ fun testScript_validPath_noStringFiles_throwsException() {
+ val exception = assertThrows(IllegalStateException::class) {
+ runScript(tempFolder.root.absolutePath)
+ }
+
+ assertThat(exception).hasMessageThat().contains("Missing translation strings for language(s)")
+ }
+
+ @Test
+ fun testScript_presentTranslations_allMatch_outputsNoneFoundMissing() {
+ populateArabicTranslations(ARABIC_STRINGS_SHARED)
+ populateBrazilianPortugueseTranslations(BRAZILIAN_PORTUGUESE_STRINGS_SHARED)
+ populateEnglishTranslations(ENGLISH_STRINGS_SHARED)
+ populateSwahiliTranslations(SWAHILI_STRINGS_SHARED)
+
+ runScript(tempFolder.root.absolutePath)
+
+ assertThat(outContent.asString()).contains("0 translation(s) were found missing")
+ }
+
+ @Test
+ fun testScript_presentTranslations_missingSomeArabic_outputsMissingTranslations() {
+ populateArabicTranslations(ARABIC_STRINGS_EXTRAS)
+ populateBrazilianPortugueseTranslations(BRAZILIAN_PORTUGUESE_STRINGS_SHARED)
+ populateEnglishTranslations(ENGLISH_STRINGS_SHARED)
+ populateSwahiliTranslations(SWAHILI_STRINGS_SHARED)
+
+ runScript(tempFolder.root.absolutePath)
+
+ assertThat(outContent.asString().trim()).isEqualTo(
+ """
+ 1 translation(s) were found missing.
+
+ Missing translations:
+ ARABIC (1/1):
+ - shared_string
+ """.trimIndent().trim()
+ )
+ }
+
+ @Test
+ fun testScript_presentTranslations_missingSomeBrazilianPortuguese_outputsMissingTranslations() {
+ populateArabicTranslations(ARABIC_STRINGS_SHARED)
+ populateBrazilianPortugueseTranslations(BRAZILIAN_PORTUGUESE_STRINGS_EXTRAS)
+ populateEnglishTranslations(ENGLISH_STRINGS_SHARED)
+ populateSwahiliTranslations(SWAHILI_STRINGS_SHARED)
+
+ runScript(tempFolder.root.absolutePath)
+
+ assertThat(outContent.asString().trim()).isEqualTo(
+ """
+ 1 translation(s) were found missing.
+
+ Missing translations:
+ BRAZILIAN_PORTUGUESE (1/1):
+ - shared_string
+ """.trimIndent().trim()
+ )
+ }
+
+ @Test
+ fun testScript_presentTranslations_missingSomeSwahili_outputsMissingTranslations() {
+ populateArabicTranslations(ARABIC_STRINGS_SHARED)
+ populateBrazilianPortugueseTranslations(BRAZILIAN_PORTUGUESE_STRINGS_SHARED)
+ populateEnglishTranslations(ENGLISH_STRINGS_SHARED)
+ populateSwahiliTranslations(SWAHILI_STRINGS_EXTRAS)
+
+ runScript(tempFolder.root.absolutePath)
+
+ assertThat(outContent.asString().trim()).isEqualTo(
+ """
+ 1 translation(s) were found missing.
+
+ Missing translations:
+ SWAHILI (1/1):
+ - shared_string
+ """.trimIndent().trim()
+ )
+ }
+
+ @Test
+ fun testScript_presentTranslations_missingMultiple_outputsMissingTranslationsWithTotalCount() {
+ populateArabicTranslations(ARABIC_STRINGS_EXTRAS)
+ populateBrazilianPortugueseTranslations(BRAZILIAN_PORTUGUESE_STRINGS_EXTRAS)
+ populateEnglishTranslations(ENGLISH_STRINGS_SHARED + ENGLISH_STRINGS_EXTRAS)
+ populateSwahiliTranslations(SWAHILI_STRINGS_EXTRAS)
+
+ runScript(tempFolder.root.absolutePath)
+
+ assertThat(outContent.asString().trim()).isEqualTo(
+ """
+ 6 translation(s) were found missing.
+
+ Missing translations:
+ ARABIC (2/6):
+ - shared_string
+ - english_only_string
+
+ BRAZILIAN_PORTUGUESE (2/6):
+ - shared_string
+ - english_only_string
+
+ SWAHILI (2/6):
+ - shared_string
+ - english_only_string
+ """.trimIndent().trim()
+ )
+ }
+
+ @Test
+ fun testScript_presentTranslations_missingMultiple_someShared_outputsMissingXlationsWithCount() {
+ populateArabicTranslations(ARABIC_STRINGS_SHARED + ARABIC_STRINGS_EXTRAS)
+ populateBrazilianPortugueseTranslations(
+ BRAZILIAN_PORTUGUESE_STRINGS_SHARED + BRAZILIAN_PORTUGUESE_STRINGS_EXTRAS
+ )
+ populateEnglishTranslations(ENGLISH_STRINGS_SHARED + ENGLISH_STRINGS_EXTRAS)
+ populateSwahiliTranslations(SWAHILI_STRINGS_SHARED + SWAHILI_STRINGS_EXTRAS)
+
+ runScript(tempFolder.root.absolutePath)
+
+ assertThat(outContent.asString().trim()).isEqualTo(
+ """
+ 3 translation(s) were found missing.
+
+ Missing translations:
+ ARABIC (1/3):
+ - english_only_string
+
+ BRAZILIAN_PORTUGUESE (1/3):
+ - english_only_string
+
+ SWAHILI (1/3):
+ - english_only_string
+ """.trimIndent().trim()
+ )
+ }
+
+ @Test
+ fun testScript_missingEnglishTranslations_outputsNoneFoundMissing() {
+ populateArabicTranslations(ARABIC_STRINGS_SHARED)
+ populateBrazilianPortugueseTranslations(BRAZILIAN_PORTUGUESE_STRINGS_SHARED)
+ populateEnglishTranslations(mapOf())
+ populateSwahiliTranslations(SWAHILI_STRINGS_SHARED)
+
+ runScript(tempFolder.root.absolutePath)
+
+ // No translations should be found missing if the string is everywhere except the base file.
+ assertThat(outContent.asString()).contains("0 translation(s) were found missing")
+ }
+
+ private fun runScript(vararg args: String) = main(*args)
+
+ private fun populateArabicTranslations(strings: Map) {
+ populateTranslations(appResources, "values-ar", strings)
+ }
+
+ private fun populateBrazilianPortugueseTranslations(strings: Map) {
+ populateTranslations(appResources, "values-pt-rBR", strings)
+ }
+
+ private fun populateEnglishTranslations(strings: Map) {
+ populateTranslations(appResources, "values", strings)
+ }
+
+ private fun populateSwahiliTranslations(strings: Map) {
+ populateTranslations(appResources, "values-sw", strings)
+ }
+
+ private fun populateTranslations(
+ resourceDir: File,
+ valuesDirName: String,
+ translations: Map
+ ) {
+ val document = documentBuilderFactory.newDocumentBuilder().newDocument()
+ val resourcesRoot = document.createElement("resources").also { document.appendChild(it) }
+ translations.map { (name, value) ->
+ document.createElement("string").also {
+ it.setAttribute("name", name)
+ it.textContent = value
+ }
+ }.forEach(resourcesRoot::appendChild)
+ writeTranslationsFile(resourceDir, valuesDirName, document.toSource())
+ }
+
+ private fun writeTranslationsFile(resourceDir: File, valuesDirName: String, contents: String) {
+ val valuesDir = File(resourceDir, valuesDirName).also { check(it.mkdir()) }
+ File(valuesDir, "strings.xml").writeText(contents)
+ }
+
+ private fun Document.toSource(): String {
+ // Reference: https://stackoverflow.com/a/5456836.
+ val transformer = transformerFactory.newTransformer()
+ return StringWriter().apply {
+ transformer.transform(DOMSource(this@toSource), StreamResult(this@apply))
+ }.toString()
+ }
+
+ private fun ByteArrayOutputStream.asString() = toString(Charsets.UTF_8.name())
+}
diff --git a/scripts/src/javatests/org/oppia/android/scripts/xml/StringResourceParserTest.kt b/scripts/src/javatests/org/oppia/android/scripts/xml/StringResourceParserTest.kt
new file mode 100644
index 00000000000..474b0ceba83
--- /dev/null
+++ b/scripts/src/javatests/org/oppia/android/scripts/xml/StringResourceParserTest.kt
@@ -0,0 +1,279 @@
+package org.oppia.android.scripts.xml
+
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.rules.TemporaryFolder
+import org.oppia.android.scripts.xml.StringResourceParser.TranslationLanguage.ARABIC
+import org.oppia.android.scripts.xml.StringResourceParser.TranslationLanguage.BRAZILIAN_PORTUGUESE
+import org.oppia.android.scripts.xml.StringResourceParser.TranslationLanguage.ENGLISH
+import org.oppia.android.scripts.xml.StringResourceParser.TranslationLanguage.SWAHILI
+import org.oppia.android.testing.assertThrows
+import org.w3c.dom.Document
+import org.xml.sax.SAXParseException
+import java.io.File
+import java.io.StringWriter
+import javax.xml.parsers.DocumentBuilderFactory
+import javax.xml.transform.TransformerFactory
+import javax.xml.transform.dom.DOMSource
+import javax.xml.transform.stream.StreamResult
+
+/** Tests for [StringResourceParser]. */
+// FunctionName: test names are conventionally named with underscores.
+@Suppress("FunctionName")
+class StringResourceParserTest {
+ @field:[Rule JvmField] val tempFolder = TemporaryFolder()
+
+ private companion object {
+ private val ARABIC_STRINGS = mapOf(
+ "shared_string" to "مشغل رحلة الاستكشاف",
+ "arabic_only_string" to "خيارات"
+ )
+
+ private val BRAZILIAN_PORTUGUESE_STRINGS = mapOf(
+ "shared_string" to "Meus Downloads",
+ "brazilian_portuguese_only_string" to "Reprodutor de Exploração"
+ )
+
+ private val ENGLISH_STRINGS = mapOf(
+ "shared_string" to "Exploration Player",
+ "english_only_string" to "Help"
+ )
+
+ private val SWAHILI_STRINGS = mapOf(
+ "shared_string" to "Kicheza Ugunduzi",
+ "swahili_only_string" to "Badili Wasifu"
+ )
+ }
+
+ private val documentBuilderFactory by lazy { DocumentBuilderFactory.newInstance() }
+ private val transformerFactory by lazy { TransformerFactory.newInstance() }
+
+ private lateinit var appResources: File
+ private lateinit var utilityResources: File
+
+ @Before
+ fun setUp() {
+ // Ensure there are directories for string resources.
+ appResources = tempFolder.newFolder("app", "src", "main", "res")
+ utilityResources = tempFolder.newFolder("utility", "src", "main", "res")
+ }
+
+ @Test
+ fun testRetrieveBaseStringFile_noStrings_throwsException() {
+ val parser = StringResourceParser(tempFolder.root)
+
+ val exception = assertThrows(IllegalStateException::class) { parser.retrieveBaseStringFile() }
+
+ assertThat(exception)
+ .hasMessageThat()
+ .contains(
+ "Missing translation strings for language(s): ARABIC, BRAZILIAN_PORTUGUESE, ENGLISH," +
+ " SWAHILI"
+ )
+ }
+
+ @Test
+ fun testRetrieveBaseStringFile_noBaseEnglishStrings_throwsException() {
+ populateArabicTranslations()
+ populateBrazilianPortugueseTranslations()
+ populateSwahiliTranslations()
+ val parser = StringResourceParser(tempFolder.root)
+
+ val exception = assertThrows(IllegalStateException::class) { parser.retrieveBaseStringFile() }
+
+ assertThat(exception)
+ .hasMessageThat()
+ .contains("Missing translation strings for language(s): ENGLISH")
+ }
+
+ @Test
+ fun testRetrieveBaseStringFile_noArabicStrings_throwsException() {
+ populateBrazilianPortugueseTranslations()
+ populateEnglishTranslations()
+ populateSwahiliTranslations()
+ val parser = StringResourceParser(tempFolder.root)
+
+ val exception = assertThrows(IllegalStateException::class) { parser.retrieveBaseStringFile() }
+
+ assertThat(exception)
+ .hasMessageThat()
+ .contains("Missing translation strings for language(s): ARABIC")
+ }
+
+ @Test
+ fun testRetrieveBaseStringFile_noBrazilianPortugueseStrings_throwsException() {
+ populateArabicTranslations()
+ populateEnglishTranslations()
+ populateSwahiliTranslations()
+ val parser = StringResourceParser(tempFolder.root)
+
+ val exception = assertThrows(IllegalStateException::class) { parser.retrieveBaseStringFile() }
+
+ assertThat(exception)
+ .hasMessageThat()
+ .contains("Missing translation strings for language(s): BRAZILIAN_PORTUGUESE")
+ }
+
+ @Test
+ fun testRetrieveBaseStringFile_noSwahiliStrings_throwsException() {
+ populateArabicTranslations()
+ populateBrazilianPortugueseTranslations()
+ populateEnglishTranslations()
+ val parser = StringResourceParser(tempFolder.root)
+
+ val exception = assertThrows(IllegalStateException::class) { parser.retrieveBaseStringFile() }
+
+ assertThat(exception)
+ .hasMessageThat()
+ .contains("Missing translation strings for language(s): SWAHILI")
+ }
+
+ @Test
+ fun testRetrieveBaseStringFile_extraStringsDirectory_throwsException() {
+ populateAllAppTranslations()
+ populateTranslations(appResources, "values-fake", mapOf())
+ val parser = StringResourceParser(tempFolder.root)
+
+ val exception = assertThrows(IllegalStateException::class) { parser.retrieveBaseStringFile() }
+
+ assertThat(exception)
+ .hasMessageThat()
+ .contains(
+ "Strings file 'app/src/main/res/values-fake/strings.xml' does not correspond to a known" +
+ " language: values-fake"
+ )
+ }
+
+ @Test
+ fun testRetrieveBaseStringFile_stringsOutsideAppDirectory_areIgnored() {
+ populateArabicTranslations()
+ populateBrazilianPortugueseTranslations()
+ populateSwahiliTranslations()
+ populateTranslations(utilityResources, "values", mapOf())
+ val parser = StringResourceParser(tempFolder.root)
+
+ val exception = assertThrows(IllegalStateException::class) { parser.retrieveBaseStringFile() }
+
+ // An exception is still thrown since resources outside the app directory are ignored.
+ assertThat(exception)
+ .hasMessageThat()
+ .contains("Missing translation strings for language(s): ENGLISH")
+ }
+
+ @Test
+ fun testRetrieveBaseStringFile_allStringsPresent_baseStringsInvalidXml_throwsException() {
+ populateArabicTranslations()
+ populateBrazilianPortugueseTranslations()
+ populateSwahiliTranslations()
+ writeTranslationsFile(appResources, "values", "")
+ val parser = StringResourceParser(tempFolder.root)
+
+ assertThrows(SAXParseException::class) { parser.retrieveBaseStringFile() }
+ }
+
+ @Test
+ fun testRetrieveBaseStringFile_allStringsPresentAndValid_returnsBaseStringFile() {
+ populateAllAppTranslations()
+ val parser = StringResourceParser(tempFolder.root)
+
+ val stringFile = parser.retrieveBaseStringFile()
+
+ assertThat(stringFile.language).isEqualTo(ENGLISH)
+ assertThat(stringFile.file.toRelativeString(tempFolder.root))
+ .isEqualTo("app/src/main/res/values/strings.xml")
+ assertThat(stringFile.strings).containsExactlyEntriesIn(ENGLISH_STRINGS)
+ }
+
+ @Test
+ fun testRetrieveBaseStringNames_allStringsPresentAndValid_returnsBaseStringNames() {
+ populateAllAppTranslations()
+ val parser = StringResourceParser(tempFolder.root)
+
+ val stringNames = parser.retrieveBaseStringNames()
+
+ assertThat(stringNames).containsExactly("shared_string", "english_only_string")
+ }
+
+ @Test
+ fun retrieveAllNonEnglishTranslations_allStringsPresentAndValid_returnsNonEnglishStringFiles() {
+ populateAllAppTranslations()
+ val parser = StringResourceParser(tempFolder.root)
+
+ val nonEnglishTranslations = parser.retrieveAllNonEnglishTranslations()
+
+ assertThat(nonEnglishTranslations).hasSize(3)
+ assertThat(nonEnglishTranslations).containsKey(ARABIC)
+ assertThat(nonEnglishTranslations).containsKey(BRAZILIAN_PORTUGUESE)
+ assertThat(nonEnglishTranslations).containsKey(SWAHILI)
+ assertThat(nonEnglishTranslations).doesNotContainKey(ENGLISH) // Only non-English are included.
+ val arFile = nonEnglishTranslations[ARABIC]
+ assertThat(arFile?.language).isEqualTo(ARABIC)
+ assertThat(arFile?.file?.toRelativeString(tempFolder.root))
+ .isEqualTo("app/src/main/res/values-ar/strings.xml")
+ assertThat(arFile?.strings).containsExactlyEntriesIn(ARABIC_STRINGS)
+ val ptBrFile = nonEnglishTranslations[BRAZILIAN_PORTUGUESE]
+ assertThat(ptBrFile?.language).isEqualTo(BRAZILIAN_PORTUGUESE)
+ assertThat(ptBrFile?.file?.toRelativeString(tempFolder.root))
+ .isEqualTo("app/src/main/res/values-pt-rBR/strings.xml")
+ assertThat(ptBrFile?.strings).containsExactlyEntriesIn(BRAZILIAN_PORTUGUESE_STRINGS)
+ val swFile = nonEnglishTranslations[SWAHILI]
+ assertThat(swFile?.language).isEqualTo(SWAHILI)
+ assertThat(swFile?.file?.toRelativeString(tempFolder.root))
+ .isEqualTo("app/src/main/res/values-sw/strings.xml")
+ assertThat(swFile?.strings).containsExactlyEntriesIn(SWAHILI_STRINGS)
+ }
+
+ private fun populateAllAppTranslations() {
+ populateArabicTranslations()
+ populateBrazilianPortugueseTranslations()
+ populateEnglishTranslations()
+ populateSwahiliTranslations()
+ }
+
+ private fun populateArabicTranslations() {
+ populateTranslations(appResources, "values-ar", ARABIC_STRINGS)
+ }
+
+ private fun populateBrazilianPortugueseTranslations() {
+ populateTranslations(appResources, "values-pt-rBR", BRAZILIAN_PORTUGUESE_STRINGS)
+ }
+
+ private fun populateEnglishTranslations() {
+ populateTranslations(appResources, "values", ENGLISH_STRINGS)
+ }
+
+ private fun populateSwahiliTranslations() {
+ populateTranslations(appResources, "values-sw", SWAHILI_STRINGS)
+ }
+
+ private fun populateTranslations(
+ resourceDir: File,
+ valuesDirName: String,
+ translations: Map
+ ) {
+ val document = documentBuilderFactory.newDocumentBuilder().newDocument()
+ val resourcesRoot = document.createElement("resources").also { document.appendChild(it) }
+ translations.map { (name, value) ->
+ document.createElement("string").also {
+ it.setAttribute("name", name)
+ it.textContent = value
+ }
+ }.forEach(resourcesRoot::appendChild)
+ writeTranslationsFile(resourceDir, valuesDirName, document.toSource())
+ }
+
+ private fun writeTranslationsFile(resourceDir: File, valuesDirName: String, contents: String) {
+ val valuesDir = File(resourceDir, valuesDirName).also { check(it.mkdir()) }
+ File(valuesDir, "strings.xml").writeText(contents)
+ }
+
+ private fun Document.toSource(): String {
+ // Reference: https://stackoverflow.com/a/5456836.
+ val transformer = transformerFactory.newTransformer()
+ return StringWriter().apply {
+ transformer.transform(DOMSource(this@toSource), StreamResult(this@apply))
+ }.toString()
+ }
+}
diff --git a/scripts/src/javatests/org/oppia/android/scripts/xml/StringResourceValidationCheckTest.kt b/scripts/src/javatests/org/oppia/android/scripts/xml/StringResourceValidationCheckTest.kt
new file mode 100644
index 00000000000..c7fc526f687
--- /dev/null
+++ b/scripts/src/javatests/org/oppia/android/scripts/xml/StringResourceValidationCheckTest.kt
@@ -0,0 +1,259 @@
+package org.oppia.android.scripts.xml
+
+import com.google.common.truth.Truth.assertThat
+import org.junit.After
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.rules.TemporaryFolder
+import org.oppia.android.testing.assertThrows
+import org.w3c.dom.Document
+import java.io.ByteArrayOutputStream
+import java.io.File
+import java.io.PrintStream
+import java.io.StringWriter
+import javax.xml.parsers.DocumentBuilderFactory
+import javax.xml.transform.TransformerFactory
+import javax.xml.transform.dom.DOMSource
+import javax.xml.transform.stream.StreamResult
+
+/** Tests for the string_resource_validation_check test. */
+// FunctionName: test names are conventionally named with underscores.
+@Suppress("FunctionName")
+class StringResourceValidationCheckTest {
+ private companion object {
+ private const val AR_STRING_NO_NEWLINES = "مساعدة"
+ private const val AR_STRING_ONE_NEWLINE = "مساعدة\\n"
+ private const val AR_STRING_TWO_NEWLINES = "\\nمساعدة\\n"
+
+ private const val PT_BR_STRING_NO_NEWLINES = "Ajuda"
+ private const val PT_BR_STRING_ONE_NEWLINE = "\\nAjuda"
+ private const val PT_BR_STRING_TWO_NEWLINES = "\\nAjuda\\n"
+
+ private const val EN_STRING_ONE_NEWLINE = "\\nHelp"
+
+ private const val SW_STRING_NO_NEWLINES = "Msaada"
+ private const val SW_STRING_ONE_NEWLINE = "\\nMsaada"
+ private const val SW_STRING_TWO_NEWLINES = "\\nMsaada\\n"
+ }
+
+ @field:[Rule JvmField] var tempFolder = TemporaryFolder()
+
+ private val originalOut: PrintStream = System.out
+ private val documentBuilderFactory by lazy { DocumentBuilderFactory.newInstance() }
+ private val transformerFactory by lazy { TransformerFactory.newInstance() }
+
+ private lateinit var outContent: ByteArrayOutputStream
+ private lateinit var appResources: File
+
+ @Before
+ fun setUp() {
+ outContent = ByteArrayOutputStream()
+ appResources = tempFolder.newFolder("app", "src", "main", "res")
+ System.setOut(PrintStream(outContent))
+ }
+
+ @After
+ fun restoreStreams() {
+ System.setOut(originalOut)
+ }
+
+ @Test
+ fun testScript_missingPath_throwsException() {
+ val exception = assertThrows(IllegalArgumentException::class) { runScript(/* With no path. */) }
+
+ assertThat(exception)
+ .hasMessageThat()
+ .contains("Expected: bazel run //scripts:string_resource_validation_check -- ")
+ }
+
+ @Test
+ fun testScript_validPath_noStringFiles_fails() {
+ val exception = assertThrows(IllegalStateException::class) {
+ runScript(tempFolder.root.absolutePath)
+ }
+
+ assertThat(exception).hasMessageThat().contains("Missing translation strings for language(s)")
+ }
+
+ @Test
+ fun testScript_allMatch_succeeds() {
+ populateArabicTranslations(mapOf("str1" to AR_STRING_ONE_NEWLINE))
+ populateBrazilianPortugueseTranslations(mapOf("str1" to PT_BR_STRING_ONE_NEWLINE))
+ populateEnglishTranslations(mapOf("str1" to EN_STRING_ONE_NEWLINE))
+ populateSwahiliTranslations(mapOf("str1" to SW_STRING_ONE_NEWLINE))
+
+ runScript(tempFolder.root.absolutePath)
+
+ assertThat(outContent.asString()).contains("STRING RESOURCE VALIDATION CHECKS PASSED")
+ }
+
+ @Test
+ fun testScript_inconsistentLines_arabic_failsWithFindings() {
+ populateArabicTranslations(
+ mapOf("str1" to AR_STRING_NO_NEWLINES, "str2" to AR_STRING_TWO_NEWLINES)
+ )
+ populateBrazilianPortugueseTranslations(mapOf("str1" to PT_BR_STRING_ONE_NEWLINE))
+ populateEnglishTranslations(
+ mapOf("str1" to EN_STRING_ONE_NEWLINE, "str2" to EN_STRING_ONE_NEWLINE)
+ )
+ populateSwahiliTranslations(mapOf("str1" to SW_STRING_ONE_NEWLINE))
+
+ val exception = assertThrows(Exception::class) { runScript(tempFolder.root.absolutePath) }
+
+ // This output check also inadvertently verifies that the script doesn't care about missing
+ // strings in translated string files.
+ assertThat(exception).hasMessageThat().contains("STRING RESOURCE VALIDATION CHECKS FAILED")
+ assertThat(outContent.asString().trim()).isEqualTo(
+ """
+ 1 language(s) were found with string consistency errors.
+
+ 2 consistency error(s) were found for ARABIC strings (file: app/src/main/res/values-ar/strings.xml):
+ - string str1: original translation uses 2 line(s) but translation uses 1 line(s). Please remove any extra lines or add any that are missing.
+ - string str2: original translation uses 2 line(s) but translation uses 3 line(s). Please remove any extra lines or add any that are missing.
+ """.trimIndent().trim()
+ )
+ }
+
+ @Test
+ fun testScript_inconsistentLines_brazilianPortuguese_failsWithFindings() {
+ populateArabicTranslations(mapOf("str1" to AR_STRING_ONE_NEWLINE))
+ populateBrazilianPortugueseTranslations(
+ mapOf("str1" to PT_BR_STRING_NO_NEWLINES, "str2" to PT_BR_STRING_TWO_NEWLINES)
+ )
+ populateEnglishTranslations(
+ mapOf("str1" to EN_STRING_ONE_NEWLINE, "str2" to EN_STRING_ONE_NEWLINE)
+ )
+ populateSwahiliTranslations(mapOf("str1" to SW_STRING_ONE_NEWLINE))
+
+ val exception = assertThrows(Exception::class) { runScript(tempFolder.root.absolutePath) }
+
+ // This output check also inadvertently verifies that the script doesn't care about missing
+ // strings in translated string files.
+ assertThat(exception).hasMessageThat().contains("STRING RESOURCE VALIDATION CHECKS FAILED")
+ assertThat(outContent.asString().trim()).isEqualTo(
+ """
+ 1 language(s) were found with string consistency errors.
+
+ 2 consistency error(s) were found for BRAZILIAN_PORTUGUESE strings (file: app/src/main/res/values-pt-rBR/strings.xml):
+ - string str1: original translation uses 2 line(s) but translation uses 1 line(s). Please remove any extra lines or add any that are missing.
+ - string str2: original translation uses 2 line(s) but translation uses 3 line(s). Please remove any extra lines or add any that are missing.
+ """.trimIndent().trim()
+ )
+ }
+
+ @Test
+ fun testScript_inconsistentLines_swahili_failsWithFindings() {
+ populateArabicTranslations(mapOf("str1" to AR_STRING_ONE_NEWLINE))
+ populateBrazilianPortugueseTranslations(mapOf("str1" to PT_BR_STRING_ONE_NEWLINE))
+ populateEnglishTranslations(
+ mapOf("str1" to EN_STRING_ONE_NEWLINE, "str2" to EN_STRING_ONE_NEWLINE)
+ )
+ populateSwahiliTranslations(
+ mapOf("str1" to SW_STRING_NO_NEWLINES, "str2" to SW_STRING_TWO_NEWLINES)
+ )
+
+ val exception = assertThrows(Exception::class) { runScript(tempFolder.root.absolutePath) }
+
+ // This output check also inadvertently verifies that the script doesn't care about missing
+ // strings in translated string files.
+ assertThat(exception).hasMessageThat().contains("STRING RESOURCE VALIDATION CHECKS FAILED")
+ assertThat(outContent.asString().trim()).isEqualTo(
+ """
+ 1 language(s) were found with string consistency errors.
+
+ 2 consistency error(s) were found for SWAHILI strings (file: app/src/main/res/values-sw/strings.xml):
+ - string str1: original translation uses 2 line(s) but translation uses 1 line(s). Please remove any extra lines or add any that are missing.
+ - string str2: original translation uses 2 line(s) but translation uses 3 line(s). Please remove any extra lines or add any that are missing.
+ """.trimIndent().trim()
+ )
+ }
+
+ @Test
+ fun testScript_inconsistentLines_allLanguages_failsWithFindings() {
+ populateArabicTranslations(
+ mapOf("str1" to AR_STRING_NO_NEWLINES, "str2" to AR_STRING_TWO_NEWLINES)
+ )
+ populateBrazilianPortugueseTranslations(
+ mapOf("str1" to PT_BR_STRING_NO_NEWLINES, "str2" to PT_BR_STRING_TWO_NEWLINES)
+ )
+ populateEnglishTranslations(
+ mapOf("str1" to EN_STRING_ONE_NEWLINE, "str2" to EN_STRING_ONE_NEWLINE)
+ )
+ populateSwahiliTranslations(
+ mapOf("str1" to SW_STRING_NO_NEWLINES, "str2" to SW_STRING_TWO_NEWLINES)
+ )
+
+ val exception = assertThrows(Exception::class) { runScript(tempFolder.root.absolutePath) }
+
+ // This output check also inadvertently verifies that the script doesn't care about missing
+ // strings in translated string files.
+ assertThat(exception).hasMessageThat().contains("STRING RESOURCE VALIDATION CHECKS FAILED")
+ assertThat(outContent.asString().trim()).isEqualTo(
+ """
+ 3 language(s) were found with string consistency errors.
+
+ 2 consistency error(s) were found for ARABIC strings (file: app/src/main/res/values-ar/strings.xml):
+ - string str1: original translation uses 2 line(s) but translation uses 1 line(s). Please remove any extra lines or add any that are missing.
+ - string str2: original translation uses 2 line(s) but translation uses 3 line(s). Please remove any extra lines or add any that are missing.
+
+ 2 consistency error(s) were found for BRAZILIAN_PORTUGUESE strings (file: app/src/main/res/values-pt-rBR/strings.xml):
+ - string str1: original translation uses 2 line(s) but translation uses 1 line(s). Please remove any extra lines or add any that are missing.
+ - string str2: original translation uses 2 line(s) but translation uses 3 line(s). Please remove any extra lines or add any that are missing.
+
+ 2 consistency error(s) were found for SWAHILI strings (file: app/src/main/res/values-sw/strings.xml):
+ - string str1: original translation uses 2 line(s) but translation uses 1 line(s). Please remove any extra lines or add any that are missing.
+ - string str2: original translation uses 2 line(s) but translation uses 3 line(s). Please remove any extra lines or add any that are missing.
+ """.trimIndent().trim()
+ )
+ }
+
+ private fun runScript(vararg args: String) = main(*args)
+
+ private fun populateArabicTranslations(strings: Map) {
+ populateTranslations(appResources, "values-ar", strings)
+ }
+
+ private fun populateBrazilianPortugueseTranslations(strings: Map) {
+ populateTranslations(appResources, "values-pt-rBR", strings)
+ }
+
+ private fun populateEnglishTranslations(strings: Map) {
+ populateTranslations(appResources, "values", strings)
+ }
+
+ private fun populateSwahiliTranslations(strings: Map) {
+ populateTranslations(appResources, "values-sw", strings)
+ }
+
+ private fun populateTranslations(
+ resourceDir: File,
+ valuesDirName: String,
+ translations: Map
+ ) {
+ val document = documentBuilderFactory.newDocumentBuilder().newDocument()
+ val resourcesRoot = document.createElement("resources").also { document.appendChild(it) }
+ translations.map { (name, value) ->
+ document.createElement("string").also {
+ it.setAttribute("name", name)
+ it.textContent = value
+ }
+ }.forEach(resourcesRoot::appendChild)
+ writeTranslationsFile(resourceDir, valuesDirName, document.toSource())
+ }
+
+ private fun writeTranslationsFile(resourceDir: File, valuesDirName: String, contents: String) {
+ val valuesDir = File(resourceDir, valuesDirName).also { check(it.mkdir()) }
+ File(valuesDir, "strings.xml").writeText(contents)
+ }
+
+ private fun Document.toSource(): String {
+ // Reference: https://stackoverflow.com/a/5456836.
+ val transformer = transformerFactory.newTransformer()
+ return StringWriter().apply {
+ transformer.transform(DOMSource(this@toSource), StreamResult(this@apply))
+ }.toString()
+ }
+
+ private fun ByteArrayOutputStream.asString() = toString(Charsets.UTF_8.name())
+}
diff --git a/third_party/maven_install.json b/third_party/maven_install.json
index a25cf4753fa..d743a3bb8ee 100644
--- a/third_party/maven_install.json
+++ b/third_party/maven_install.json
@@ -1,8 +1,8 @@
{
"dependency_tree": {
"__AUTOGENERATED_FILE_DO_NOT_MODIFY_THIS_FILE_MANUALLY": "THERE_IS_NO_DATA_ONLY_ZUUL",
- "__INPUT_ARTIFACTS_HASH": 134596076,
- "__RESOLVED_ARTIFACTS_HASH": -1383535075,
+ "__INPUT_ARTIFACTS_HASH": -2010577555,
+ "__RESOLVED_ARTIFACTS_HASH": 6219109,
"conflict_resolution": {
"androidx.constraintlayout:constraintlayout:1.1.3": "androidx.constraintlayout:constraintlayout:2.0.1",
"androidx.core:core:1.0.1": "androidx.core:core:1.3.1",
@@ -12,7 +12,7 @@
"com.google.truth:truth:0.43": "com.google.truth:truth:1.1.3",
"junit:junit:4.12": "junit:junit:4.13.2",
"org.jetbrains.kotlin:kotlin-reflect:1.3.41": "org.jetbrains.kotlin:kotlin-reflect:1.5.0",
- "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.72": "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.4.10",
+ "org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.72": "org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.4.10",
"org.mockito:mockito-core:2.19.0": "org.mockito:mockito-core:3.9.0"
},
"dependencies": [
@@ -7157,8 +7157,10 @@
{
"coord": "com.squareup:kotlinpoet:1.6.0",
"dependencies": [
+ "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.4.10",
"org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.4.10",
- "org.jetbrains.kotlin:kotlin-reflect:1.5.0"
+ "org.jetbrains.kotlin:kotlin-reflect:1.5.0",
+ "org.jetbrains.kotlin:kotlin-stdlib:1.5.0"
],
"directDependencies": [
"org.jetbrains.kotlin:kotlin-reflect:1.5.0",
@@ -7179,6 +7181,8 @@
"coord": "com.squareup:kotlinpoet:jar:sources:1.6.0",
"dependencies": [
"org.jetbrains.kotlin:kotlin-stdlib-jdk8:jar:sources:1.4.10",
+ "org.jetbrains.kotlin:kotlin-stdlib:jar:sources:1.5.0",
+ "org.jetbrains.kotlin:kotlin-stdlib-jdk7:jar:sources:1.4.10",
"org.jetbrains.kotlin:kotlin-reflect:jar:sources:1.5.0"
],
"directDependencies": [
diff --git a/third_party/versions.bzl b/third_party/versions.bzl
index 289c58ad5a8..245d14f20b9 100644
--- a/third_party/versions.bzl
+++ b/third_party/versions.bzl
@@ -69,7 +69,7 @@ MAVEN_PRODUCTION_DEPENDENCY_VERSIONS = {
"javax.annotation:javax.annotation-api:jar": "1.3.2",
"javax.inject:javax.inject": "1",
"nl.dionsegijn:konfetti": "1.2.5",
- "org.jetbrains.kotlin:kotlin-stdlib-jdk7:jar": "1.3.72",
+ "org.jetbrains.kotlin:kotlin-stdlib-jdk8:jar": "1.3.72",
"org.jetbrains.kotlinx:kotlinx-coroutines-android": "1.4.1",
"org.jetbrains.kotlinx:kotlinx-coroutines-core": "1.4.1",
"org.jetbrains:annotations:jar": "13.0",
From 1fcd7746f23af5e546558203eb685d0c7662a39d Mon Sep 17 00:00:00 2001
From: Ben Henning
Date: Thu, 8 Sep 2022 00:40:19 -0700
Subject: [PATCH 36/57] Fix #4389, #4407: Future-proof event analytics logging
infrastructure (#4421)
## Explanation
Fixes #4389
Fixes #4407
This PR "future-proofs" the learner analytics logging infrastructure by:
- Introducing separate event names that should be more understandable to data analysts than used in the Kenya version of the app (though compatibility is still kept with existing Kenya logged metrics by means of a separate implementation used only in that build of the app).
- Logging a new ``event_type`` parameter that contains the actual proto integer of the event rather than just logging a string representation (so that we can rename both the events in code, and the corresponding strings logged to Firebase). The event names, at this point, act as a nice point-of-reference while analyzing events but are no longer meant to be the primary identifying keys for events (``event_type`` should be used for this purpose, instead).
- The device's Android SDK version, the app's version name, and the app's version code are now logged with all events for better event dimension slicing and analysis.
- Effort is now made to ensure event names don't exceed 40 characters (Firebase's limit) to help avoid events being potentially rejected during upload.
Specifics about tests and exemptions:
- ``EventTypeToHumanReadableNameConverter`` is exempted from tests since it's an interface.
- ``KenyaAlphaEventTypeToHumanReadableNameConverterImpl`` is exempted from tests since it's temporary, and its values are at least indirectly tested through ``KenyaAlphaEventBundleCreatorTest``.
- ``KenyaAlphaEventBundleCreatorTest`` was added as a fork of ``EventBundleCreatorTest`` to ensure the existing Kenya-specific event names are properly logged, but it will be removed in the future (as tracked by #4419). Note that this suite wasn't updated to verify the new fields like ``EventBundleCreatorTest`` was.
- A BUILD.bazel file was added for the existing logging/firebase and logging/performancemetrics tests since one was added for the tests under logging/ (and subpackages must also have BUILD files if parent packages do).
## Essential Checklist
- [x] The PR title and explanation each start with "Fix #bugnum: " (If this PR fixes part of an issue, prefix the title with "Fix part of #bugnum: ...".)
- [x] Any changes to [scripts/assets](https://github.com/oppia/oppia-android/tree/develop/scripts/assets) files have their rationale included in the PR explanation.
- [x] The PR follows the [style guide](https://github.com/oppia/oppia-android/wiki/Coding-style-guide).
- [x] The PR does not contain any unnecessary code changes from Android Studio ([reference](https://github.com/oppia/oppia-android/wiki/Guidance-on-submitting-a-PR#undo-unnecessary-changes)).
- [x] The PR is made from a branch that's **not** called "develop" and is up-to-date with "develop".
- [x] The PR is **assigned** to the appropriate reviewers ([reference](https://github.com/oppia/oppia-android/wiki/Guidance-on-submitting-a-PR#clarification-regarding-assignees-and-reviewers-section)).
## For UI-specific PRs only
N/A -- This is a metrics infrastructure change that will have zero effect on the UI (except maybe how events are displayed in the developer options menu, but that's not important to include here since it isn't end user-facing).
Commits:
* Create dedicated alpha application component.
This simplifies application component management significantly and
allows individual build flavors to have their own unique module lists.
* Add beta & GA update notices.
This also introduces dedicated beta & GA build flavors which is a
necessary prerequisite.
It also introduces an extra beta, alpha, and dev mode labels for the splash
screen (the latter 2 were extra) with 2 second minimum wait timers for
beta and alpha to ensure they are seen. A 5-second safety timer was
added to ensure the splash screen can always be passed even if something
goes wrong at the domain level (since there are now quite a few moving
pieces to determine the user's current onboarding state).
* Add build tests for the new beta & GA flavors.
* Add Kenya study-specific alpha build flavor.
This new build flavor automatically enables the study-specific learner
study feature flag.
* Future-proof metrics infrastructure.
This is mainly done by:
1. Logging an immutable event type for each event and de-coupling the
event names so that the latter can be changed over time to improve event
management quality-of-life.
2. Logging the Android SDK version, app version name, and app version
code with each event.
3. Ensuring the existing Kenya-specific alpha versions of the app
continue to use their existing event names so that historical data can
be matched (since those queries rely on event names rather than this new
event type).
* Fix broken test per earlier changes.
* Fix general broken tests & builds.
Tests broken due to changes to the app startup experience haven't yet
been fixed.
* Lint fixes.
* First part of adding tests for GA notices.
There's a bunch left to do here, this is mainly needed so that I can
transfer changes to a different machine.
* Update TransformAndroidManifestTest.kt
Correct typos.
* Fix tests & static checks.
This also removes temporary debug code and TODOs, and finishes the tests
for SplashActivity.
* Fix & add testing.
* Static check fixes + missing tests.
* Post-merge fixes.
* Test fixes.
* Fix failing tests.
* Fix Gradle test.
* Post-merge fixes.
* Follow-up adjustments after self-review.
---
app/BUILD.bazel | 1 +
.../alpha/AlphaApplicationComponent.kt | 4 +-
.../android/app/application/alpha/BUILD.bazel | 1 +
.../AlphaKenyaApplicationComponent.kt | 4 +-
.../app/application/alphakenya/BUILD.bazel | 1 +
.../android/app/application/beta/BUILD.bazel | 1 +
.../beta/BetaApplicationComponent.kt | 4 +-
.../android/app/application/dev/BUILD.bazel | 1 +
.../dev/DeveloperApplicationComponent.kt | 3 +-
.../android/app/application/ga/BUILD.bazel | 1 +
.../application/ga/GaApplicationComponent.kt | 4 +-
.../AdministratorControlsActivityTest.kt | 4 +-
.../AdministratorControlsFragmentTest.kt | 4 +-
.../AppVersionActivityTest.kt | 4 +-
.../learneranalytics/BUILD.bazel | 2 +
.../ProfileAndDeviceIdActivityTest.kt | 3 +-
.../ProfileAndDeviceIdFragmentTest.kt | 3 +-
.../CompletedStoryListActivityTest.kt | 4 +-
.../LessonThumbnailImageViewTest.kt | 4 +-
.../app/customview/interaction/BUILD.bazel | 1 +
.../MathExpressionInteractionsViewTest.kt | 4 +-
.../oppia/android/app/databinding/BUILD.bazel | 7 +
.../DrawableBindingAdaptersTest.kt | 4 +-
.../ImageViewBindingAdaptersTest.kt | 4 +-
.../databinding/MarginBindingAdaptersTest.kt | 4 +-
...StateAssemblerMarginBindingAdaptersTest.kt | 4 +-
...tateAssemblerPaddingBindingAdaptersTest.kt | 4 +-
.../TextViewBindingAdaptersTest.kt | 4 +-
.../databinding/ViewBindingAdaptersTest.kt | 4 +-
.../DeveloperOptionsActivityTest.kt | 4 +-
.../DeveloperOptionsFragmentTest.kt | 4 +-
.../MarkChaptersCompletedActivityTest.kt | 4 +-
.../MarkChaptersCompletedFragmentTest.kt | 4 +-
.../MarkStoriesCompletedActivityTest.kt | 4 +-
.../MarkStoriesCompletedFragmentTest.kt | 4 +-
.../MarkTopicsCompletedActivityTest.kt | 4 +-
.../MarkTopicsCompletedFragmentTest.kt | 4 +-
.../devoptions/ViewEventLogsActivityTest.kt | 3 +-
.../devoptions/ViewEventLogsFragmentTest.kt | 4 +-
.../ForceNetworkTypeActivityTest.kt | 4 +-
.../ForceNetworkTypeFragmentTest.kt | 4 +-
.../mathexpressionparser/BUILD.bazel | 2 +
.../MathExpressionParserActivityTest.kt | 4 +-
.../MathExpressionParserFragmentTest.kt | 4 +-
.../android/app/faq/FAQListFragmentTest.kt | 4 +-
.../android/app/faq/FAQSingleActivityTest.kt | 4 +-
.../android/app/faq/FaqListActivityTest.kt | 4 +-
.../android/app/help/HelpActivityTest.kt | 4 +-
.../android/app/help/HelpFragmentTest.kt | 4 +-
.../android/app/home/HomeActivityTest.kt | 4 +-
.../app/home/RecentlyPlayedFragmentTest.kt | 4 +-
.../app/home/TopicSummaryViewModelTest.kt | 4 +-
.../android/app/home/WelcomeViewModelTest.kt | 4 +-
.../PromotedStoryListViewModelTest.kt | 4 +-
.../PromotedStoryViewModelTest.kt | 4 +-
.../mydownloads/MyDownloadsActivityTest.kt | 4 +-
.../mydownloads/MyDownloadsFragmentTest.kt | 4 +-
.../org/oppia/android/app/notice/BUILD.bazel | 2 +
.../notice/BetaNoticeDialogFragmentTest.kt | 4 +-
...labilityUpgradeNoticeDialogFragmentTest.kt | 4 +-
.../app/onboarding/OnboardingActivityTest.kt | 4 +-
.../app/onboarding/OnboardingFragmentTest.kt | 4 +-
.../OngoingTopicListActivityTest.kt | 4 +-
.../app/options/AppLanguageActivityTest.kt | 4 +-
.../app/options/AppLanguageFragmentTest.kt | 4 +-
.../app/options/AudioLanguageActivityTest.kt | 4 +-
.../app/options/AudioLanguageFragmentTest.kt | 4 +-
.../app/options/OptionsActivityTest.kt | 4 +-
.../app/options/OptionsFragmentTest.kt | 4 +-
.../options/ReadingTextSizeActivityTest.kt | 4 +-
.../options/ReadingTextSizeFragmentTest.kt | 4 +-
.../android/app/parser/HtmlParserTest.kt | 4 +-
.../app/player/audio/AudioFragmentTest.kt | 4 +-
.../exploration/ExplorationActivityTest.kt | 4 +-
.../android/app/player/state/BUILD.bazel | 1 +
.../app/player/state/StateFragmentTest.kt | 4 +-
.../app/policies/PoliciesActivityTest.kt | 4 +-
.../app/policies/PoliciesFragmentTest.kt | 4 +-
.../app/profile/AddProfileActivityTest.kt | 4 +-
.../app/profile/AdminAuthActivityTest.kt | 4 +-
.../app/profile/AdminPinActivityTest.kt | 4 +-
.../app/profile/PinPasswordActivityTest.kt | 4 +-
.../app/profile/ProfileChooserFragmentTest.kt | 4 +-
.../ProfilePictureActivityTest.kt | 4 +-
.../ProfileProgressActivityTest.kt | 4 +-
.../ProfileProgressFragmentTest.kt | 4 +-
.../app/recyclerview/BindableAdapterTest.kt | 4 +-
.../resumelesson/ResumeLessonActivityTest.kt | 4 +-
.../resumelesson/ResumeLessonFragmentTest.kt | 4 +-
.../profile/ProfileEditActivityTest.kt | 4 +-
.../profile/ProfileEditFragmentTest.kt | 4 +-
.../profile/ProfileListActivityTest.kt | 4 +-
.../profile/ProfileListFragmentTest.kt | 4 +-
.../profile/ProfileRenameActivityTest.kt | 4 +-
.../profile/ProfileRenameFragmentTest.kt | 4 +-
.../profile/ProfileResetPinActivityTest.kt | 4 +-
.../profile/ProfileResetPinFragmentTest.kt | 4 +-
.../org/oppia/android/app/splash/BUILD.bazel | 1 +
.../android/app/splash/SplashActivityTest.kt | 4 +-
.../android/app/story/StoryActivityTest.kt | 4 +-
.../android/app/story/StoryFragmentTest.kt | 4 +-
.../app/testing/DragDropTestActivityTest.kt | 4 +-
...ImageRegionSelectionInteractionViewTest.kt | 4 +-
.../InputInteractionViewTestActivityTest.kt | 4 +-
.../NavigationDrawerActivityDebugTest.kt | 4 +-
.../NavigationDrawerActivityProdTest.kt | 4 +-
...tFontScaleConfigurationUtilActivityTest.kt | 4 +-
.../testing/TopicTestActivityForStoryTest.kt | 4 +-
.../app/thirdparty/LicenseListActivityTest.kt | 4 +-
.../app/thirdparty/LicenseListFragmentTest.kt | 4 +-
.../LicenseTextViewerActivityTest.kt | 4 +-
.../LicenseTextViewerFragmentTest.kt | 4 +-
.../ThirdPartyDependencyListActivityTest.kt | 4 +-
.../ThirdPartyDependencyListFragmentTest.kt | 4 +-
.../android/app/topic/TopicActivityTest.kt | 4 +-
.../android/app/topic/TopicFragmentTest.kt | 4 +-
.../conceptcard/ConceptCardFragmentTest.kt | 4 +-
.../app/topic/info/TopicInfoFragmentTest.kt | 4 +-
.../topic/lessons/TopicLessonsFragmentTest.kt | 4 +-
.../practice/TopicPracticeFragmentTest.kt | 4 +-
.../QuestionPlayerActivityTest.kt | 4 +-
.../revision/TopicRevisionFragmentTest.kt | 4 +-
.../revisioncard/RevisionCardActivityTest.kt | 4 +-
.../revisioncard/RevisionCardFragmentTest.kt | 4 +-
.../app/utility/RatioExtensionsTest.kt | 4 +-
.../walkthrough/WalkthroughActivityTest.kt | 4 +-
.../WalkthroughFinalFragmentTest.kt | 4 +-
.../WalkthroughTopicListFragmentTest.kt | 4 +-
.../WalkthroughWelcomeFragmentTest.kt | 4 +-
.../activity/ActivityIntentFactoriesTest.kt | 4 +-
.../oppia/android/app/activity/BUILD.bazel | 1 +
.../android/app/home/HomeActivityLocalTest.kt | 4 +-
.../app/parser/FractionParsingUiErrorTest.kt | 4 +-
.../parser/ListItemLeadingMarginSpanTest.kt | 4 +-
.../app/parser/StringToRatioParserTest.kt | 4 +-
.../ExplorationActivityLocalTest.kt | 4 +-
.../player/state/StateFragmentLocalTest.kt | 4 +-
.../ProfileChooserFragmentLocalTest.kt | 4 +-
.../app/story/StoryActivityLocalTest.kt | 4 +-
.../app/testing/CompletedStoryListSpanTest.kt | 4 +-
.../oppia/android/app/testing/HomeSpanTest.kt | 4 +-
.../app/testing/OngoingTopicListSpanTest.kt | 4 +-
.../PlatformParameterIntegrationTest.kt | 4 +-
.../app/testing/ProfileChooserSpanTest.kt | 4 +-
.../testing/ProfileProgressSpanCountTest.kt | 4 +-
.../app/testing/RecentlyPlayedSpanTest.kt | 4 +-
.../app/testing/TopicRevisionSpanTest.kt | 4 +-
.../android/app/testing/activity/BUILD.bazel | 1 +
.../app/testing/activity/TestActivityTest.kt | 4 +-
.../AdministratorControlsFragmentTest.kt | 4 +-
.../testing/options/OptionsFragmentTest.kt | 4 +-
.../player/split/PlayerSplitScreenTest.kt | 4 +-
.../state/StateFragmentAccessibilityTest.kt | 4 +-
.../topic/info/TopicInfoFragmentLocalTest.kt | 4 +-
.../lessons/TopicLessonsFragmentLocalTest.kt | 4 +-
.../QuestionPlayerActivityLocalTest.kt | 4 +-
.../RevisionCardActivityLocalTest.kt | 4 +-
.../AppLanguageResourceHandlerTest.kt | 4 +-
.../AppLanguageWatcherMixinTest.kt | 4 +-
.../oppia/android/app/translation/BUILD.bazel | 2 +
.../app/utility/datetime/DateTimeUtilTest.kt | 4 +-
.../android/app/utility/math/BUILD.bazel | 1 +
.../MathExpressionAccessibilityUtilTest.kt | 4 +-
.../instrumentation/application/BUILD.bazel | 1 +
.../application/TestApplicationComponent.kt | 3 +-
scripts/assets/test_file_exemptions.textproto | 2 +
.../oppia/android/testing/junit/BUILD.bazel | 3 +
...alizeDefaultLocaleRuleCustomContextTest.kt | 4 +-
...InitializeDefaultLocaleRuleOmissionTest.kt | 4 +-
.../junit/InitializeDefaultLocaleRuleTest.kt | 4 +-
.../oppia/android/util/logging/BUILD.bazel | 38 +
.../util/logging/EventBundleCreator.kt | 89 +-
.../EventLoggingConfigurationModule.kt | 13 +
.../EventTypeToHumanReadableNameConverter.kt | 21 +
...nyaAlphaEventLoggingConfigurationModule.kt | 16 +
...entTypeToHumanReadableNameConverterImpl.kt | 48 +
...entTypeToHumanReadableNameConverterImpl.kt | 58 +
.../logging/performancemetrics/BUILD.bazel | 2 +-
.../oppia/android/util/logging/BUILD.bazel | 122 ++
.../util/logging/EventBundleCreatorTest.kt | 428 +++--
.../EventLoggingConfigurationModuleTest.kt | 70 +
.../KenyaAlphaEventBundleCreatorTest.kt | 1445 +++++++++++++++++
...lphaEventLoggingConfigurationModuleTest.kt | 70 +
...ypeToHumanReadableNameConverterImplTest.kt | 117 ++
.../android/util/logging/firebase/BUILD.bazel | 32 +
.../firebase/LogReportingModuleTest.kt | 4 +-
.../logging/performancemetrics/BUILD.bazel | 80 +
187 files changed, 2994 insertions(+), 287 deletions(-)
create mode 100644 utility/src/main/java/org/oppia/android/util/logging/EventLoggingConfigurationModule.kt
create mode 100644 utility/src/main/java/org/oppia/android/util/logging/EventTypeToHumanReadableNameConverter.kt
create mode 100644 utility/src/main/java/org/oppia/android/util/logging/KenyaAlphaEventLoggingConfigurationModule.kt
create mode 100644 utility/src/main/java/org/oppia/android/util/logging/KenyaAlphaEventTypeToHumanReadableNameConverterImpl.kt
create mode 100644 utility/src/main/java/org/oppia/android/util/logging/StandardEventTypeToHumanReadableNameConverterImpl.kt
create mode 100644 utility/src/test/java/org/oppia/android/util/logging/BUILD.bazel
create mode 100644 utility/src/test/java/org/oppia/android/util/logging/EventLoggingConfigurationModuleTest.kt
create mode 100644 utility/src/test/java/org/oppia/android/util/logging/KenyaAlphaEventBundleCreatorTest.kt
create mode 100644 utility/src/test/java/org/oppia/android/util/logging/KenyaAlphaEventLoggingConfigurationModuleTest.kt
create mode 100644 utility/src/test/java/org/oppia/android/util/logging/StandardEventTypeToHumanReadableNameConverterImplTest.kt
create mode 100644 utility/src/test/java/org/oppia/android/util/logging/firebase/BUILD.bazel
create mode 100644 utility/src/test/java/org/oppia/android/util/logging/performancemetrics/BUILD.bazel
diff --git a/app/BUILD.bazel b/app/BUILD.bazel
index d20fc5793ea..9389c372c45 100644
--- a/app/BUILD.bazel
+++ b/app/BUILD.bazel
@@ -892,6 +892,7 @@ TEST_DEPS = [
"//utility/src/main/java/org/oppia/android/util/accessibility:test_module",
"//utility/src/main/java/org/oppia/android/util/caching:asset_prod_module",
"//utility/src/main/java/org/oppia/android/util/caching/testing:caching_test_module",
+ "//utility/src/main/java/org/oppia/android/util/logging:standard_event_logging_configuration_module",
"//utility/src/main/java/org/oppia/android/util/logging/firebase:debug_module",
"//utility/src/main/java/org/oppia/android/util/math:math_expression_parser",
"//utility/src/main/java/org/oppia/android/util/networking:debug_module",
diff --git a/app/src/main/java/org/oppia/android/app/application/alpha/AlphaApplicationComponent.kt b/app/src/main/java/org/oppia/android/app/application/alpha/AlphaApplicationComponent.kt
index 3f7643dfbb1..c7cfb35dafa 100644
--- a/app/src/main/java/org/oppia/android/app/application/alpha/AlphaApplicationComponent.kt
+++ b/app/src/main/java/org/oppia/android/app/application/alpha/AlphaApplicationComponent.kt
@@ -48,6 +48,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.CachingModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -95,7 +96,8 @@ import javax.inject.Singleton
SyncStatusModule::class, LogReportingModule::class, NetworkConnectionUtilProdModule::class,
HintsAndSolutionProdModule::class, MetricLogSchedulerModule::class,
PerformanceMetricsLoggerModule::class, PerformanceMetricsAssessorModule::class,
- PerformanceMetricsConfigurationsModule::class, AlphaBuildFlavorModule::class
+ PerformanceMetricsConfigurationsModule::class, AlphaBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface AlphaApplicationComponent : ApplicationComponent {
diff --git a/app/src/main/java/org/oppia/android/app/application/alpha/BUILD.bazel b/app/src/main/java/org/oppia/android/app/application/alpha/BUILD.bazel
index b5514bee52f..9c410695450 100644
--- a/app/src/main/java/org/oppia/android/app/application/alpha/BUILD.bazel
+++ b/app/src/main/java/org/oppia/android/app/application/alpha/BUILD.bazel
@@ -19,6 +19,7 @@ kt_android_library(
"//app/src/main/java/org/oppia/android/app/application:abstract_application",
"//app/src/main/java/org/oppia/android/app/application:application_component",
"//app/src/main/java/org/oppia/android/app/application:common_application_modules",
+ "//utility/src/main/java/org/oppia/android/util/logging:standard_event_logging_configuration_module",
"//utility/src/main/java/org/oppia/android/util/logging/firebase:prod_module",
"//utility/src/main/java/org/oppia/android/util/networking:prod_module",
],
diff --git a/app/src/main/java/org/oppia/android/app/application/alphakenya/AlphaKenyaApplicationComponent.kt b/app/src/main/java/org/oppia/android/app/application/alphakenya/AlphaKenyaApplicationComponent.kt
index d66d01a719f..c63a9773e50 100644
--- a/app/src/main/java/org/oppia/android/app/application/alphakenya/AlphaKenyaApplicationComponent.kt
+++ b/app/src/main/java/org/oppia/android/app/application/alphakenya/AlphaKenyaApplicationComponent.kt
@@ -49,6 +49,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.CachingModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.KenyaAlphaEventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -96,7 +97,8 @@ import javax.inject.Singleton
SyncStatusModule::class, LogReportingModule::class, NetworkConnectionUtilProdModule::class,
HintsAndSolutionProdModule::class, MetricLogSchedulerModule::class,
PerformanceMetricsLoggerModule::class, PerformanceMetricsAssessorModule::class,
- PerformanceMetricsConfigurationsModule::class, AlphaBuildFlavorModule::class
+ PerformanceMetricsConfigurationsModule::class, AlphaBuildFlavorModule::class,
+ KenyaAlphaEventLoggingConfigurationModule::class
]
)
interface AlphaKenyaApplicationComponent : ApplicationComponent {
diff --git a/app/src/main/java/org/oppia/android/app/application/alphakenya/BUILD.bazel b/app/src/main/java/org/oppia/android/app/application/alphakenya/BUILD.bazel
index f27362050ba..538d47308dc 100644
--- a/app/src/main/java/org/oppia/android/app/application/alphakenya/BUILD.bazel
+++ b/app/src/main/java/org/oppia/android/app/application/alphakenya/BUILD.bazel
@@ -20,6 +20,7 @@ kt_android_library(
"//app/src/main/java/org/oppia/android/app/application:application_component",
"//app/src/main/java/org/oppia/android/app/application:common_application_modules",
"//app/src/main/java/org/oppia/android/app/application/alpha:alpha_build_flavor_module",
+ "//utility/src/main/java/org/oppia/android/util/logging:kenya_alpha_event_logging_configuration_module",
"//utility/src/main/java/org/oppia/android/util/logging/firebase:prod_module",
"//utility/src/main/java/org/oppia/android/util/networking:prod_module",
],
diff --git a/app/src/main/java/org/oppia/android/app/application/beta/BUILD.bazel b/app/src/main/java/org/oppia/android/app/application/beta/BUILD.bazel
index cd268f76005..db532533d41 100644
--- a/app/src/main/java/org/oppia/android/app/application/beta/BUILD.bazel
+++ b/app/src/main/java/org/oppia/android/app/application/beta/BUILD.bazel
@@ -22,6 +22,7 @@ kt_android_library(
"//app/src/main/java/org/oppia/android/app/application:abstract_application",
"//app/src/main/java/org/oppia/android/app/application:application_component",
"//app/src/main/java/org/oppia/android/app/application:common_application_modules",
+ "//utility/src/main/java/org/oppia/android/util/logging:standard_event_logging_configuration_module",
"//utility/src/main/java/org/oppia/android/util/logging/firebase:prod_module",
"//utility/src/main/java/org/oppia/android/util/networking:prod_module",
],
diff --git a/app/src/main/java/org/oppia/android/app/application/beta/BetaApplicationComponent.kt b/app/src/main/java/org/oppia/android/app/application/beta/BetaApplicationComponent.kt
index b772edd8689..6b9b7a626b1 100644
--- a/app/src/main/java/org/oppia/android/app/application/beta/BetaApplicationComponent.kt
+++ b/app/src/main/java/org/oppia/android/app/application/beta/BetaApplicationComponent.kt
@@ -48,6 +48,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.CachingModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -95,7 +96,8 @@ import javax.inject.Singleton
SyncStatusModule::class, LogReportingModule::class, NetworkConnectionUtilProdModule::class,
HintsAndSolutionProdModule::class, MetricLogSchedulerModule::class,
PerformanceMetricsLoggerModule::class, PerformanceMetricsAssessorModule::class,
- PerformanceMetricsConfigurationsModule::class, BetaBuildFlavorModule::class
+ PerformanceMetricsConfigurationsModule::class, BetaBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface BetaApplicationComponent : ApplicationComponent {
diff --git a/app/src/main/java/org/oppia/android/app/application/dev/BUILD.bazel b/app/src/main/java/org/oppia/android/app/application/dev/BUILD.bazel
index b0de24922b6..53841df1c37 100644
--- a/app/src/main/java/org/oppia/android/app/application/dev/BUILD.bazel
+++ b/app/src/main/java/org/oppia/android/app/application/dev/BUILD.bazel
@@ -26,6 +26,7 @@ kt_android_library(
"//app/src/main/java/org/oppia/android/app/application:abstract_application",
"//app/src/main/java/org/oppia/android/app/application:application_component",
"//app/src/main/java/org/oppia/android/app/application:common_application_modules",
+ "//utility/src/main/java/org/oppia/android/util/logging:standard_event_logging_configuration_module",
"//utility/src/main/java/org/oppia/android/util/logging/firebase:debug_module",
"//utility/src/main/java/org/oppia/android/util/networking:debug_module",
],
diff --git a/app/src/main/java/org/oppia/android/app/application/dev/DeveloperApplicationComponent.kt b/app/src/main/java/org/oppia/android/app/application/dev/DeveloperApplicationComponent.kt
index 917186a0628..b1a827847d7 100644
--- a/app/src/main/java/org/oppia/android/app/application/dev/DeveloperApplicationComponent.kt
+++ b/app/src/main/java/org/oppia/android/app/application/dev/DeveloperApplicationComponent.kt
@@ -49,6 +49,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.CachingModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.DebugLogReportingModule
@@ -97,7 +98,7 @@ import javax.inject.Singleton
NetworkConnectionDebugUtilModule::class, LoggingIdentifierModule::class,
SyncStatusModule::class, MetricLogSchedulerModule::class, PerformanceMetricsLoggerModule::class,
PerformanceMetricsAssessorModule::class, PerformanceMetricsConfigurationsModule::class,
- DeveloperBuildFlavorModule::class
+ DeveloperBuildFlavorModule::class, EventLoggingConfigurationModule::class
]
)
interface DeveloperApplicationComponent : ApplicationComponent {
diff --git a/app/src/main/java/org/oppia/android/app/application/ga/BUILD.bazel b/app/src/main/java/org/oppia/android/app/application/ga/BUILD.bazel
index 009ce4b8328..5421f374f20 100644
--- a/app/src/main/java/org/oppia/android/app/application/ga/BUILD.bazel
+++ b/app/src/main/java/org/oppia/android/app/application/ga/BUILD.bazel
@@ -22,6 +22,7 @@ kt_android_library(
"//app/src/main/java/org/oppia/android/app/application:abstract_application",
"//app/src/main/java/org/oppia/android/app/application:application_component",
"//app/src/main/java/org/oppia/android/app/application:common_application_modules",
+ "//utility/src/main/java/org/oppia/android/util/logging:standard_event_logging_configuration_module",
"//utility/src/main/java/org/oppia/android/util/logging/firebase:prod_module",
"//utility/src/main/java/org/oppia/android/util/networking:prod_module",
],
diff --git a/app/src/main/java/org/oppia/android/app/application/ga/GaApplicationComponent.kt b/app/src/main/java/org/oppia/android/app/application/ga/GaApplicationComponent.kt
index d9eb173fb4f..23d4cbad398 100644
--- a/app/src/main/java/org/oppia/android/app/application/ga/GaApplicationComponent.kt
+++ b/app/src/main/java/org/oppia/android/app/application/ga/GaApplicationComponent.kt
@@ -48,6 +48,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.CachingModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -95,7 +96,8 @@ import javax.inject.Singleton
SyncStatusModule::class, LogReportingModule::class, NetworkConnectionUtilProdModule::class,
HintsAndSolutionProdModule::class, MetricLogSchedulerModule::class,
PerformanceMetricsLoggerModule::class, PerformanceMetricsAssessorModule::class,
- PerformanceMetricsConfigurationsModule::class, GaBuildFlavorModule::class
+ PerformanceMetricsConfigurationsModule::class, GaBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface GaApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/AdministratorControlsActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/AdministratorControlsActivityTest.kt
index 80fbbbbf0ec..ac2d7596a29 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/AdministratorControlsActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/AdministratorControlsActivityTest.kt
@@ -110,6 +110,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -836,7 +837,8 @@ class AdministratorControlsActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/AdministratorControlsFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/AdministratorControlsFragmentTest.kt
index 95ee91fd9ef..b308811bbbf 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/AdministratorControlsFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/AdministratorControlsFragmentTest.kt
@@ -101,6 +101,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -614,7 +615,8 @@ class AdministratorControlsFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/AppVersionActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/AppVersionActivityTest.kt
index ea6982c549f..92ee676da4b 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/AppVersionActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/AppVersionActivityTest.kt
@@ -89,6 +89,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -292,7 +293,8 @@ class AppVersionActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/learneranalytics/BUILD.bazel b/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/learneranalytics/BUILD.bazel
index b64b7f60e82..b9345fe116f 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/learneranalytics/BUILD.bazel
+++ b/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/learneranalytics/BUILD.bazel
@@ -29,6 +29,7 @@ app_test(
"//utility/src/main/java/org/oppia/android/util/accessibility:test_module",
"//utility/src/main/java/org/oppia/android/util/caching/testing:caching_test_module",
"//utility/src/main/java/org/oppia/android/util/logging:prod_module",
+ "//utility/src/main/java/org/oppia/android/util/logging:standard_event_logging_configuration_module",
"//utility/src/main/java/org/oppia/android/util/logging/firebase:debug_module",
"//utility/src/main/java/org/oppia/android/util/networking:debug_module",
],
@@ -62,6 +63,7 @@ app_test(
"//utility/src/main/java/org/oppia/android/util/accessibility:test_module",
"//utility/src/main/java/org/oppia/android/util/caching/testing:caching_test_module",
"//utility/src/main/java/org/oppia/android/util/logging:prod_module",
+ "//utility/src/main/java/org/oppia/android/util/logging:standard_event_logging_configuration_module",
"//utility/src/main/java/org/oppia/android/util/logging/firebase:debug_module",
"//utility/src/main/java/org/oppia/android/util/networking:debug_module",
],
diff --git a/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/learneranalytics/ProfileAndDeviceIdActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/learneranalytics/ProfileAndDeviceIdActivityTest.kt
index 37fbe33d836..f68224e7c96 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/learneranalytics/ProfileAndDeviceIdActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/learneranalytics/ProfileAndDeviceIdActivityTest.kt
@@ -80,6 +80,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusManager
import org.oppia.android.util.logging.SyncStatusModule
@@ -201,7 +202,7 @@ class ProfileAndDeviceIdActivityTest {
SyncStatusModule::class, SplitScreenInteractionModule::class,
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, MetricLogSchedulerModule::class,
- TestingBuildFlavorModule::class
+ TestingBuildFlavorModule::class, EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/learneranalytics/ProfileAndDeviceIdFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/learneranalytics/ProfileAndDeviceIdFragmentTest.kt
index 4f5b16a23e1..bed9db1657c 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/learneranalytics/ProfileAndDeviceIdFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/learneranalytics/ProfileAndDeviceIdFragmentTest.kt
@@ -99,6 +99,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusManager
import org.oppia.android.util.logging.SyncStatusModule
@@ -627,7 +628,7 @@ class ProfileAndDeviceIdFragmentTest {
SyncStatusModule::class, SplitScreenInteractionModule::class,
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, MetricLogSchedulerModule::class,
- TestingBuildFlavorModule::class
+ TestingBuildFlavorModule::class, EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/completedstorylist/CompletedStoryListActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/completedstorylist/CompletedStoryListActivityTest.kt
index f50c687c987..28be6b5abca 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/completedstorylist/CompletedStoryListActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/completedstorylist/CompletedStoryListActivityTest.kt
@@ -94,6 +94,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -515,7 +516,8 @@ class CompletedStoryListActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/customview/LessonThumbnailImageViewTest.kt b/app/src/sharedTest/java/org/oppia/android/app/customview/LessonThumbnailImageViewTest.kt
index c4082c8733a..cb048b59af8 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/customview/LessonThumbnailImageViewTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/customview/LessonThumbnailImageViewTest.kt
@@ -73,6 +73,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -173,7 +174,8 @@ class LessonThumbnailImageViewTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/customview/interaction/BUILD.bazel b/app/src/sharedTest/java/org/oppia/android/app/customview/interaction/BUILD.bazel
index 37a21163500..16a33d5d0ea 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/customview/interaction/BUILD.bazel
+++ b/app/src/sharedTest/java/org/oppia/android/app/customview/interaction/BUILD.bazel
@@ -35,6 +35,7 @@ app_test(
"//third_party:robolectric_android-all",
"//utility/src/main/java/org/oppia/android/util/accessibility:test_module",
"//utility/src/main/java/org/oppia/android/util/caching/testing:caching_test_module",
+ "//utility/src/main/java/org/oppia/android/util/logging:standard_event_logging_configuration_module",
"//utility/src/main/java/org/oppia/android/util/logging/firebase:debug_module",
"//utility/src/main/java/org/oppia/android/util/networking:debug_module",
],
diff --git a/app/src/sharedTest/java/org/oppia/android/app/customview/interaction/MathExpressionInteractionsViewTest.kt b/app/src/sharedTest/java/org/oppia/android/app/customview/interaction/MathExpressionInteractionsViewTest.kt
index f5a54d6e7d1..31b7cef50c2 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/customview/interaction/MathExpressionInteractionsViewTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/customview/interaction/MathExpressionInteractionsViewTest.kt
@@ -94,6 +94,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -1775,7 +1776,8 @@ class MathExpressionInteractionsViewTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/databinding/BUILD.bazel b/app/src/sharedTest/java/org/oppia/android/app/databinding/BUILD.bazel
index 019f1ff1983..cf3ebcd513d 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/databinding/BUILD.bazel
+++ b/app/src/sharedTest/java/org/oppia/android/app/databinding/BUILD.bazel
@@ -94,6 +94,7 @@ oppia_android_test(
"//utility/src/main/java/org/oppia/android/util/caching/testing:caching_test_module",
"//utility/src/main/java/org/oppia/android/util/data:data_providers",
"//utility/src/main/java/org/oppia/android/util/logging:prod_module",
+ "//utility/src/main/java/org/oppia/android/util/logging:standard_event_logging_configuration_module",
"//utility/src/main/java/org/oppia/android/util/logging/firebase:debug_module",
"//utility/src/main/java/org/oppia/android/util/networking:debug_module",
],
@@ -131,6 +132,7 @@ oppia_android_test(
"//utility/src/main/java/org/oppia/android/util/caching/testing:caching_test_module",
"//utility/src/main/java/org/oppia/android/util/data:data_providers",
"//utility/src/main/java/org/oppia/android/util/logging:prod_module",
+ "//utility/src/main/java/org/oppia/android/util/logging:standard_event_logging_configuration_module",
"//utility/src/main/java/org/oppia/android/util/logging/firebase:debug_module",
"//utility/src/main/java/org/oppia/android/util/networking:debug_module",
],
@@ -168,6 +170,7 @@ oppia_android_test(
"//utility/src/main/java/org/oppia/android/util/caching/testing:caching_test_module",
"//utility/src/main/java/org/oppia/android/util/data:data_providers",
"//utility/src/main/java/org/oppia/android/util/logging:prod_module",
+ "//utility/src/main/java/org/oppia/android/util/logging:standard_event_logging_configuration_module",
"//utility/src/main/java/org/oppia/android/util/logging/firebase:debug_module",
"//utility/src/main/java/org/oppia/android/util/networking:debug_module",
],
@@ -205,6 +208,7 @@ oppia_android_test(
"//utility/src/main/java/org/oppia/android/util/caching/testing:caching_test_module",
"//utility/src/main/java/org/oppia/android/util/data:data_providers",
"//utility/src/main/java/org/oppia/android/util/logging:prod_module",
+ "//utility/src/main/java/org/oppia/android/util/logging:standard_event_logging_configuration_module",
"//utility/src/main/java/org/oppia/android/util/logging/firebase:debug_module",
"//utility/src/main/java/org/oppia/android/util/networking:debug_module",
],
@@ -242,6 +246,7 @@ oppia_android_test(
"//utility/src/main/java/org/oppia/android/util/caching/testing:caching_test_module",
"//utility/src/main/java/org/oppia/android/util/data:data_providers",
"//utility/src/main/java/org/oppia/android/util/logging:prod_module",
+ "//utility/src/main/java/org/oppia/android/util/logging:standard_event_logging_configuration_module",
"//utility/src/main/java/org/oppia/android/util/logging/firebase:debug_module",
"//utility/src/main/java/org/oppia/android/util/networking:debug_module",
],
@@ -279,6 +284,7 @@ oppia_android_test(
"//utility/src/main/java/org/oppia/android/util/caching/testing:caching_test_module",
"//utility/src/main/java/org/oppia/android/util/data:data_providers",
"//utility/src/main/java/org/oppia/android/util/logging:prod_module",
+ "//utility/src/main/java/org/oppia/android/util/logging:standard_event_logging_configuration_module",
"//utility/src/main/java/org/oppia/android/util/logging/firebase:debug_module",
"//utility/src/main/java/org/oppia/android/util/networking:debug_module",
],
@@ -316,6 +322,7 @@ oppia_android_test(
"//utility/src/main/java/org/oppia/android/util/caching/testing:caching_test_module",
"//utility/src/main/java/org/oppia/android/util/data:data_providers",
"//utility/src/main/java/org/oppia/android/util/logging:prod_module",
+ "//utility/src/main/java/org/oppia/android/util/logging:standard_event_logging_configuration_module",
"//utility/src/main/java/org/oppia/android/util/logging/firebase:debug_module",
"//utility/src/main/java/org/oppia/android/util/networking:debug_module",
],
diff --git a/app/src/sharedTest/java/org/oppia/android/app/databinding/DrawableBindingAdaptersTest.kt b/app/src/sharedTest/java/org/oppia/android/app/databinding/DrawableBindingAdaptersTest.kt
index da2853a4422..c982728f9a2 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/databinding/DrawableBindingAdaptersTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/databinding/DrawableBindingAdaptersTest.kt
@@ -78,6 +78,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -184,7 +185,8 @@ class DrawableBindingAdaptersTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/databinding/ImageViewBindingAdaptersTest.kt b/app/src/sharedTest/java/org/oppia/android/app/databinding/ImageViewBindingAdaptersTest.kt
index fe003c940f8..8d396de4cca 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/databinding/ImageViewBindingAdaptersTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/databinding/ImageViewBindingAdaptersTest.kt
@@ -83,6 +83,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -226,7 +227,8 @@ class ImageViewBindingAdaptersTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class,
- MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
/** Create a TestApplicationComponent. */
diff --git a/app/src/sharedTest/java/org/oppia/android/app/databinding/MarginBindingAdaptersTest.kt b/app/src/sharedTest/java/org/oppia/android/app/databinding/MarginBindingAdaptersTest.kt
index 212323d5fdb..3e4464170c4 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/databinding/MarginBindingAdaptersTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/databinding/MarginBindingAdaptersTest.kt
@@ -84,6 +84,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -314,7 +315,8 @@ class MarginBindingAdaptersTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class,
- MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
/** Create a TestApplicationComponent. */
diff --git a/app/src/sharedTest/java/org/oppia/android/app/databinding/StateAssemblerMarginBindingAdaptersTest.kt b/app/src/sharedTest/java/org/oppia/android/app/databinding/StateAssemblerMarginBindingAdaptersTest.kt
index e9603c8d4c0..093c3cf46a5 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/databinding/StateAssemblerMarginBindingAdaptersTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/databinding/StateAssemblerMarginBindingAdaptersTest.kt
@@ -86,6 +86,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -502,7 +503,8 @@ class StateAssemblerMarginBindingAdaptersTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class,
- MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
/** Create a TestApplicationComponent. */
diff --git a/app/src/sharedTest/java/org/oppia/android/app/databinding/StateAssemblerPaddingBindingAdaptersTest.kt b/app/src/sharedTest/java/org/oppia/android/app/databinding/StateAssemblerPaddingBindingAdaptersTest.kt
index ce12765a684..9162498f4fc 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/databinding/StateAssemblerPaddingBindingAdaptersTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/databinding/StateAssemblerPaddingBindingAdaptersTest.kt
@@ -84,6 +84,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -500,7 +501,8 @@ class StateAssemblerPaddingBindingAdaptersTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class,
- MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
diff --git a/app/src/sharedTest/java/org/oppia/android/app/databinding/TextViewBindingAdaptersTest.kt b/app/src/sharedTest/java/org/oppia/android/app/databinding/TextViewBindingAdaptersTest.kt
index aff64f8daa1..a885e0f751b 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/databinding/TextViewBindingAdaptersTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/databinding/TextViewBindingAdaptersTest.kt
@@ -77,6 +77,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -333,7 +334,8 @@ class TextViewBindingAdaptersTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/databinding/ViewBindingAdaptersTest.kt b/app/src/sharedTest/java/org/oppia/android/app/databinding/ViewBindingAdaptersTest.kt
index 2275048ed95..03e97a159c3 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/databinding/ViewBindingAdaptersTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/databinding/ViewBindingAdaptersTest.kt
@@ -81,6 +81,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -234,7 +235,8 @@ class ViewBindingAdaptersTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class,
- MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
/** Create a TestApplicationComponent. */
diff --git a/app/src/sharedTest/java/org/oppia/android/app/devoptions/DeveloperOptionsActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/devoptions/DeveloperOptionsActivityTest.kt
index 78e2f796262..c9f64e1b9e8 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/devoptions/DeveloperOptionsActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/devoptions/DeveloperOptionsActivityTest.kt
@@ -99,6 +99,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -326,7 +327,8 @@ class DeveloperOptionsActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/devoptions/DeveloperOptionsFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/devoptions/DeveloperOptionsFragmentTest.kt
index b1e1c4215b4..242dd42140a 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/devoptions/DeveloperOptionsFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/devoptions/DeveloperOptionsFragmentTest.kt
@@ -96,6 +96,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -657,7 +658,8 @@ class DeveloperOptionsFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkChaptersCompletedActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkChaptersCompletedActivityTest.kt
index 932a971c13a..abf3682b94b 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkChaptersCompletedActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkChaptersCompletedActivityTest.kt
@@ -75,6 +75,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -188,7 +189,8 @@ class MarkChaptersCompletedActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkChaptersCompletedFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkChaptersCompletedFragmentTest.kt
index b2ba91623d0..0fa6c4ad037 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkChaptersCompletedFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkChaptersCompletedFragmentTest.kt
@@ -87,6 +87,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -916,7 +917,8 @@ class MarkChaptersCompletedFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkStoriesCompletedActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkStoriesCompletedActivityTest.kt
index 5978a29ce69..3bbdd8de946 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkStoriesCompletedActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkStoriesCompletedActivityTest.kt
@@ -75,6 +75,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -188,7 +189,8 @@ class MarkStoriesCompletedActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkStoriesCompletedFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkStoriesCompletedFragmentTest.kt
index e2ab546bb6b..1930bf670fa 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkStoriesCompletedFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkStoriesCompletedFragmentTest.kt
@@ -87,6 +87,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -593,7 +594,8 @@ class MarkStoriesCompletedFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkTopicsCompletedActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkTopicsCompletedActivityTest.kt
index 13a792f1c21..a74e5697c6f 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkTopicsCompletedActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkTopicsCompletedActivityTest.kt
@@ -75,6 +75,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -188,7 +189,8 @@ class MarkTopicsCompletedActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkTopicsCompletedFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkTopicsCompletedFragmentTest.kt
index a13f699941d..19958dadc77 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkTopicsCompletedFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/devoptions/MarkTopicsCompletedFragmentTest.kt
@@ -87,6 +87,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -563,7 +564,8 @@ class MarkTopicsCompletedFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/devoptions/ViewEventLogsActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/devoptions/ViewEventLogsActivityTest.kt
index d76f14aabf0..71a1cf80e9f 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/devoptions/ViewEventLogsActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/devoptions/ViewEventLogsActivityTest.kt
@@ -75,6 +75,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.DebugLogReportingModule
@@ -180,7 +181,7 @@ class ViewEventLogsActivityTest {
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
SyncStatusModule::class, MetricLogSchedulerModule::class,
PerformanceMetricsAssessorModule::class, PerformanceMetricsConfigurationsModule::class,
- TestingBuildFlavorModule::class
+ TestingBuildFlavorModule::class, EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/devoptions/ViewEventLogsFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/devoptions/ViewEventLogsFragmentTest.kt
index 907042b27ac..c2987019e3f 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/devoptions/ViewEventLogsFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/devoptions/ViewEventLogsFragmentTest.kt
@@ -82,6 +82,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.DebugLogReportingModule
@@ -579,7 +580,8 @@ class ViewEventLogsFragmentTest {
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class,
MetricLogSchedulerModule::class, PerformanceMetricsAssessorModule::class,
- PerformanceMetricsConfigurationsModule::class, TestingBuildFlavorModule::class
+ PerformanceMetricsConfigurationsModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
diff --git a/app/src/sharedTest/java/org/oppia/android/app/devoptions/forcenetworktype/ForceNetworkTypeActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/devoptions/forcenetworktype/ForceNetworkTypeActivityTest.kt
index 1acc5d39820..f65763c0508 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/devoptions/forcenetworktype/ForceNetworkTypeActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/devoptions/forcenetworktype/ForceNetworkTypeActivityTest.kt
@@ -76,6 +76,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -180,7 +181,8 @@ class ForceNetworkTypeActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class,
- MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
/** [ApplicationComponent] for [ForceNetworkTypeActivityTest]. */
diff --git a/app/src/sharedTest/java/org/oppia/android/app/devoptions/forcenetworktype/ForceNetworkTypeFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/devoptions/forcenetworktype/ForceNetworkTypeFragmentTest.kt
index 0b63f3edacb..82361b14b1d 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/devoptions/forcenetworktype/ForceNetworkTypeFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/devoptions/forcenetworktype/ForceNetworkTypeFragmentTest.kt
@@ -82,6 +82,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -396,7 +397,8 @@ class ForceNetworkTypeFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class,
- MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
/** [ApplicationComponent] for [ForceNetworkTypeFragmentTest]. */
diff --git a/app/src/sharedTest/java/org/oppia/android/app/devoptions/mathexpressionparser/BUILD.bazel b/app/src/sharedTest/java/org/oppia/android/app/devoptions/mathexpressionparser/BUILD.bazel
index e20913f64aa..1cf6d50f745 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/devoptions/mathexpressionparser/BUILD.bazel
+++ b/app/src/sharedTest/java/org/oppia/android/app/devoptions/mathexpressionparser/BUILD.bazel
@@ -32,6 +32,7 @@ app_test(
"//third_party:robolectric_android-all",
"//utility/src/main/java/org/oppia/android/util/accessibility:test_module",
"//utility/src/main/java/org/oppia/android/util/caching/testing:caching_test_module",
+ "//utility/src/main/java/org/oppia/android/util/logging:standard_event_logging_configuration_module",
"//utility/src/main/java/org/oppia/android/util/logging/firebase:debug_module",
"//utility/src/main/java/org/oppia/android/util/networking:debug_module",
],
@@ -64,6 +65,7 @@ app_test(
"//third_party:robolectric_android-all",
"//utility/src/main/java/org/oppia/android/util/accessibility:test_module",
"//utility/src/main/java/org/oppia/android/util/caching/testing:caching_test_module",
+ "//utility/src/main/java/org/oppia/android/util/logging:standard_event_logging_configuration_module",
"//utility/src/main/java/org/oppia/android/util/logging/firebase:debug_module",
"//utility/src/main/java/org/oppia/android/util/networking:debug_module",
],
diff --git a/app/src/sharedTest/java/org/oppia/android/app/devoptions/mathexpressionparser/MathExpressionParserActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/devoptions/mathexpressionparser/MathExpressionParserActivityTest.kt
index 6a207e03bd8..0c0528a3a28 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/devoptions/mathexpressionparser/MathExpressionParserActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/devoptions/mathexpressionparser/MathExpressionParserActivityTest.kt
@@ -73,6 +73,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -164,7 +165,8 @@ class MathExpressionParserActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/devoptions/mathexpressionparser/MathExpressionParserFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/devoptions/mathexpressionparser/MathExpressionParserFragmentTest.kt
index 4f3a4f62600..6e7c2bcfee7 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/devoptions/mathexpressionparser/MathExpressionParserFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/devoptions/mathexpressionparser/MathExpressionParserFragmentTest.kt
@@ -85,6 +85,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -1414,7 +1415,8 @@ class MathExpressionParserFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/faq/FAQListFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/faq/FAQListFragmentTest.kt
index 33fd5eeddb9..d86fc7136cd 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/faq/FAQListFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/faq/FAQListFragmentTest.kt
@@ -87,6 +87,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -248,7 +249,8 @@ class FAQListFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/faq/FAQSingleActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/faq/FAQSingleActivityTest.kt
index 1c354ef9c98..aeba89c61f9 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/faq/FAQSingleActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/faq/FAQSingleActivityTest.kt
@@ -83,6 +83,7 @@ import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.DefaultResourceBucketName
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -226,7 +227,8 @@ class FAQSingleActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/faq/FaqListActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/faq/FaqListActivityTest.kt
index a9238755789..64f747d0fa2 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/faq/FaqListActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/faq/FaqListActivityTest.kt
@@ -70,6 +70,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -153,7 +154,8 @@ class FaqListActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/help/HelpActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/help/HelpActivityTest.kt
index 69c195e66e7..26da7ebc470 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/help/HelpActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/help/HelpActivityTest.kt
@@ -69,6 +69,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -155,7 +156,8 @@ class HelpActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/help/HelpFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/help/HelpFragmentTest.kt
index 1c7cd066ce9..11750a32051 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/help/HelpFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/help/HelpFragmentTest.kt
@@ -103,6 +103,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -1443,7 +1444,8 @@ class HelpFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt
index b229732f377..eddebee5ab9 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/home/HomeActivityTest.kt
@@ -128,6 +128,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -1812,7 +1813,8 @@ class HomeActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/home/RecentlyPlayedFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/home/RecentlyPlayedFragmentTest.kt
index f086e9920d2..fc5a5ec42ee 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/home/RecentlyPlayedFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/home/RecentlyPlayedFragmentTest.kt
@@ -114,6 +114,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -1507,7 +1508,8 @@ class RecentlyPlayedFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/home/TopicSummaryViewModelTest.kt b/app/src/sharedTest/java/org/oppia/android/app/home/TopicSummaryViewModelTest.kt
index f910210e0ac..9ad394c060b 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/home/TopicSummaryViewModelTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/home/TopicSummaryViewModelTest.kt
@@ -71,6 +71,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -374,7 +375,8 @@ class TopicSummaryViewModelTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/home/WelcomeViewModelTest.kt b/app/src/sharedTest/java/org/oppia/android/app/home/WelcomeViewModelTest.kt
index 95c188b9600..c7e94d19070 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/home/WelcomeViewModelTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/home/WelcomeViewModelTest.kt
@@ -72,6 +72,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -358,7 +359,8 @@ class WelcomeViewModelTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/home/promotedlist/PromotedStoryListViewModelTest.kt b/app/src/sharedTest/java/org/oppia/android/app/home/promotedlist/PromotedStoryListViewModelTest.kt
index 15988155b7a..9c2eafd02e7 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/home/promotedlist/PromotedStoryListViewModelTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/home/promotedlist/PromotedStoryListViewModelTest.kt
@@ -72,6 +72,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -370,7 +371,8 @@ class PromotedStoryListViewModelTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/home/promotedlist/PromotedStoryViewModelTest.kt b/app/src/sharedTest/java/org/oppia/android/app/home/promotedlist/PromotedStoryViewModelTest.kt
index 0e4f82c366e..8c1f0d35665 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/home/promotedlist/PromotedStoryViewModelTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/home/promotedlist/PromotedStoryViewModelTest.kt
@@ -70,6 +70,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -380,7 +381,8 @@ class PromotedStoryViewModelTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/mydownloads/MyDownloadsActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/mydownloads/MyDownloadsActivityTest.kt
index d1b682cbb0b..fe53065ddf2 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/mydownloads/MyDownloadsActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/mydownloads/MyDownloadsActivityTest.kt
@@ -68,6 +68,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -143,7 +144,8 @@ class MyDownloadsActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/mydownloads/MyDownloadsFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/mydownloads/MyDownloadsFragmentTest.kt
index 330171bab0c..927c14d4622 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/mydownloads/MyDownloadsFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/mydownloads/MyDownloadsFragmentTest.kt
@@ -79,6 +79,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -234,7 +235,8 @@ class MyDownloadsFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/notice/BUILD.bazel b/app/src/sharedTest/java/org/oppia/android/app/notice/BUILD.bazel
index a58c530be9f..20d4828910e 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/notice/BUILD.bazel
+++ b/app/src/sharedTest/java/org/oppia/android/app/notice/BUILD.bazel
@@ -36,6 +36,7 @@ app_test(
"//utility/src/main/java/org/oppia/android/util/caching/testing:caching_test_module",
"//utility/src/main/java/org/oppia/android/util/locale/testing:test_module",
"//utility/src/main/java/org/oppia/android/util/logging:prod_module",
+ "//utility/src/main/java/org/oppia/android/util/logging:standard_event_logging_configuration_module",
"//utility/src/main/java/org/oppia/android/util/logging/firebase:debug_module",
"//utility/src/main/java/org/oppia/android/util/networking:debug_module",
"//utility/src/main/java/org/oppia/android/util/networking:debug_util_module",
@@ -72,6 +73,7 @@ app_test(
"//utility/src/main/java/org/oppia/android/util/caching/testing:caching_test_module",
"//utility/src/main/java/org/oppia/android/util/locale/testing:test_module",
"//utility/src/main/java/org/oppia/android/util/logging:prod_module",
+ "//utility/src/main/java/org/oppia/android/util/logging:standard_event_logging_configuration_module",
"//utility/src/main/java/org/oppia/android/util/logging/firebase:debug_module",
"//utility/src/main/java/org/oppia/android/util/networking:debug_module",
"//utility/src/main/java/org/oppia/android/util/networking:debug_util_module",
diff --git a/app/src/sharedTest/java/org/oppia/android/app/notice/BetaNoticeDialogFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/notice/BetaNoticeDialogFragmentTest.kt
index 0a694c49b2b..d3f870d3535 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/notice/BetaNoticeDialogFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/notice/BetaNoticeDialogFragmentTest.kt
@@ -84,6 +84,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -245,7 +246,8 @@ class BetaNoticeDialogFragmentTest {
AlgebraicExpressionInputModule::class, MathEquationInputModule::class,
SplitScreenInteractionModule::class, LoggingIdentifierModule::class,
ApplicationLifecycleModule::class, SyncStatusModule::class, TestingBuildFlavorModule::class,
- CachingTestModule::class, MetricLogSchedulerModule::class
+ CachingTestModule::class, MetricLogSchedulerModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/notice/GeneralAvailabilityUpgradeNoticeDialogFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/notice/GeneralAvailabilityUpgradeNoticeDialogFragmentTest.kt
index 4207a1d5e78..a2ae13b3dc4 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/notice/GeneralAvailabilityUpgradeNoticeDialogFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/notice/GeneralAvailabilityUpgradeNoticeDialogFragmentTest.kt
@@ -84,6 +84,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -252,7 +253,8 @@ class GeneralAvailabilityUpgradeNoticeDialogFragmentTest {
AlgebraicExpressionInputModule::class, MathEquationInputModule::class,
SplitScreenInteractionModule::class, LoggingIdentifierModule::class,
ApplicationLifecycleModule::class, SyncStatusModule::class, TestingBuildFlavorModule::class,
- CachingTestModule::class, MetricLogSchedulerModule::class
+ CachingTestModule::class, MetricLogSchedulerModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingActivityTest.kt
index 3757c17d7cf..7205c4bc103 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingActivityTest.kt
@@ -69,6 +69,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -152,7 +153,8 @@ class OnboardingActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingFragmentTest.kt
index 4fea9798161..ab17df40bfe 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/onboarding/OnboardingFragmentTest.kt
@@ -99,6 +99,7 @@ import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.DefaultResourceBucketName
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -724,7 +725,8 @@ class OnboardingFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/ongoingtopiclist/OngoingTopicListActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/ongoingtopiclist/OngoingTopicListActivityTest.kt
index 44948180740..234d19175ea 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/ongoingtopiclist/OngoingTopicListActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/ongoingtopiclist/OngoingTopicListActivityTest.kt
@@ -92,6 +92,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -459,7 +460,8 @@ class OngoingTopicListActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/options/AppLanguageActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/options/AppLanguageActivityTest.kt
index 1bda24c4f48..c50eca3f02f 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/options/AppLanguageActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/options/AppLanguageActivityTest.kt
@@ -69,6 +69,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -162,7 +163,8 @@ class AppLanguageActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/options/AppLanguageFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/options/AppLanguageFragmentTest.kt
index 3f4aa8f3a31..d0b018756cb 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/options/AppLanguageFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/options/AppLanguageFragmentTest.kt
@@ -81,6 +81,7 @@ import org.oppia.android.util.caching.CacheAssetsLocally
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -257,7 +258,8 @@ class AppLanguageFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/options/AudioLanguageActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/options/AudioLanguageActivityTest.kt
index 2bc4922f9a4..f11cac82f24 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/options/AudioLanguageActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/options/AudioLanguageActivityTest.kt
@@ -69,6 +69,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -162,7 +163,8 @@ class AudioLanguageActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/options/AudioLanguageFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/options/AudioLanguageFragmentTest.kt
index 69bf7e01e8a..c888949ce4d 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/options/AudioLanguageFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/options/AudioLanguageFragmentTest.kt
@@ -80,6 +80,7 @@ import org.oppia.android.util.caching.CacheAssetsLocally
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -250,7 +251,8 @@ class AudioLanguageFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/options/OptionsActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/options/OptionsActivityTest.kt
index 8839bf88eb7..974251e214a 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/options/OptionsActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/options/OptionsActivityTest.kt
@@ -69,6 +69,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -154,7 +155,8 @@ class OptionsActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/options/OptionsFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/options/OptionsFragmentTest.kt
index 5e17d4b0877..40b61b95c6d 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/options/OptionsFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/options/OptionsFragmentTest.kt
@@ -91,6 +91,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -654,7 +655,8 @@ class OptionsFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/options/ReadingTextSizeActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/options/ReadingTextSizeActivityTest.kt
index 2d11f2d65cc..b4e3196e763 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/options/ReadingTextSizeActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/options/ReadingTextSizeActivityTest.kt
@@ -69,6 +69,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -162,7 +163,8 @@ class ReadingTextSizeActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/options/ReadingTextSizeFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/options/ReadingTextSizeFragmentTest.kt
index bb3b3d23a7b..c0a5a36a26e 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/options/ReadingTextSizeFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/options/ReadingTextSizeFragmentTest.kt
@@ -87,6 +87,7 @@ import org.oppia.android.util.caching.CacheAssetsLocally
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -316,7 +317,8 @@ class ReadingTextSizeFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/parser/HtmlParserTest.kt b/app/src/sharedTest/java/org/oppia/android/app/parser/HtmlParserTest.kt
index 83640c04d2f..8194020e6d8 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/parser/HtmlParserTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/parser/HtmlParserTest.kt
@@ -119,6 +119,7 @@ import org.oppia.android.util.locale.DisplayLocaleImpl
import org.oppia.android.util.locale.LocaleProdModule
import org.oppia.android.util.locale.OppiaBidiFormatter
import org.oppia.android.util.locale.OppiaLocale
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -908,7 +909,8 @@ class HtmlParserTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/player/audio/AudioFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/player/audio/AudioFragmentTest.kt
index ecafe75284e..a28cfa1dd3a 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/player/audio/AudioFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/player/audio/AudioFragmentTest.kt
@@ -99,6 +99,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -479,7 +480,8 @@ class AudioFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt
index 053cddc373a..9830902e90c 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt
@@ -146,6 +146,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -1959,7 +1960,8 @@ class ExplorationActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class,
- MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
diff --git a/app/src/sharedTest/java/org/oppia/android/app/player/state/BUILD.bazel b/app/src/sharedTest/java/org/oppia/android/app/player/state/BUILD.bazel
index 1430f73fa51..5f43c05d529 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/player/state/BUILD.bazel
+++ b/app/src/sharedTest/java/org/oppia/android/app/player/state/BUILD.bazel
@@ -43,6 +43,7 @@ app_test(
"//utility/src/main/java/org/oppia/android/util/data:data_providers",
"//utility/src/main/java/org/oppia/android/util/locale/testing:test_module",
"//utility/src/main/java/org/oppia/android/util/logging:prod_module",
+ "//utility/src/main/java/org/oppia/android/util/logging:standard_event_logging_configuration_module",
"//utility/src/main/java/org/oppia/android/util/logging/firebase:debug_module",
"//utility/src/main/java/org/oppia/android/util/networking:debug_module",
"//utility/src/main/java/org/oppia/android/util/networking:debug_util_module",
diff --git a/app/src/sharedTest/java/org/oppia/android/app/player/state/StateFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/player/state/StateFragmentTest.kt
index ed0a0125b0d..798898c50a6 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/player/state/StateFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/player/state/StateFragmentTest.kt
@@ -170,6 +170,7 @@ import org.oppia.android.util.caching.LoadLessonProtosFromAssets
import org.oppia.android.util.caching.TopicListToCache
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -4320,7 +4321,8 @@ class StateFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/policies/PoliciesActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/policies/PoliciesActivityTest.kt
index 26724b47f42..a08267bea80 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/policies/PoliciesActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/policies/PoliciesActivityTest.kt
@@ -70,6 +70,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -185,7 +186,8 @@ class PoliciesActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/policies/PoliciesFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/policies/PoliciesFragmentTest.kt
index 69b5e5ddbdf..c31d8a65687 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/policies/PoliciesFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/policies/PoliciesFragmentTest.kt
@@ -95,6 +95,7 @@ import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.DefaultResourceBucketName
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -338,7 +339,8 @@ class PoliciesFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/profile/AddProfileActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/profile/AddProfileActivityTest.kt
index 4595e72857e..b0f22cf2746 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/profile/AddProfileActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/profile/AddProfileActivityTest.kt
@@ -108,6 +108,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -1733,7 +1734,8 @@ class AddProfileActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/profile/AdminAuthActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/profile/AdminAuthActivityTest.kt
index 23949bf6b7e..74cf33ec247 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/profile/AdminAuthActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/profile/AdminAuthActivityTest.kt
@@ -92,6 +92,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -673,7 +674,8 @@ class AdminAuthActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/profile/AdminPinActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/profile/AdminPinActivityTest.kt
index 5b92a040c25..44c263ffd1b 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/profile/AdminPinActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/profile/AdminPinActivityTest.kt
@@ -103,6 +103,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -1091,7 +1092,8 @@ class AdminPinActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/profile/PinPasswordActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/profile/PinPasswordActivityTest.kt
index c4b9a510724..09657cd3dae 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/profile/PinPasswordActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/profile/PinPasswordActivityTest.kt
@@ -98,6 +98,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -1153,7 +1154,8 @@ class PinPasswordActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/profile/ProfileChooserFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/profile/ProfileChooserFragmentTest.kt
index cbb45e201cf..41adc0c22b3 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/profile/ProfileChooserFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/profile/ProfileChooserFragmentTest.kt
@@ -94,6 +94,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -530,7 +531,8 @@ class ProfileChooserFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/profileprogress/ProfilePictureActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/profileprogress/ProfilePictureActivityTest.kt
index 51a4440dc1f..ba9727c7eb1 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/profileprogress/ProfilePictureActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/profileprogress/ProfilePictureActivityTest.kt
@@ -78,6 +78,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -205,7 +206,8 @@ class ProfilePictureActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/profileprogress/ProfileProgressActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/profileprogress/ProfileProgressActivityTest.kt
index a47d30bd5a0..0647d0a7c9a 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/profileprogress/ProfileProgressActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/profileprogress/ProfileProgressActivityTest.kt
@@ -69,6 +69,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -156,7 +157,8 @@ class ProfileProgressActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/profileprogress/ProfileProgressFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/profileprogress/ProfileProgressFragmentTest.kt
index b01743cdfcb..17bc98f9f1a 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/profileprogress/ProfileProgressFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/profileprogress/ProfileProgressFragmentTest.kt
@@ -117,6 +117,7 @@ import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
import org.oppia.android.util.logging.EnableConsoleLog
import org.oppia.android.util.logging.EnableFileLog
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.GlobalLogLevel
import org.oppia.android.util.logging.LogLevel
import org.oppia.android.util.logging.SyncStatusModule
@@ -857,7 +858,8 @@ class ProfileProgressFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/recyclerview/BindableAdapterTest.kt b/app/src/sharedTest/java/org/oppia/android/app/recyclerview/BindableAdapterTest.kt
index 0a8321945bb..c12ad0b6c7c 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/recyclerview/BindableAdapterTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/recyclerview/BindableAdapterTest.kt
@@ -109,6 +109,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -768,7 +769,8 @@ class BindableAdapterTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/resumelesson/ResumeLessonActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/resumelesson/ResumeLessonActivityTest.kt
index d3a0c8073bd..e39f45da2b8 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/resumelesson/ResumeLessonActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/resumelesson/ResumeLessonActivityTest.kt
@@ -89,6 +89,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -226,7 +227,8 @@ class ResumeLessonActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/resumelesson/ResumeLessonFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/resumelesson/ResumeLessonFragmentTest.kt
index 4760439db99..6fe742fa7df 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/resumelesson/ResumeLessonFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/resumelesson/ResumeLessonFragmentTest.kt
@@ -92,6 +92,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -315,7 +316,8 @@ class ResumeLessonFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditActivityTest.kt
index 0e0450b08a2..2c71deefabd 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditActivityTest.kt
@@ -88,6 +88,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -379,7 +380,8 @@ class ProfileEditActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditFragmentTest.kt
index dcc7285bf51..5ddf52446db 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditFragmentTest.kt
@@ -90,6 +90,7 @@ import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.data.DataProviders.Companion.toLiveData
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -356,7 +357,8 @@ class ProfileEditFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
diff --git a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileListActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileListActivityTest.kt
index fc6b3cc972e..3134ef57506 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileListActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileListActivityTest.kt
@@ -69,6 +69,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -152,7 +153,8 @@ class ProfileListActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileListFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileListFragmentTest.kt
index 37feb72c90d..a23ee83334a 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileListFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileListFragmentTest.kt
@@ -86,6 +86,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -390,7 +391,8 @@ class ProfileListFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileRenameActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileRenameActivityTest.kt
index 026dede3753..9a94cb052d1 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileRenameActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileRenameActivityTest.kt
@@ -73,6 +73,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -175,7 +176,8 @@ class ProfileRenameActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileRenameFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileRenameFragmentTest.kt
index 7efe91a973e..2e144526421 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileRenameFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileRenameFragmentTest.kt
@@ -91,6 +91,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -464,7 +465,8 @@ class ProfileRenameFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileResetPinActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileResetPinActivityTest.kt
index 766f0ffc3ec..0b3ef56e709 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileResetPinActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileResetPinActivityTest.kt
@@ -74,6 +74,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -186,7 +187,8 @@ class ProfileResetPinActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileResetPinFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileResetPinFragmentTest.kt
index c82448b3733..1adaab8f8d8 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileResetPinFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileResetPinFragmentTest.kt
@@ -92,6 +92,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -1028,7 +1029,8 @@ class ProfileResetPinFragmentTest {
AlgebraicExpressionInputModule::class, MathEquationInputModule::class,
SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/splash/BUILD.bazel b/app/src/sharedTest/java/org/oppia/android/app/splash/BUILD.bazel
index 8a15fa58892..65dbb604e46 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/splash/BUILD.bazel
+++ b/app/src/sharedTest/java/org/oppia/android/app/splash/BUILD.bazel
@@ -44,6 +44,7 @@ app_test(
"//utility/src/main/java/org/oppia/android/util/data:data_providers",
"//utility/src/main/java/org/oppia/android/util/locale/testing:test_module",
"//utility/src/main/java/org/oppia/android/util/logging:prod_module",
+ "//utility/src/main/java/org/oppia/android/util/logging:standard_event_logging_configuration_module",
"//utility/src/main/java/org/oppia/android/util/logging/firebase:debug_module",
"//utility/src/main/java/org/oppia/android/util/networking:debug_module",
"//utility/src/main/java/org/oppia/android/util/networking:debug_util_module",
diff --git a/app/src/sharedTest/java/org/oppia/android/app/splash/SplashActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/splash/SplashActivityTest.kt
index 9c1da667d90..6c119fff0e5 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/splash/SplashActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/splash/SplashActivityTest.kt
@@ -109,6 +109,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -1203,7 +1204,8 @@ class SplashActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/story/StoryActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/story/StoryActivityTest.kt
index 2fa6bda9d46..0183b1740a5 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/story/StoryActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/story/StoryActivityTest.kt
@@ -89,6 +89,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -236,7 +237,8 @@ class StoryActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/story/StoryFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/story/StoryFragmentTest.kt
index e1b9859c69c..1df903d3ae5 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/story/StoryFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/story/StoryFragmentTest.kt
@@ -130,6 +130,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -904,7 +905,8 @@ class StoryFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/testing/DragDropTestActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/testing/DragDropTestActivityTest.kt
index 3e79cccd1b6..4f629fa702b 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/testing/DragDropTestActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/testing/DragDropTestActivityTest.kt
@@ -80,6 +80,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -229,7 +230,8 @@ class DragDropTestActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/testing/ImageRegionSelectionInteractionViewTest.kt b/app/src/sharedTest/java/org/oppia/android/app/testing/ImageRegionSelectionInteractionViewTest.kt
index 15ced77dc59..a29f03d5667 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/testing/ImageRegionSelectionInteractionViewTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/testing/ImageRegionSelectionInteractionViewTest.kt
@@ -94,6 +94,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -416,7 +417,8 @@ class ImageRegionSelectionInteractionViewTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/testing/InputInteractionViewTestActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/testing/InputInteractionViewTestActivityTest.kt
index 97d4326ceaf..59cf604fcff 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/testing/InputInteractionViewTestActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/testing/InputInteractionViewTestActivityTest.kt
@@ -89,6 +89,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -1127,7 +1128,8 @@ class InputInteractionViewTestActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/testing/NavigationDrawerActivityDebugTest.kt b/app/src/sharedTest/java/org/oppia/android/app/testing/NavigationDrawerActivityDebugTest.kt
index 6096a49752e..f263bdc6685 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/testing/NavigationDrawerActivityDebugTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/testing/NavigationDrawerActivityDebugTest.kt
@@ -110,6 +110,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -440,7 +441,8 @@ class NavigationDrawerActivityDebugTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/testing/NavigationDrawerActivityProdTest.kt b/app/src/sharedTest/java/org/oppia/android/app/testing/NavigationDrawerActivityProdTest.kt
index e9c6b2a98ac..cf9354a7afb 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/testing/NavigationDrawerActivityProdTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/testing/NavigationDrawerActivityProdTest.kt
@@ -120,6 +120,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -989,7 +990,8 @@ class NavigationDrawerActivityProdTest {
AlgebraicExpressionInputModule::class, MathEquationInputModule::class,
SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/testing/TestFontScaleConfigurationUtilActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/testing/TestFontScaleConfigurationUtilActivityTest.kt
index 5cfe02d9bdc..5516365c6dd 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/testing/TestFontScaleConfigurationUtilActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/testing/TestFontScaleConfigurationUtilActivityTest.kt
@@ -75,6 +75,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -207,7 +208,8 @@ class TestFontScaleConfigurationUtilActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/testing/TopicTestActivityForStoryTest.kt b/app/src/sharedTest/java/org/oppia/android/app/testing/TopicTestActivityForStoryTest.kt
index 329648407b1..b3a01339ace 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/testing/TopicTestActivityForStoryTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/testing/TopicTestActivityForStoryTest.kt
@@ -82,6 +82,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -204,7 +205,8 @@ class TopicTestActivityForStoryTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseListActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseListActivityTest.kt
index 32993ac8369..80933efdd17 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseListActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseListActivityTest.kt
@@ -70,6 +70,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -164,7 +165,8 @@ class LicenseListActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class,
- MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
diff --git a/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseListFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseListFragmentTest.kt
index 0b5f2eae1ab..0d1b9530019 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseListFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseListFragmentTest.kt
@@ -87,6 +87,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -374,7 +375,8 @@ class LicenseListFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class,
- MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
diff --git a/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseTextViewerActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseTextViewerActivityTest.kt
index 198ef7c20f5..a05b58482b8 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseTextViewerActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseTextViewerActivityTest.kt
@@ -71,6 +71,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -173,7 +174,8 @@ class LicenseTextViewerActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class,
- MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
diff --git a/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseTextViewerFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseTextViewerFragmentTest.kt
index b12abd0898a..1ba4db8defe 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseTextViewerFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseTextViewerFragmentTest.kt
@@ -77,6 +77,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -352,7 +353,8 @@ class LicenseTextViewerFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class,
- MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
diff --git a/app/src/sharedTest/java/org/oppia/android/app/thirdparty/ThirdPartyDependencyListActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/thirdparty/ThirdPartyDependencyListActivityTest.kt
index b6a7a2093b7..7c48c7b3293 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/thirdparty/ThirdPartyDependencyListActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/thirdparty/ThirdPartyDependencyListActivityTest.kt
@@ -70,6 +70,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -161,7 +162,8 @@ class ThirdPartyDependencyListActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class,
- MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
diff --git a/app/src/sharedTest/java/org/oppia/android/app/thirdparty/ThirdPartyDependencyListFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/thirdparty/ThirdPartyDependencyListFragmentTest.kt
index cd7839f3fdb..d83be2fa69c 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/thirdparty/ThirdPartyDependencyListFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/thirdparty/ThirdPartyDependencyListFragmentTest.kt
@@ -86,6 +86,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -484,7 +485,8 @@ class ThirdPartyDependencyListFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class, SyncStatusModule::class,
- MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/TopicActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/TopicActivityTest.kt
index 9cbbb6dd857..811eb56e3a0 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/TopicActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/TopicActivityTest.kt
@@ -86,6 +86,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -210,7 +211,8 @@ class TopicActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt
index a83ee19558f..2cc623d9673 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt
@@ -96,6 +96,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -665,7 +666,8 @@ class TopicFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/conceptcard/ConceptCardFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/conceptcard/ConceptCardFragmentTest.kt
index 3af01c379e0..be84ee5b866 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/conceptcard/ConceptCardFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/conceptcard/ConceptCardFragmentTest.kt
@@ -102,6 +102,7 @@ import org.oppia.android.util.caching.LoadLessonProtosFromAssets
import org.oppia.android.util.caching.TopicListToCache
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -436,7 +437,8 @@ class ConceptCardFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/info/TopicInfoFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/info/TopicInfoFragmentTest.kt
index ab908ad0315..ac4c4f2242e 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/info/TopicInfoFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/info/TopicInfoFragmentTest.kt
@@ -101,6 +101,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -492,7 +493,8 @@ class TopicInfoFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/lessons/TopicLessonsFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/lessons/TopicLessonsFragmentTest.kt
index 6cccfd1f84a..9bd4ceb03eb 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/lessons/TopicLessonsFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/lessons/TopicLessonsFragmentTest.kt
@@ -114,6 +114,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -1021,7 +1022,8 @@ class TopicLessonsFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/practice/TopicPracticeFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/practice/TopicPracticeFragmentTest.kt
index be3f067135a..7363b036760 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/practice/TopicPracticeFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/practice/TopicPracticeFragmentTest.kt
@@ -94,6 +94,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -437,7 +438,8 @@ class TopicPracticeFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/questionplayer/QuestionPlayerActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/questionplayer/QuestionPlayerActivityTest.kt
index 13e515ebefc..d24b7a45c89 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/questionplayer/QuestionPlayerActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/questionplayer/QuestionPlayerActivityTest.kt
@@ -135,6 +135,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -726,7 +727,8 @@ class QuestionPlayerActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/revision/TopicRevisionFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/revision/TopicRevisionFragmentTest.kt
index 01054765d12..32796a6a931 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/revision/TopicRevisionFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/revision/TopicRevisionFragmentTest.kt
@@ -97,6 +97,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -333,7 +334,8 @@ class TopicRevisionFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/revisioncard/RevisionCardActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/revisioncard/RevisionCardActivityTest.kt
index 894dec9cb73..869b93f93ac 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/revisioncard/RevisionCardActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/revisioncard/RevisionCardActivityTest.kt
@@ -90,6 +90,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -287,7 +288,8 @@ class RevisionCardActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/revisioncard/RevisionCardFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/revisioncard/RevisionCardFragmentTest.kt
index 85c1e26ef3d..180ea961249 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/topic/revisioncard/RevisionCardFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/topic/revisioncard/RevisionCardFragmentTest.kt
@@ -114,6 +114,7 @@ import org.oppia.android.util.caching.LoadLessonProtosFromAssets
import org.oppia.android.util.caching.TopicListToCache
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -603,7 +604,8 @@ class RevisionCardFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/utility/RatioExtensionsTest.kt b/app/src/sharedTest/java/org/oppia/android/app/utility/RatioExtensionsTest.kt
index 8ea214e120a..eddf809bbd1 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/utility/RatioExtensionsTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/utility/RatioExtensionsTest.kt
@@ -68,6 +68,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -160,7 +161,8 @@ class RatioExtensionsTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughActivityTest.kt
index 9d977f37a02..988d6ad9a35 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughActivityTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughActivityTest.kt
@@ -81,6 +81,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -238,7 +239,8 @@ class WalkthroughActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughFinalFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughFinalFragmentTest.kt
index d27197c2cad..3d7e1189353 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughFinalFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughFinalFragmentTest.kt
@@ -85,6 +85,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -295,7 +296,8 @@ class WalkthroughFinalFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughTopicListFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughTopicListFragmentTest.kt
index ec3ab607a23..df4ffd67de5 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughTopicListFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughTopicListFragmentTest.kt
@@ -92,6 +92,7 @@ import org.oppia.android.util.caching.LoadLessonProtosFromAssets
import org.oppia.android.util.caching.TopicListToCache
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -321,7 +322,8 @@ class WalkthroughTopicListFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughWelcomeFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughWelcomeFragmentTest.kt
index d8b48d6dbdb..dee95da51ba 100644
--- a/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughWelcomeFragmentTest.kt
+++ b/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughWelcomeFragmentTest.kt
@@ -82,6 +82,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -218,7 +219,8 @@ class WalkthroughWelcomeFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/activity/ActivityIntentFactoriesTest.kt b/app/src/test/java/org/oppia/android/app/activity/ActivityIntentFactoriesTest.kt
index 80145e188cc..c9beffcb977 100644
--- a/app/src/test/java/org/oppia/android/app/activity/ActivityIntentFactoriesTest.kt
+++ b/app/src/test/java/org/oppia/android/app/activity/ActivityIntentFactoriesTest.kt
@@ -70,6 +70,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -183,7 +184,8 @@ class ActivityIntentFactoriesTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/activity/BUILD.bazel b/app/src/test/java/org/oppia/android/app/activity/BUILD.bazel
index ec052a7416a..ba122153187 100644
--- a/app/src/test/java/org/oppia/android/app/activity/BUILD.bazel
+++ b/app/src/test/java/org/oppia/android/app/activity/BUILD.bazel
@@ -38,6 +38,7 @@ oppia_android_test(
"//utility/src/main/java/org/oppia/android/util/caching/testing:caching_test_module",
"//utility/src/main/java/org/oppia/android/util/data:data_providers",
"//utility/src/main/java/org/oppia/android/util/logging:prod_module",
+ "//utility/src/main/java/org/oppia/android/util/logging:standard_event_logging_configuration_module",
"//utility/src/main/java/org/oppia/android/util/logging/firebase:debug_module",
"//utility/src/main/java/org/oppia/android/util/networking:debug_module",
],
diff --git a/app/src/test/java/org/oppia/android/app/home/HomeActivityLocalTest.kt b/app/src/test/java/org/oppia/android/app/home/HomeActivityLocalTest.kt
index 810f35b9475..04f76b1b589 100644
--- a/app/src/test/java/org/oppia/android/app/home/HomeActivityLocalTest.kt
+++ b/app/src/test/java/org/oppia/android/app/home/HomeActivityLocalTest.kt
@@ -72,6 +72,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -155,7 +156,8 @@ class HomeActivityLocalTest {
AlgebraicExpressionInputModule::class, MathEquationInputModule::class,
SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/parser/FractionParsingUiErrorTest.kt b/app/src/test/java/org/oppia/android/app/parser/FractionParsingUiErrorTest.kt
index c0216f6e8c6..68409b4de54 100644
--- a/app/src/test/java/org/oppia/android/app/parser/FractionParsingUiErrorTest.kt
+++ b/app/src/test/java/org/oppia/android/app/parser/FractionParsingUiErrorTest.kt
@@ -66,6 +66,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -265,7 +266,8 @@ class FractionParsingUiErrorTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/parser/ListItemLeadingMarginSpanTest.kt b/app/src/test/java/org/oppia/android/app/parser/ListItemLeadingMarginSpanTest.kt
index 8c3fc424a40..a77de28131c 100644
--- a/app/src/test/java/org/oppia/android/app/parser/ListItemLeadingMarginSpanTest.kt
+++ b/app/src/test/java/org/oppia/android/app/parser/ListItemLeadingMarginSpanTest.kt
@@ -101,6 +101,7 @@ import org.oppia.android.util.locale.DisplayLocaleImpl
import org.oppia.android.util.locale.LocaleProdModule
import org.oppia.android.util.locale.OppiaBidiFormatter
import org.oppia.android.util.locale.OppiaLocale
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -1107,7 +1108,8 @@ class ListItemLeadingMarginSpanTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
diff --git a/app/src/test/java/org/oppia/android/app/parser/StringToRatioParserTest.kt b/app/src/test/java/org/oppia/android/app/parser/StringToRatioParserTest.kt
index 0c038ea5d11..3a7eb3d31ee 100644
--- a/app/src/test/java/org/oppia/android/app/parser/StringToRatioParserTest.kt
+++ b/app/src/test/java/org/oppia/android/app/parser/StringToRatioParserTest.kt
@@ -68,6 +68,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -269,7 +270,8 @@ class StringToRatioParserTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/player/exploration/ExplorationActivityLocalTest.kt b/app/src/test/java/org/oppia/android/app/player/exploration/ExplorationActivityLocalTest.kt
index 25d38fd6333..84d0d72c555 100644
--- a/app/src/test/java/org/oppia/android/app/player/exploration/ExplorationActivityLocalTest.kt
+++ b/app/src/test/java/org/oppia/android/app/player/exploration/ExplorationActivityLocalTest.kt
@@ -77,6 +77,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -216,7 +217,8 @@ class ExplorationActivityLocalTest {
AlgebraicExpressionInputModule::class, MathEquationInputModule::class,
SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/player/state/StateFragmentLocalTest.kt b/app/src/test/java/org/oppia/android/app/player/state/StateFragmentLocalTest.kt
index 0a6b6a31e01..22d86d7abac 100644
--- a/app/src/test/java/org/oppia/android/app/player/state/StateFragmentLocalTest.kt
+++ b/app/src/test/java/org/oppia/android/app/player/state/StateFragmentLocalTest.kt
@@ -147,6 +147,7 @@ import org.oppia.android.util.caching.LoadLessonProtosFromAssets
import org.oppia.android.util.caching.TopicListToCache
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -2298,7 +2299,8 @@ class StateFragmentLocalTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/profile/ProfileChooserFragmentLocalTest.kt b/app/src/test/java/org/oppia/android/app/profile/ProfileChooserFragmentLocalTest.kt
index db5a73a3add..e97553798b6 100644
--- a/app/src/test/java/org/oppia/android/app/profile/ProfileChooserFragmentLocalTest.kt
+++ b/app/src/test/java/org/oppia/android/app/profile/ProfileChooserFragmentLocalTest.kt
@@ -69,6 +69,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -144,7 +145,8 @@ class ProfileChooserFragmentLocalTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/story/StoryActivityLocalTest.kt b/app/src/test/java/org/oppia/android/app/story/StoryActivityLocalTest.kt
index dbe875db082..984b184560c 100644
--- a/app/src/test/java/org/oppia/android/app/story/StoryActivityLocalTest.kt
+++ b/app/src/test/java/org/oppia/android/app/story/StoryActivityLocalTest.kt
@@ -71,6 +71,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -169,7 +170,8 @@ class StoryActivityLocalTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/testing/CompletedStoryListSpanTest.kt b/app/src/test/java/org/oppia/android/app/testing/CompletedStoryListSpanTest.kt
index e2874312b64..8356fd5ed65 100644
--- a/app/src/test/java/org/oppia/android/app/testing/CompletedStoryListSpanTest.kt
+++ b/app/src/test/java/org/oppia/android/app/testing/CompletedStoryListSpanTest.kt
@@ -72,6 +72,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -178,7 +179,8 @@ class CompletedStoryListSpanTest {
AlgebraicExpressionInputModule::class, MathEquationInputModule::class,
SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/testing/HomeSpanTest.kt b/app/src/test/java/org/oppia/android/app/testing/HomeSpanTest.kt
index d34e7fa7a19..e4040f94bb6 100644
--- a/app/src/test/java/org/oppia/android/app/testing/HomeSpanTest.kt
+++ b/app/src/test/java/org/oppia/android/app/testing/HomeSpanTest.kt
@@ -72,6 +72,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -192,7 +193,8 @@ class HomeSpanTest {
AlgebraicExpressionInputModule::class, MathEquationInputModule::class,
SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/testing/OngoingTopicListSpanTest.kt b/app/src/test/java/org/oppia/android/app/testing/OngoingTopicListSpanTest.kt
index ae741ccd5b8..76f9bf95fe9 100644
--- a/app/src/test/java/org/oppia/android/app/testing/OngoingTopicListSpanTest.kt
+++ b/app/src/test/java/org/oppia/android/app/testing/OngoingTopicListSpanTest.kt
@@ -73,6 +73,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -189,7 +190,8 @@ class OngoingTopicListSpanTest {
AlgebraicExpressionInputModule::class, MathEquationInputModule::class,
SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/testing/PlatformParameterIntegrationTest.kt b/app/src/test/java/org/oppia/android/app/testing/PlatformParameterIntegrationTest.kt
index abb5758dc05..ed188afb18d 100644
--- a/app/src/test/java/org/oppia/android/app/testing/PlatformParameterIntegrationTest.kt
+++ b/app/src/test/java/org/oppia/android/app/testing/PlatformParameterIntegrationTest.kt
@@ -92,6 +92,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -362,7 +363,8 @@ class PlatformParameterIntegrationTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/testing/ProfileChooserSpanTest.kt b/app/src/test/java/org/oppia/android/app/testing/ProfileChooserSpanTest.kt
index 07fa5fc3e8a..ead0abdb54b 100644
--- a/app/src/test/java/org/oppia/android/app/testing/ProfileChooserSpanTest.kt
+++ b/app/src/test/java/org/oppia/android/app/testing/ProfileChooserSpanTest.kt
@@ -72,6 +72,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -391,7 +392,8 @@ class ProfileChooserSpanTest {
AlgebraicExpressionInputModule::class, MathEquationInputModule::class,
SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/testing/ProfileProgressSpanCountTest.kt b/app/src/test/java/org/oppia/android/app/testing/ProfileProgressSpanCountTest.kt
index a51118c53c2..366347e0e22 100644
--- a/app/src/test/java/org/oppia/android/app/testing/ProfileProgressSpanCountTest.kt
+++ b/app/src/test/java/org/oppia/android/app/testing/ProfileProgressSpanCountTest.kt
@@ -72,6 +72,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -175,7 +176,8 @@ class ProfileProgressSpanCountTest {
AlgebraicExpressionInputModule::class, MathEquationInputModule::class,
SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/testing/RecentlyPlayedSpanTest.kt b/app/src/test/java/org/oppia/android/app/testing/RecentlyPlayedSpanTest.kt
index d922623fe3f..ff5356bf1bc 100644
--- a/app/src/test/java/org/oppia/android/app/testing/RecentlyPlayedSpanTest.kt
+++ b/app/src/test/java/org/oppia/android/app/testing/RecentlyPlayedSpanTest.kt
@@ -77,6 +77,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -310,7 +311,8 @@ class RecentlyPlayedSpanTest {
AlgebraicExpressionInputModule::class, MathEquationInputModule::class,
SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/testing/TopicRevisionSpanTest.kt b/app/src/test/java/org/oppia/android/app/testing/TopicRevisionSpanTest.kt
index 24822b4c5f2..8d2650f5f28 100644
--- a/app/src/test/java/org/oppia/android/app/testing/TopicRevisionSpanTest.kt
+++ b/app/src/test/java/org/oppia/android/app/testing/TopicRevisionSpanTest.kt
@@ -71,6 +71,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -175,7 +176,8 @@ class TopicRevisionSpanTest {
AlgebraicExpressionInputModule::class, MathEquationInputModule::class,
SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/testing/activity/BUILD.bazel b/app/src/test/java/org/oppia/android/app/testing/activity/BUILD.bazel
index 6b3c8185dd7..26313703901 100644
--- a/app/src/test/java/org/oppia/android/app/testing/activity/BUILD.bazel
+++ b/app/src/test/java/org/oppia/android/app/testing/activity/BUILD.bazel
@@ -40,6 +40,7 @@ oppia_android_test(
"//utility/src/main/java/org/oppia/android/util/locale:prod_module",
"//utility/src/main/java/org/oppia/android/util/locale/testing:test_module",
"//utility/src/main/java/org/oppia/android/util/logging:prod_module",
+ "//utility/src/main/java/org/oppia/android/util/logging:standard_event_logging_configuration_module",
"//utility/src/main/java/org/oppia/android/util/logging/firebase:debug_module",
"//utility/src/main/java/org/oppia/android/util/networking:debug_module",
"//utility/src/main/java/org/oppia/android/util/networking:debug_util_module",
diff --git a/app/src/test/java/org/oppia/android/app/testing/activity/TestActivityTest.kt b/app/src/test/java/org/oppia/android/app/testing/activity/TestActivityTest.kt
index a2b18b6500a..6e78e4ee333 100644
--- a/app/src/test/java/org/oppia/android/app/testing/activity/TestActivityTest.kt
+++ b/app/src/test/java/org/oppia/android/app/testing/activity/TestActivityTest.kt
@@ -68,6 +68,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -200,7 +201,8 @@ class TestActivityTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/testing/administratorcontrols/AdministratorControlsFragmentTest.kt b/app/src/test/java/org/oppia/android/app/testing/administratorcontrols/AdministratorControlsFragmentTest.kt
index 9f0d0a5e4a3..6360351244d 100644
--- a/app/src/test/java/org/oppia/android/app/testing/administratorcontrols/AdministratorControlsFragmentTest.kt
+++ b/app/src/test/java/org/oppia/android/app/testing/administratorcontrols/AdministratorControlsFragmentTest.kt
@@ -79,6 +79,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -199,7 +200,8 @@ class AdministratorControlsFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/testing/options/OptionsFragmentTest.kt b/app/src/test/java/org/oppia/android/app/testing/options/OptionsFragmentTest.kt
index b0481e189ec..dee6fc47d71 100644
--- a/app/src/test/java/org/oppia/android/app/testing/options/OptionsFragmentTest.kt
+++ b/app/src/test/java/org/oppia/android/app/testing/options/OptionsFragmentTest.kt
@@ -80,6 +80,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -253,7 +254,8 @@ class OptionsFragmentTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/testing/player/split/PlayerSplitScreenTest.kt b/app/src/test/java/org/oppia/android/app/testing/player/split/PlayerSplitScreenTest.kt
index 1b7ff73b2c3..4fb1e275b53 100644
--- a/app/src/test/java/org/oppia/android/app/testing/player/split/PlayerSplitScreenTest.kt
+++ b/app/src/test/java/org/oppia/android/app/testing/player/split/PlayerSplitScreenTest.kt
@@ -69,6 +69,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -208,7 +209,8 @@ class PlayerSplitScreenTest {
AlgebraicExpressionInputModule::class, MathEquationInputModule::class,
SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/testing/player/state/StateFragmentAccessibilityTest.kt b/app/src/test/java/org/oppia/android/app/testing/player/state/StateFragmentAccessibilityTest.kt
index 369862684ef..ce8149249cd 100644
--- a/app/src/test/java/org/oppia/android/app/testing/player/state/StateFragmentAccessibilityTest.kt
+++ b/app/src/test/java/org/oppia/android/app/testing/player/state/StateFragmentAccessibilityTest.kt
@@ -81,6 +81,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -215,7 +216,8 @@ class StateFragmentAccessibilityTest {
AlgebraicExpressionInputModule::class, MathEquationInputModule::class,
SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/topic/info/TopicInfoFragmentLocalTest.kt b/app/src/test/java/org/oppia/android/app/topic/info/TopicInfoFragmentLocalTest.kt
index 2ce810912e1..5806775288a 100644
--- a/app/src/test/java/org/oppia/android/app/topic/info/TopicInfoFragmentLocalTest.kt
+++ b/app/src/test/java/org/oppia/android/app/topic/info/TopicInfoFragmentLocalTest.kt
@@ -69,6 +69,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -157,7 +158,8 @@ class TopicInfoFragmentLocalTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/topic/lessons/TopicLessonsFragmentLocalTest.kt b/app/src/test/java/org/oppia/android/app/topic/lessons/TopicLessonsFragmentLocalTest.kt
index 34e74865716..9cb29e6cc7c 100644
--- a/app/src/test/java/org/oppia/android/app/topic/lessons/TopicLessonsFragmentLocalTest.kt
+++ b/app/src/test/java/org/oppia/android/app/topic/lessons/TopicLessonsFragmentLocalTest.kt
@@ -68,6 +68,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -160,7 +161,8 @@ class TopicLessonsFragmentLocalTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/topic/questionplayer/QuestionPlayerActivityLocalTest.kt b/app/src/test/java/org/oppia/android/app/topic/questionplayer/QuestionPlayerActivityLocalTest.kt
index f095af739b5..618d85cf349 100644
--- a/app/src/test/java/org/oppia/android/app/topic/questionplayer/QuestionPlayerActivityLocalTest.kt
+++ b/app/src/test/java/org/oppia/android/app/topic/questionplayer/QuestionPlayerActivityLocalTest.kt
@@ -100,6 +100,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -508,7 +509,8 @@ class QuestionPlayerActivityLocalTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/topic/revisioncard/RevisionCardActivityLocalTest.kt b/app/src/test/java/org/oppia/android/app/topic/revisioncard/RevisionCardActivityLocalTest.kt
index df63ed67dbb..5b2cf5172de 100644
--- a/app/src/test/java/org/oppia/android/app/topic/revisioncard/RevisionCardActivityLocalTest.kt
+++ b/app/src/test/java/org/oppia/android/app/topic/revisioncard/RevisionCardActivityLocalTest.kt
@@ -70,6 +70,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -149,7 +150,8 @@ class RevisionCardActivityLocalTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/translation/AppLanguageResourceHandlerTest.kt b/app/src/test/java/org/oppia/android/app/translation/AppLanguageResourceHandlerTest.kt
index 12c7ed9d8c3..93a26276a3d 100644
--- a/app/src/test/java/org/oppia/android/app/translation/AppLanguageResourceHandlerTest.kt
+++ b/app/src/test/java/org/oppia/android/app/translation/AppLanguageResourceHandlerTest.kt
@@ -77,6 +77,7 @@ import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.testing.LocaleTestModule
import org.oppia.android.util.locale.testing.TestOppiaBidiFormatter
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -558,7 +559,8 @@ class AppLanguageResourceHandlerTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/translation/AppLanguageWatcherMixinTest.kt b/app/src/test/java/org/oppia/android/app/translation/AppLanguageWatcherMixinTest.kt
index 5b4a6ede4fb..536195ef6c5 100644
--- a/app/src/test/java/org/oppia/android/app/translation/AppLanguageWatcherMixinTest.kt
+++ b/app/src/test/java/org/oppia/android/app/translation/AppLanguageWatcherMixinTest.kt
@@ -82,6 +82,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.testing.LocaleTestModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -273,7 +274,8 @@ class AppLanguageWatcherMixinTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/translation/BUILD.bazel b/app/src/test/java/org/oppia/android/app/translation/BUILD.bazel
index 171d07f5602..46184129002 100644
--- a/app/src/test/java/org/oppia/android/app/translation/BUILD.bazel
+++ b/app/src/test/java/org/oppia/android/app/translation/BUILD.bazel
@@ -80,6 +80,7 @@ oppia_android_test(
"//utility/src/main/java/org/oppia/android/util/locale/testing:test_module",
"//utility/src/main/java/org/oppia/android/util/locale/testing:test_oppia_bidi_formatter",
"//utility/src/main/java/org/oppia/android/util/logging:prod_module",
+ "//utility/src/main/java/org/oppia/android/util/logging:standard_event_logging_configuration_module",
"//utility/src/main/java/org/oppia/android/util/logging/firebase:debug_module",
"//utility/src/main/java/org/oppia/android/util/networking:debug_module",
"//utility/src/main/java/org/oppia/android/util/networking:debug_util_module",
@@ -124,6 +125,7 @@ oppia_android_test(
"//utility/src/main/java/org/oppia/android/util/data:data_providers",
"//utility/src/main/java/org/oppia/android/util/locale/testing:test_module",
"//utility/src/main/java/org/oppia/android/util/logging:prod_module",
+ "//utility/src/main/java/org/oppia/android/util/logging:standard_event_logging_configuration_module",
"//utility/src/main/java/org/oppia/android/util/logging/firebase:debug_module",
"//utility/src/main/java/org/oppia/android/util/networking:debug_module",
"//utility/src/main/java/org/oppia/android/util/networking:debug_util_module",
diff --git a/app/src/test/java/org/oppia/android/app/utility/datetime/DateTimeUtilTest.kt b/app/src/test/java/org/oppia/android/app/utility/datetime/DateTimeUtilTest.kt
index 95ba0d375ff..290447a698e 100644
--- a/app/src/test/java/org/oppia/android/app/utility/datetime/DateTimeUtilTest.kt
+++ b/app/src/test/java/org/oppia/android/app/utility/datetime/DateTimeUtilTest.kt
@@ -70,6 +70,7 @@ import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
import org.oppia.android.util.logging.EnableConsoleLog
import org.oppia.android.util.logging.EnableFileLog
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.GlobalLogLevel
import org.oppia.android.util.logging.LogLevel
import org.oppia.android.util.logging.SyncStatusModule
@@ -186,7 +187,8 @@ class DateTimeUtilTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/app/src/test/java/org/oppia/android/app/utility/math/BUILD.bazel b/app/src/test/java/org/oppia/android/app/utility/math/BUILD.bazel
index 24a84596c68..0678f0fb9bd 100644
--- a/app/src/test/java/org/oppia/android/app/utility/math/BUILD.bazel
+++ b/app/src/test/java/org/oppia/android/app/utility/math/BUILD.bazel
@@ -44,6 +44,7 @@ oppia_android_test(
"//utility/src/main/java/org/oppia/android/util/caching/testing:caching_test_module",
"//utility/src/main/java/org/oppia/android/util/locale/testing:test_module",
"//utility/src/main/java/org/oppia/android/util/logging:prod_module",
+ "//utility/src/main/java/org/oppia/android/util/logging:standard_event_logging_configuration_module",
"//utility/src/main/java/org/oppia/android/util/logging/firebase:debug_module",
"//utility/src/main/java/org/oppia/android/util/math:math_expression_parser",
"//utility/src/main/java/org/oppia/android/util/networking:debug_module",
diff --git a/app/src/test/java/org/oppia/android/app/utility/math/MathExpressionAccessibilityUtilTest.kt b/app/src/test/java/org/oppia/android/app/utility/math/MathExpressionAccessibilityUtilTest.kt
index 293f8b0e94a..6b4ca0670ab 100644
--- a/app/src/test/java/org/oppia/android/app/utility/math/MathExpressionAccessibilityUtilTest.kt
+++ b/app/src/test/java/org/oppia/android/app/utility/math/MathExpressionAccessibilityUtilTest.kt
@@ -95,6 +95,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.testing.LocaleTestModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -1332,7 +1333,8 @@ class MathExpressionAccessibilityUtilTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/instrumentation/src/java/org/oppia/android/instrumentation/application/BUILD.bazel b/instrumentation/src/java/org/oppia/android/instrumentation/application/BUILD.bazel
index 78c15038969..97be8252f41 100644
--- a/instrumentation/src/java/org/oppia/android/instrumentation/application/BUILD.bazel
+++ b/instrumentation/src/java/org/oppia/android/instrumentation/application/BUILD.bazel
@@ -26,6 +26,7 @@ kt_android_library(
"//data/src/main/java/org/oppia/android/data/backends/gae:network_config_annotations",
"//domain",
"//utility",
+ "//utility/src/main/java/org/oppia/android/util/logging:standard_event_logging_configuration_module",
"//utility/src/main/java/org/oppia/android/util/logging/firebase:debug_module",
"//utility/src/main/java/org/oppia/android/util/networking:debug_module",
],
diff --git a/instrumentation/src/java/org/oppia/android/instrumentation/application/TestApplicationComponent.kt b/instrumentation/src/java/org/oppia/android/instrumentation/application/TestApplicationComponent.kt
index 7a95bcc6990..10561cc538e 100644
--- a/instrumentation/src/java/org/oppia/android/instrumentation/application/TestApplicationComponent.kt
+++ b/instrumentation/src/java/org/oppia/android/instrumentation/application/TestApplicationComponent.kt
@@ -48,6 +48,7 @@ import org.oppia.android.util.accessibility.AccessibilityProdModule
import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.CachingModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.DebugLogReportingModule
@@ -98,7 +99,7 @@ import javax.inject.Singleton
SyncStatusModule::class, NetworkConnectionDebugUtilModule::class,
MetricLogSchedulerModule::class, PerformanceMetricsLoggerModule::class,
PerformanceMetricsAssessorModule::class, PerformanceMetricsConfigurationsModule::class,
- TestingBuildFlavorModule::class
+ TestingBuildFlavorModule::class, EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/scripts/assets/test_file_exemptions.textproto b/scripts/assets/test_file_exemptions.textproto
index 8018118b950..336a15a6ba0 100644
--- a/scripts/assets/test_file_exemptions.textproto
+++ b/scripts/assets/test_file_exemptions.textproto
@@ -773,7 +773,9 @@ exempted_file_path: "utility/src/main/java/org/oppia/android/util/logging/Consol
exempted_file_path: "utility/src/main/java/org/oppia/android/util/logging/ConsoleLoggerInjector.kt"
exempted_file_path: "utility/src/main/java/org/oppia/android/util/logging/ConsoleLoggerInjectorProvider.kt"
exempted_file_path: "utility/src/main/java/org/oppia/android/util/logging/EventLogger.kt"
+exempted_file_path: "utility/src/main/java/org/oppia/android/util/logging/EventTypeToHumanReadableNameConverter.kt"
exempted_file_path: "utility/src/main/java/org/oppia/android/util/logging/ExceptionLogger.kt"
+exempted_file_path: "utility/src/main/java/org/oppia/android/util/logging/KenyaAlphaEventTypeToHumanReadableNameConverterImpl.kt"
exempted_file_path: "utility/src/main/java/org/oppia/android/util/logging/LogLevel.kt"
exempted_file_path: "utility/src/main/java/org/oppia/android/util/logging/LogUploader.kt"
exempted_file_path: "utility/src/main/java/org/oppia/android/util/logging/LoggerModule.kt"
diff --git a/testing/src/test/java/org/oppia/android/testing/junit/BUILD.bazel b/testing/src/test/java/org/oppia/android/testing/junit/BUILD.bazel
index cde8eeeb69a..1b4bcc4dc08 100644
--- a/testing/src/test/java/org/oppia/android/testing/junit/BUILD.bazel
+++ b/testing/src/test/java/org/oppia/android/testing/junit/BUILD.bazel
@@ -53,6 +53,7 @@ oppia_android_test(
"//utility/src/main/java/org/oppia/android/util/locale:prod_module",
"//utility/src/main/java/org/oppia/android/util/locale/testing:test_module",
"//utility/src/main/java/org/oppia/android/util/logging:prod_module",
+ "//utility/src/main/java/org/oppia/android/util/logging:standard_event_logging_configuration_module",
"//utility/src/main/java/org/oppia/android/util/logging/firebase:debug_module",
"//utility/src/main/java/org/oppia/android/util/networking:debug_module",
"//utility/src/main/java/org/oppia/android/util/networking:debug_util_module",
@@ -106,6 +107,7 @@ oppia_android_test(
"//utility/src/main/java/org/oppia/android/util/locale:prod_module",
"//utility/src/main/java/org/oppia/android/util/locale/testing:test_module",
"//utility/src/main/java/org/oppia/android/util/logging:prod_module",
+ "//utility/src/main/java/org/oppia/android/util/logging:standard_event_logging_configuration_module",
"//utility/src/main/java/org/oppia/android/util/logging/firebase:debug_module",
"//utility/src/main/java/org/oppia/android/util/networking:debug_module",
"//utility/src/main/java/org/oppia/android/util/networking:debug_util_module",
@@ -160,6 +162,7 @@ oppia_android_test(
"//utility/src/main/java/org/oppia/android/util/locale:prod_module",
"//utility/src/main/java/org/oppia/android/util/locale/testing:test_module",
"//utility/src/main/java/org/oppia/android/util/logging:prod_module",
+ "//utility/src/main/java/org/oppia/android/util/logging:standard_event_logging_configuration_module",
"//utility/src/main/java/org/oppia/android/util/logging/firebase:debug_module",
"//utility/src/main/java/org/oppia/android/util/networking:debug_module",
"//utility/src/main/java/org/oppia/android/util/networking:debug_util_module",
diff --git a/testing/src/test/java/org/oppia/android/testing/junit/InitializeDefaultLocaleRuleCustomContextTest.kt b/testing/src/test/java/org/oppia/android/testing/junit/InitializeDefaultLocaleRuleCustomContextTest.kt
index 0064df9d8cc..7185f15142e 100644
--- a/testing/src/test/java/org/oppia/android/testing/junit/InitializeDefaultLocaleRuleCustomContextTest.kt
+++ b/testing/src/test/java/org/oppia/android/testing/junit/InitializeDefaultLocaleRuleCustomContextTest.kt
@@ -67,6 +67,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -266,7 +267,8 @@ class InitializeDefaultLocaleRuleCustomContextTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/testing/src/test/java/org/oppia/android/testing/junit/InitializeDefaultLocaleRuleOmissionTest.kt b/testing/src/test/java/org/oppia/android/testing/junit/InitializeDefaultLocaleRuleOmissionTest.kt
index 4eeb5333f5c..5f2910069a9 100644
--- a/testing/src/test/java/org/oppia/android/testing/junit/InitializeDefaultLocaleRuleOmissionTest.kt
+++ b/testing/src/test/java/org/oppia/android/testing/junit/InitializeDefaultLocaleRuleOmissionTest.kt
@@ -65,6 +65,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -142,7 +143,8 @@ class InitializeDefaultLocaleRuleOmissionTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/testing/src/test/java/org/oppia/android/testing/junit/InitializeDefaultLocaleRuleTest.kt b/testing/src/test/java/org/oppia/android/testing/junit/InitializeDefaultLocaleRuleTest.kt
index 4cb60a9367a..4988c1218a1 100644
--- a/testing/src/test/java/org/oppia/android/testing/junit/InitializeDefaultLocaleRuleTest.kt
+++ b/testing/src/test/java/org/oppia/android/testing/junit/InitializeDefaultLocaleRuleTest.kt
@@ -68,6 +68,7 @@ import org.oppia.android.util.caching.AssetModule
import org.oppia.android.util.caching.testing.CachingTestModule
import org.oppia.android.util.gcsresource.GcsResourceModule
import org.oppia.android.util.locale.LocaleProdModule
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule
@@ -146,7 +147,8 @@ class InitializeDefaultLocaleRuleTest {
NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class,
MathEquationInputModule::class, SplitScreenInteractionModule::class,
LoggingIdentifierModule::class, ApplicationLifecycleModule::class,
- SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class
+ SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : ApplicationComponent {
diff --git a/utility/src/main/java/org/oppia/android/util/logging/BUILD.bazel b/utility/src/main/java/org/oppia/android/util/logging/BUILD.bazel
index 77c82bb3bf7..fb741426478 100644
--- a/utility/src/main/java/org/oppia/android/util/logging/BUILD.bazel
+++ b/utility/src/main/java/org/oppia/android/util/logging/BUILD.bazel
@@ -65,10 +65,12 @@ kt_android_library(
],
visibility = ["//:oppia_api_visibility"],
deps = [
+ ":event_type_to_human_readable_name_converter",
"//model/src/main/proto:event_logger_java_proto_lite",
"//model/src/main/proto:performance_metrics_event_logger_java_proto_lite",
"//third_party:javax_inject_javax_inject",
"//utility",
+ "//utility/src/main/java/org/oppia/android/util/extensions:context_extensions",
],
)
@@ -99,6 +101,16 @@ kt_android_library(
visibility = ["//:oppia_api_visibility"],
)
+kt_android_library(
+ name = "event_type_to_human_readable_name_converter",
+ srcs = [
+ "EventTypeToHumanReadableNameConverter.kt",
+ ],
+ deps = [
+ "//model/src/main/proto:event_logger_java_proto_lite",
+ ],
+)
+
kt_android_library(
name = "prod_module",
srcs = [
@@ -115,6 +127,32 @@ kt_android_library(
],
)
+kt_android_library(
+ name = "standard_event_logging_configuration_module",
+ srcs = [
+ "EventLoggingConfigurationModule.kt",
+ "StandardEventTypeToHumanReadableNameConverterImpl.kt",
+ ],
+ visibility = ["//:oppia_prod_module_visibility"],
+ deps = [
+ ":dagger",
+ ":event_type_to_human_readable_name_converter",
+ ],
+)
+
+kt_android_library(
+ name = "kenya_alpha_event_logging_configuration_module",
+ srcs = [
+ "KenyaAlphaEventLoggingConfigurationModule.kt",
+ "KenyaAlphaEventTypeToHumanReadableNameConverterImpl.kt",
+ ],
+ visibility = ["//:oppia_prod_module_visibility"],
+ deps = [
+ ":dagger",
+ ":event_type_to_human_readable_name_converter",
+ ],
+)
+
kt_android_library(
name = "log_uploader",
srcs = [
diff --git a/utility/src/main/java/org/oppia/android/util/logging/EventBundleCreator.kt b/utility/src/main/java/org/oppia/android/util/logging/EventBundleCreator.kt
index 3c2747e9ec9..bcc14836e73 100644
--- a/utility/src/main/java/org/oppia/android/util/logging/EventBundleCreator.kt
+++ b/utility/src/main/java/org/oppia/android/util/logging/EventBundleCreator.kt
@@ -1,5 +1,7 @@
package org.oppia.android.util.logging
+import android.content.Context
+import android.os.Build
import android.os.Bundle
import org.oppia.android.app.model.EventLog
import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.ACCESS_HINT_CONTEXT
@@ -39,6 +41,8 @@ import org.oppia.android.app.model.OppiaMetricLog.LoggableMetric.LoggableMetricT
import org.oppia.android.app.model.OppiaMetricLog.LoggableMetric.LoggableMetricTypeCase.NETWORK_USAGE_METRIC
import org.oppia.android.app.model.OppiaMetricLog.LoggableMetric.LoggableMetricTypeCase.STARTUP_LATENCY_METRIC
import org.oppia.android.app.model.OppiaMetricLog.LoggableMetric.LoggableMetricTypeCase.STORAGE_USAGE_METRIC
+import org.oppia.android.app.utility.getVersionCode
+import org.oppia.android.app.utility.getVersionName
import org.oppia.android.util.logging.EventBundleCreator.EventActivityContext.CardContext
import org.oppia.android.util.logging.EventBundleCreator.EventActivityContext.ConceptCardContext
import org.oppia.android.util.logging.EventBundleCreator.EventActivityContext.EmptyContext
@@ -61,6 +65,7 @@ import org.oppia.android.util.logging.EventBundleCreator.PerformanceMetricsLogga
import org.oppia.android.util.platformparameter.LearnerStudyAnalytics
import org.oppia.android.util.platformparameter.PlatformParameterValue
import javax.inject.Inject
+import javax.inject.Singleton
import org.oppia.android.app.model.EventLog.CardContext as CardEventContext
import org.oppia.android.app.model.EventLog.ConceptCardContext as ConceptCardEventContext
import org.oppia.android.app.model.EventLog.ExplorationContext as ExplorationEventContext
@@ -88,9 +93,16 @@ private const val MAX_CHARACTERS_IN_PARAMETER_NAME = 40
* This class is only expected to be used by internal logging mechanisms and should not be called
* directly.
*/
+@Singleton
class EventBundleCreator @Inject constructor(
+ private val context: Context,
+ private val eventTypeNameConverter: EventTypeToHumanReadableNameConverter,
@LearnerStudyAnalytics private val learnerStudyAnalytics: PlatformParameterValue
) {
+ private val androidSdkVersion by lazy { Build.VERSION.SDK_INT }
+ private val appVersionCode by lazy { context.getVersionCode() }
+ private val appVersionName by lazy { context.getVersionName() }
+
/**
* Fills the specified [bundle] with a logging-ready representation of [eventLog] and returns a
* string representation of the high-level type of event logged (per
@@ -99,10 +111,14 @@ class EventBundleCreator @Inject constructor(
fun fillEventBundle(eventLog: EventLog, bundle: Bundle): String {
bundle.putLong("timestamp", eventLog.timestamp)
bundle.putString("priority", eventLog.priority.toAnalyticsName())
- return eventLog.context.convertToActivityContext()?.also { eventContext ->
+ bundle.putInt("event_type", eventLog.context.activityContextCase.number)
+ bundle.putInt("android_sdk", androidSdkVersion)
+ bundle.putString("app_version_name", appVersionName)
+ bundle.putInt("app_version_code", appVersionCode)
+ return eventLog.context.convertToActivityContext().also { eventContext ->
// Only allow user IDs to be logged when the learner study feature is enabled.
eventContext.storeValue(PropertyStore(bundle, allowUserIds = learnerStudyAnalytics.value))
- }?.activityName ?: "unknown_activity_context"
+ }.activityName
}
/**
@@ -124,48 +140,39 @@ class EventBundleCreator @Inject constructor(
}?.metricName ?: "unknown_loggable_metric"
}
- private fun EventLog.Context.convertToActivityContext(): EventActivityContext<*>? {
+ private fun EventLog.Context.convertToActivityContext(): EventActivityContext<*> {
+ val activityName = eventTypeNameConverter.convertToHumanReadableName(activityContextCase)
return when (activityContextCase) {
- OPEN_EXPLORATION_ACTIVITY ->
- ExplorationContext("open_exploration_activity", openExplorationActivity)
- OPEN_INFO_TAB -> TopicContext("open_info_tab", openInfoTab)
- OPEN_LESSONS_TAB -> TopicContext("open_lessons_tab", openLessonsTab)
- OPEN_PRACTICE_TAB -> TopicContext("open_practice_tab", openPracticeTab)
- OPEN_REVISION_TAB -> TopicContext("open_revision_tab", openRevisionTab)
- OPEN_QUESTION_PLAYER -> QuestionContext("open_question_player", openQuestionPlayer)
- OPEN_STORY_ACTIVITY -> StoryContext("open_story_activity", openStoryActivity)
- OPEN_CONCEPT_CARD -> ConceptCardContext("open_concept_card", openConceptCard)
- OPEN_REVISION_CARD -> RevisionCardContext("open_revision_card", openRevisionCard)
- START_CARD_CONTEXT -> CardContext("start_card_context", startCardContext)
- END_CARD_CONTEXT -> CardContext("end_card_context", endCardContext)
- HINT_OFFERED_CONTEXT -> HintContext("hint_offered_context", hintOfferedContext)
- ACCESS_HINT_CONTEXT -> HintContext("access_hint_context", accessHintContext)
- SOLUTION_OFFERED_CONTEXT ->
- ExplorationContext("solution_offered_context", solutionOfferedContext)
- ACCESS_SOLUTION_CONTEXT ->
- ExplorationContext("access_solution_context", accessSolutionContext)
- SUBMIT_ANSWER_CONTEXT -> SubmitAnswerContext("submit_answer_context", submitAnswerContext)
- PLAY_VOICE_OVER_CONTEXT ->
- PlayVoiceOverContext("play_voice_over_context", playVoiceOverContext)
- APP_IN_BACKGROUND_CONTEXT ->
- LearnerDetailsContext("app_in_background_context", appInBackgroundContext)
- APP_IN_FOREGROUND_CONTEXT ->
- LearnerDetailsContext("app_in_foreground_context", appInForegroundContext)
- EXIT_EXPLORATION_CONTEXT ->
- ExplorationContext("exit_exploration_context", exitExplorationContext)
- FINISH_EXPLORATION_CONTEXT ->
- ExplorationContext("finish_exploration_context", finishExplorationContext)
- RESUME_EXPLORATION_CONTEXT ->
- LearnerDetailsContext("resume_exploration_context", resumeExplorationContext)
+ OPEN_EXPLORATION_ACTIVITY -> ExplorationContext(activityName, openExplorationActivity)
+ OPEN_INFO_TAB -> TopicContext(activityName, openInfoTab)
+ OPEN_LESSONS_TAB -> TopicContext(activityName, openLessonsTab)
+ OPEN_PRACTICE_TAB -> TopicContext(activityName, openPracticeTab)
+ OPEN_REVISION_TAB -> TopicContext(activityName, openRevisionTab)
+ OPEN_QUESTION_PLAYER -> QuestionContext(activityName, openQuestionPlayer)
+ OPEN_STORY_ACTIVITY -> StoryContext(activityName, openStoryActivity)
+ OPEN_CONCEPT_CARD -> ConceptCardContext(activityName, openConceptCard)
+ OPEN_REVISION_CARD -> RevisionCardContext(activityName, openRevisionCard)
+ START_CARD_CONTEXT -> CardContext(activityName, startCardContext)
+ END_CARD_CONTEXT -> CardContext(activityName, endCardContext)
+ HINT_OFFERED_CONTEXT -> HintContext(activityName, hintOfferedContext)
+ ACCESS_HINT_CONTEXT -> HintContext(activityName, accessHintContext)
+ SOLUTION_OFFERED_CONTEXT -> ExplorationContext(activityName, solutionOfferedContext)
+ ACCESS_SOLUTION_CONTEXT -> ExplorationContext(activityName, accessSolutionContext)
+ SUBMIT_ANSWER_CONTEXT -> SubmitAnswerContext(activityName, submitAnswerContext)
+ PLAY_VOICE_OVER_CONTEXT -> PlayVoiceOverContext(activityName, playVoiceOverContext)
+ APP_IN_BACKGROUND_CONTEXT -> LearnerDetailsContext(activityName, appInBackgroundContext)
+ APP_IN_FOREGROUND_CONTEXT -> LearnerDetailsContext(activityName, appInForegroundContext)
+ EXIT_EXPLORATION_CONTEXT -> ExplorationContext(activityName, exitExplorationContext)
+ FINISH_EXPLORATION_CONTEXT -> ExplorationContext(activityName, finishExplorationContext)
+ RESUME_EXPLORATION_CONTEXT -> LearnerDetailsContext(activityName, resumeExplorationContext)
START_OVER_EXPLORATION_CONTEXT ->
- LearnerDetailsContext("start_over_exploration_context", startOverExplorationContext)
- DELETE_PROFILE_CONTEXT ->
- LearnerDetailsContext("delete_profile_context", deleteProfileContext)
- OPEN_HOME -> EmptyContext("open_home")
- OPEN_PROFILE_CHOOSER -> EmptyContext("open_profile_chooser")
+ LearnerDetailsContext(activityName, startOverExplorationContext)
+ DELETE_PROFILE_CONTEXT -> LearnerDetailsContext(activityName, deleteProfileContext)
+ OPEN_HOME -> EmptyContext(activityName)
+ OPEN_PROFILE_CHOOSER -> EmptyContext(activityName)
INSTALL_ID_FOR_FAILED_ANALYTICS_LOG ->
- SensitiveStringContext("failed_analytics_log", installIdForFailedAnalyticsLog, "install_id")
- ACTIVITYCONTEXT_NOT_SET, null -> null // No context to create here.
+ SensitiveStringContext(activityName, installIdForFailedAnalyticsLog, "install_id")
+ ACTIVITYCONTEXT_NOT_SET, null -> EmptyContext(activityName) // No context to create here.
}
}
diff --git a/utility/src/main/java/org/oppia/android/util/logging/EventLoggingConfigurationModule.kt b/utility/src/main/java/org/oppia/android/util/logging/EventLoggingConfigurationModule.kt
new file mode 100644
index 00000000000..57c88d8d2c9
--- /dev/null
+++ b/utility/src/main/java/org/oppia/android/util/logging/EventLoggingConfigurationModule.kt
@@ -0,0 +1,13 @@
+package org.oppia.android.util.logging
+
+import dagger.Binds
+import dagger.Module
+
+/** Module to provide standard configurations for the event logging infrastructure. */
+@Module
+interface EventLoggingConfigurationModule {
+ @Binds
+ fun bindStandardEventTypeToHumanReadableNameConverter(
+ impl: StandardEventTypeToHumanReadableNameConverterImpl
+ ): EventTypeToHumanReadableNameConverter
+}
diff --git a/utility/src/main/java/org/oppia/android/util/logging/EventTypeToHumanReadableNameConverter.kt b/utility/src/main/java/org/oppia/android/util/logging/EventTypeToHumanReadableNameConverter.kt
new file mode 100644
index 00000000000..c6c3c849e40
--- /dev/null
+++ b/utility/src/main/java/org/oppia/android/util/logging/EventTypeToHumanReadableNameConverter.kt
@@ -0,0 +1,21 @@
+package org.oppia.android.util.logging
+
+import org.oppia.android.app.model.EventLog
+
+/**
+ * Converter for event types into loggable, human-readable names.
+ *
+ * Different builds of the app may leverage different implementations of this converter in order to
+ * customize the event names for querying purposes.
+ */
+interface EventTypeToHumanReadableNameConverter {
+ /**
+ * Returns a human-readable event name for the specified [eventType].
+ *
+ * Note that the same name should always be returned for a given event type within the same
+ * version of the app (though the names can change across versions). The returned name should not
+ * contain any personal information nor any information tied to users; they should be constant
+ * regardless of the current logged in/created profile state of the app.
+ */
+ fun convertToHumanReadableName(eventType: EventLog.Context.ActivityContextCase): String
+}
diff --git a/utility/src/main/java/org/oppia/android/util/logging/KenyaAlphaEventLoggingConfigurationModule.kt b/utility/src/main/java/org/oppia/android/util/logging/KenyaAlphaEventLoggingConfigurationModule.kt
new file mode 100644
index 00000000000..447525e5488
--- /dev/null
+++ b/utility/src/main/java/org/oppia/android/util/logging/KenyaAlphaEventLoggingConfigurationModule.kt
@@ -0,0 +1,16 @@
+package org.oppia.android.util.logging
+
+import dagger.Binds
+import dagger.Module
+
+/**
+ * Module to provide event logging infrastructure configurations specific to Kenya study alpha
+ * builds of the app.
+ */
+@Module
+interface KenyaAlphaEventLoggingConfigurationModule {
+ @Binds
+ fun bindKenyaAlphaSpecificEventTypeToHumanReadableNameConverter(
+ impl: KenyaAlphaEventTypeToHumanReadableNameConverterImpl
+ ): EventTypeToHumanReadableNameConverter
+}
diff --git a/utility/src/main/java/org/oppia/android/util/logging/KenyaAlphaEventTypeToHumanReadableNameConverterImpl.kt b/utility/src/main/java/org/oppia/android/util/logging/KenyaAlphaEventTypeToHumanReadableNameConverterImpl.kt
new file mode 100644
index 00000000000..d420258d726
--- /dev/null
+++ b/utility/src/main/java/org/oppia/android/util/logging/KenyaAlphaEventTypeToHumanReadableNameConverterImpl.kt
@@ -0,0 +1,48 @@
+package org.oppia.android.util.logging
+
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase
+import javax.inject.Inject
+
+// TODO(#4419): Remove this implementation and the extra piping for event name mapping.
+/**
+ * Implementation of [EventTypeToHumanReadableNameConverter] which provides legacy event names for
+ * interoperability with previously logged data in the Kenya user study.
+ *
+ * The event names provided by this implementation are expected to never change as these names are
+ * the primary ways each corresponding event is identified in logged event queries.
+ */
+class KenyaAlphaEventTypeToHumanReadableNameConverterImpl @Inject constructor() :
+ EventTypeToHumanReadableNameConverter {
+ override fun convertToHumanReadableName(eventType: ActivityContextCase): String {
+ return when (eventType) {
+ ActivityContextCase.OPEN_EXPLORATION_ACTIVITY -> "open_exploration_activity"
+ ActivityContextCase.OPEN_INFO_TAB -> "open_info_tab"
+ ActivityContextCase.OPEN_LESSONS_TAB -> "open_lessons_tab"
+ ActivityContextCase.OPEN_PRACTICE_TAB -> "open_practice_tab"
+ ActivityContextCase.OPEN_REVISION_TAB -> "open_revision_tab"
+ ActivityContextCase.OPEN_QUESTION_PLAYER -> "open_question_player"
+ ActivityContextCase.OPEN_STORY_ACTIVITY -> "open_story_activity"
+ ActivityContextCase.OPEN_CONCEPT_CARD -> "open_concept_card"
+ ActivityContextCase.OPEN_REVISION_CARD -> "open_revision_card"
+ ActivityContextCase.START_CARD_CONTEXT -> "start_card_context"
+ ActivityContextCase.END_CARD_CONTEXT -> "end_card_context"
+ ActivityContextCase.HINT_OFFERED_CONTEXT -> "hint_offered_context"
+ ActivityContextCase.ACCESS_HINT_CONTEXT -> "access_hint_context"
+ ActivityContextCase.SOLUTION_OFFERED_CONTEXT -> "solution_offered_context"
+ ActivityContextCase.ACCESS_SOLUTION_CONTEXT -> "access_solution_context"
+ ActivityContextCase.SUBMIT_ANSWER_CONTEXT -> "submit_answer_context"
+ ActivityContextCase.PLAY_VOICE_OVER_CONTEXT -> "play_voice_over_context"
+ ActivityContextCase.APP_IN_BACKGROUND_CONTEXT -> "app_in_background_context"
+ ActivityContextCase.APP_IN_FOREGROUND_CONTEXT -> "app_in_foreground_context"
+ ActivityContextCase.EXIT_EXPLORATION_CONTEXT -> "exit_exploration_context"
+ ActivityContextCase.FINISH_EXPLORATION_CONTEXT -> "finish_exploration_context"
+ ActivityContextCase.RESUME_EXPLORATION_CONTEXT -> "resume_exploration_context"
+ ActivityContextCase.START_OVER_EXPLORATION_CONTEXT -> "start_over_exploration_context"
+ ActivityContextCase.DELETE_PROFILE_CONTEXT -> "delete_profile_context"
+ ActivityContextCase.OPEN_HOME -> "open_home"
+ ActivityContextCase.OPEN_PROFILE_CHOOSER -> "open_profile_chooser"
+ ActivityContextCase.INSTALL_ID_FOR_FAILED_ANALYTICS_LOG -> "failed_analytics_log"
+ ActivityContextCase.ACTIVITYCONTEXT_NOT_SET -> "unknown_activity_context"
+ }
+ }
+}
diff --git a/utility/src/main/java/org/oppia/android/util/logging/StandardEventTypeToHumanReadableNameConverterImpl.kt b/utility/src/main/java/org/oppia/android/util/logging/StandardEventTypeToHumanReadableNameConverterImpl.kt
new file mode 100644
index 00000000000..3b3251bc852
--- /dev/null
+++ b/utility/src/main/java/org/oppia/android/util/logging/StandardEventTypeToHumanReadableNameConverterImpl.kt
@@ -0,0 +1,58 @@
+package org.oppia.android.util.logging
+
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase
+import javax.inject.Inject
+
+/**
+ * Implementation of [EventTypeToHumanReadableNameConverter] which provides well-named
+ * representations for each event type.
+ *
+ * The provided names may be changed over time as the broad standard for event names evolves with
+ * new and changed events. The general convention for event names is a second person singular
+ * conjugated action verb followed by the action, context, or both, that the user conducted that led
+ * to that event. Furthermore, efforts are taken to reduce referencing Android-specific terminology
+ * (e.g. 'screen' is used in place of 'activity').
+ *
+ * Event names cannot exceed 40 characters, so care should be taken to ensure only the most
+ * important information is conveyed via the name.
+ *
+ * Finally, the provided event names are only meant to help simplify analyzing logged events. Since
+ * they can change, aggregation or dimensional slicing of events should occur by keying on the
+ * event's integral type rather than its name (as this type will remain fixed for the lifetime of a
+ * given event, unlike its name returned by this implementation).
+ */
+class StandardEventTypeToHumanReadableNameConverterImpl @Inject constructor() :
+ EventTypeToHumanReadableNameConverter {
+ override fun convertToHumanReadableName(eventType: ActivityContextCase): String {
+ return when (eventType) {
+ ActivityContextCase.OPEN_EXPLORATION_ACTIVITY -> "open_exploration_player_screen"
+ ActivityContextCase.OPEN_INFO_TAB -> "select_topic_info_tab"
+ ActivityContextCase.OPEN_LESSONS_TAB -> "select_topic_lessons_tab"
+ ActivityContextCase.OPEN_PRACTICE_TAB -> "select_topic_practice_tab"
+ ActivityContextCase.OPEN_REVISION_TAB -> "select_topic_revision_tab"
+ ActivityContextCase.OPEN_QUESTION_PLAYER -> "open_question_player_screen"
+ ActivityContextCase.OPEN_STORY_ACTIVITY -> "open_story_chapter_list_screen"
+ ActivityContextCase.OPEN_CONCEPT_CARD -> "open_concept_card"
+ ActivityContextCase.OPEN_REVISION_CARD -> "open_revision_card"
+ ActivityContextCase.START_CARD_CONTEXT -> "start_exploration_card"
+ ActivityContextCase.END_CARD_CONTEXT -> "end_exploration_card"
+ ActivityContextCase.HINT_OFFERED_CONTEXT -> "receive_hint_offer"
+ ActivityContextCase.ACCESS_HINT_CONTEXT -> "reveal_hint"
+ ActivityContextCase.SOLUTION_OFFERED_CONTEXT -> "receive_solution_offer"
+ ActivityContextCase.ACCESS_SOLUTION_CONTEXT -> "reveal_solution"
+ ActivityContextCase.SUBMIT_ANSWER_CONTEXT -> "submit_answer"
+ ActivityContextCase.PLAY_VOICE_OVER_CONTEXT -> "click_play_voiceover_button"
+ ActivityContextCase.APP_IN_BACKGROUND_CONTEXT -> "send_app_to_background"
+ ActivityContextCase.APP_IN_FOREGROUND_CONTEXT -> "bring_app_to_foreground"
+ ActivityContextCase.EXIT_EXPLORATION_CONTEXT -> "leave_exploration"
+ ActivityContextCase.FINISH_EXPLORATION_CONTEXT -> "complete_exploration"
+ ActivityContextCase.RESUME_EXPLORATION_CONTEXT -> "resume_in_progress_exploration"
+ ActivityContextCase.START_OVER_EXPLORATION_CONTEXT -> "restart_in_progress_exploration"
+ ActivityContextCase.DELETE_PROFILE_CONTEXT -> "delete_profile"
+ ActivityContextCase.OPEN_HOME -> "open_home_screen"
+ ActivityContextCase.OPEN_PROFILE_CHOOSER -> "open_profile_chooser_screen"
+ ActivityContextCase.INSTALL_ID_FOR_FAILED_ANALYTICS_LOG,
+ ActivityContextCase.ACTIVITYCONTEXT_NOT_SET -> "ERROR_internal_logging_failure"
+ }
+ }
+}
diff --git a/utility/src/main/java/org/oppia/android/util/logging/performancemetrics/BUILD.bazel b/utility/src/main/java/org/oppia/android/util/logging/performancemetrics/BUILD.bazel
index 3e83fdcdb06..418b0023956 100644
--- a/utility/src/main/java/org/oppia/android/util/logging/performancemetrics/BUILD.bazel
+++ b/utility/src/main/java/org/oppia/android/util/logging/performancemetrics/BUILD.bazel
@@ -46,7 +46,7 @@ kt_android_library(
srcs = [
"PerformanceMetricsAssessorImpl.kt",
],
- visibility = ["//:oppia_api_visibility"],
+ visibility = ["//:oppia_testing_visibility"],
deps = [
":performance_metrics_assessor",
":performance_metrics_configurations_module",
diff --git a/utility/src/test/java/org/oppia/android/util/logging/BUILD.bazel b/utility/src/test/java/org/oppia/android/util/logging/BUILD.bazel
new file mode 100644
index 00000000000..b08d52bccaf
--- /dev/null
+++ b/utility/src/test/java/org/oppia/android/util/logging/BUILD.bazel
@@ -0,0 +1,122 @@
+"""
+Tests for logging utilities.
+"""
+
+load("@dagger//:workspace_defs.bzl", "dagger_rules")
+load("//:oppia_android_test.bzl", "oppia_android_test")
+
+oppia_android_test(
+ name = "EventBundleCreatorTest",
+ srcs = ["EventBundleCreatorTest.kt"],
+ custom_package = "org.oppia.android.util.logging",
+ test_class = "org.oppia.android.util.logging.EventBundleCreatorTest",
+ test_manifest = "//utility:test_manifest",
+ deps = [
+ ":dagger",
+ "//testing",
+ "//third_party:androidx_test_ext_junit",
+ "//third_party:androidx_test_ext_truth",
+ "//third_party:com_google_truth_truth",
+ "//third_party:org_robolectric_robolectric",
+ "//third_party:robolectric_android-all",
+ "//utility/src/main/java/org/oppia/android/util/logging:event_bundle_creator",
+ "//utility/src/main/java/org/oppia/android/util/logging:standard_event_logging_configuration_module",
+ ],
+)
+
+oppia_android_test(
+ name = "EventLoggingConfigurationModuleTest",
+ srcs = ["EventLoggingConfigurationModuleTest.kt"],
+ custom_package = "org.oppia.android.util.logging",
+ test_class = "org.oppia.android.util.logging.EventLoggingConfigurationModuleTest",
+ test_manifest = "//utility:test_manifest",
+ deps = [
+ ":dagger",
+ "//testing",
+ "//third_party:androidx_test_ext_junit",
+ "//third_party:androidx_test_ext_truth",
+ "//third_party:com_google_truth_truth",
+ "//third_party:org_robolectric_robolectric",
+ "//third_party:robolectric_android-all",
+ "//utility/src/main/java/org/oppia/android/util/logging:standard_event_logging_configuration_module",
+ ],
+)
+
+oppia_android_test(
+ name = "KenyaAlphaEventBundleCreatorTest",
+ srcs = ["KenyaAlphaEventBundleCreatorTest.kt"],
+ custom_package = "org.oppia.android.util.logging",
+ test_class = "org.oppia.android.util.logging.KenyaAlphaEventBundleCreatorTest",
+ test_manifest = "//utility:test_manifest",
+ deps = [
+ ":dagger",
+ "//testing",
+ "//third_party:androidx_test_ext_junit",
+ "//third_party:androidx_test_ext_truth",
+ "//third_party:com_google_truth_truth",
+ "//third_party:org_robolectric_robolectric",
+ "//third_party:robolectric_android-all",
+ "//utility/src/main/java/org/oppia/android/util/logging:event_bundle_creator",
+ "//utility/src/main/java/org/oppia/android/util/logging:kenya_alpha_event_logging_configuration_module",
+ ],
+)
+
+oppia_android_test(
+ name = "KenyaAlphaEventLoggingConfigurationModuleTest",
+ srcs = ["KenyaAlphaEventLoggingConfigurationModuleTest.kt"],
+ custom_package = "org.oppia.android.util.logging",
+ test_class = "org.oppia.android.util.logging.KenyaAlphaEventLoggingConfigurationModuleTest",
+ test_manifest = "//utility:test_manifest",
+ deps = [
+ ":dagger",
+ "//testing",
+ "//third_party:androidx_test_ext_junit",
+ "//third_party:androidx_test_ext_truth",
+ "//third_party:com_google_truth_truth",
+ "//third_party:org_robolectric_robolectric",
+ "//third_party:robolectric_android-all",
+ "//utility/src/main/java/org/oppia/android/util/logging:kenya_alpha_event_logging_configuration_module",
+ ],
+)
+
+oppia_android_test(
+ name = "StandardEventTypeToHumanReadableNameConverterImplTest",
+ srcs = ["StandardEventTypeToHumanReadableNameConverterImplTest.kt"],
+ custom_package = "org.oppia.android.util.logging",
+ test_class = "org.oppia.android.util.logging.StandardEventTypeToHumanReadableNameConverterImplTest",
+ test_manifest = "//utility:test_manifest",
+ deps = [
+ ":dagger",
+ "//testing",
+ "//third_party:androidx_test_ext_junit",
+ "//third_party:com_google_truth_truth",
+ "//third_party:org_robolectric_robolectric",
+ "//third_party:robolectric_android-all",
+ "//utility/src/main/java/org/oppia/android/util/logging:standard_event_logging_configuration_module",
+ ],
+)
+
+oppia_android_test(
+ name = "SyncStatusManagerImplTest",
+ srcs = ["SyncStatusManagerImplTest.kt"],
+ custom_package = "org.oppia.android.util.logging",
+ test_class = "org.oppia.android.util.logging.SyncStatusManagerImplTest",
+ test_manifest = "//utility:test_manifest",
+ deps = [
+ ":dagger",
+ "//testing",
+ "//testing/src/main/java/org/oppia/android/testing/data:data_provider_test_monitor",
+ "//testing/src/main/java/org/oppia/android/testing/robolectric:test_module",
+ "//testing/src/main/java/org/oppia/android/testing/threading:test_module",
+ "//testing/src/main/java/org/oppia/android/testing/time:test_module",
+ "//third_party:androidx_test_ext_junit",
+ "//third_party:com_google_truth_truth",
+ "//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",
+ ],
+)
+
+dagger_rules()
diff --git a/utility/src/test/java/org/oppia/android/util/logging/EventBundleCreatorTest.kt b/utility/src/test/java/org/oppia/android/util/logging/EventBundleCreatorTest.kt
index f9067c27f4c..df24c319f90 100644
--- a/utility/src/test/java/org/oppia/android/util/logging/EventBundleCreatorTest.kt
+++ b/utility/src/test/java/org/oppia/android/util/logging/EventBundleCreatorTest.kt
@@ -4,6 +4,8 @@ import android.app.Application
import android.content.Context
import android.os.Bundle
import androidx.test.core.app.ApplicationProvider
+import androidx.test.core.content.pm.ApplicationInfoBuilder
+import androidx.test.core.content.pm.PackageInfoBuilder
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.ext.truth.os.BundleSubject.assertThat
import com.google.common.truth.Truth.assertThat
@@ -17,6 +19,34 @@ import org.junit.runner.RunWith
import org.oppia.android.app.model.EventLog
import org.oppia.android.app.model.EventLog.CardContext
import org.oppia.android.app.model.EventLog.ConceptCardContext
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.ACCESS_HINT_CONTEXT
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.ACCESS_SOLUTION_CONTEXT
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.ACTIVITYCONTEXT_NOT_SET
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.APP_IN_BACKGROUND_CONTEXT
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.APP_IN_FOREGROUND_CONTEXT
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.DELETE_PROFILE_CONTEXT
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.END_CARD_CONTEXT
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.EXIT_EXPLORATION_CONTEXT
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.FINISH_EXPLORATION_CONTEXT
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.HINT_OFFERED_CONTEXT
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.INSTALL_ID_FOR_FAILED_ANALYTICS_LOG
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.OPEN_CONCEPT_CARD
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.OPEN_EXPLORATION_ACTIVITY
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.OPEN_HOME
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.OPEN_INFO_TAB
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.OPEN_LESSONS_TAB
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.OPEN_PRACTICE_TAB
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.OPEN_PROFILE_CHOOSER
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.OPEN_QUESTION_PLAYER
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.OPEN_REVISION_CARD
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.OPEN_REVISION_TAB
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.OPEN_STORY_ACTIVITY
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.PLAY_VOICE_OVER_CONTEXT
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.RESUME_EXPLORATION_CONTEXT
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.SOLUTION_OFFERED_CONTEXT
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.START_CARD_CONTEXT
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.START_OVER_EXPLORATION_CONTEXT
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.SUBMIT_ANSWER_CONTEXT
import org.oppia.android.app.model.EventLog.ExplorationContext
import org.oppia.android.app.model.EventLog.HintContext
import org.oppia.android.app.model.EventLog.LearnerDetailsContext
@@ -48,12 +78,15 @@ import org.oppia.android.app.model.OppiaMetricLog.StorageTier.MEDIUM_STORAGE
import org.oppia.android.util.platformparameter.LEARNER_STUDY_ANALYTICS_DEFAULT_VALUE
import org.oppia.android.util.platformparameter.LearnerStudyAnalytics
import org.oppia.android.util.platformparameter.PlatformParameterValue
+import org.robolectric.Shadows
import org.robolectric.annotation.Config
import org.robolectric.annotation.LooperMode
import javax.inject.Inject
import javax.inject.Singleton
import org.oppia.android.app.model.EventLog.Context.Builder as EventContextBuilder
+private const val TEST_ANDROID_SDK_VERSION = 30
+
/**
* Tests for [EventBundleCreator].
*
@@ -67,7 +100,10 @@ import org.oppia.android.app.model.EventLog.Context.Builder as EventContextBuild
@Suppress("FunctionName")
@RunWith(AndroidJUnit4::class)
@LooperMode(LooperMode.Mode.PAUSED)
-@Config(application = EventBundleCreatorTest.TestApplication::class)
+@Config(
+ application = EventBundleCreatorTest.TestApplication::class,
+ sdk = [TEST_ANDROID_SDK_VERSION]
+)
class EventBundleCreatorTest {
private companion object {
private const val TEST_TIMESTAMP_1 = 1556094120000
@@ -91,6 +127,8 @@ class EventBundleCreatorTest {
private const val TEST_IS_ANSWER_CORRECT = true
private const val TEST_IS_ANSWER_CORRECT_STR = "true"
private const val TEST_CONTENT_ID = "test_content_id"
+ private const val TEST_APP_VERSION_NAME = "oppia-android-test-0123456789"
+ private const val TEST_APP_VERSION_CODE = 125
private const val TEST_CPU_USAGE = Long.MAX_VALUE
private const val TEST_APK_SIZE = Long.MAX_VALUE
private const val TEST_STORAGE_USAGE = Long.MAX_VALUE
@@ -99,8 +137,8 @@ class EventBundleCreatorTest {
private const val TEST_MEMORY_USAGE = Long.MAX_VALUE
}
- @Inject
- lateinit var eventBundleCreator: EventBundleCreator
+ @Inject lateinit var context: Context
+ @Inject lateinit var eventBundleCreator: EventBundleCreator
@After
fun tearDown() {
@@ -114,10 +152,14 @@ class EventBundleCreatorTest {
val typeName = eventBundleCreator.fillEventBundle(EventLog.getDefaultInstance(), bundle)
- assertThat(typeName).isEqualTo("unknown_activity_context")
- assertThat(bundle).hasSize(2)
+ assertThat(typeName).isEqualTo("ERROR_internal_logging_failure")
+ assertThat(bundle).hasSize(6)
assertThat(bundle).longInt("timestamp").isEqualTo(0)
assertThat(bundle).string("priority").isEqualTo("unspecified_priority")
+ assertThat(bundle).integer("event_type").isEqualTo(ACTIVITYCONTEXT_NOT_SET.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
}
@Test
@@ -148,10 +190,14 @@ class EventBundleCreatorTest {
val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
- assertThat(typeName).isEqualTo("unknown_activity_context")
- assertThat(bundle).hasSize(2)
+ assertThat(typeName).isEqualTo("ERROR_internal_logging_failure")
+ assertThat(bundle).hasSize(6)
assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(ACTIVITYCONTEXT_NOT_SET.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
}
@Test
@@ -296,10 +342,14 @@ class EventBundleCreatorTest {
val eventLog = createEventLog(context = createOpenExplorationActivity())
val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
- assertThat(typeName).isEqualTo("open_exploration_activity")
- assertThat(bundle).hasSize(8)
+ assertThat(typeName).isEqualTo("open_exploration_player_screen")
+ assertThat(bundle).hasSize(12)
assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(OPEN_EXPLORATION_ACTIVITY.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
assertThat(bundle).string("topic_id").isEqualTo(TEST_TOPIC_ID)
assertThat(bundle).string("story_id").isEqualTo(TEST_STORY_ID)
assertThat(bundle).string("exploration_id").isEqualTo(TEST_EXPLORATION_ID)
@@ -316,10 +366,14 @@ class EventBundleCreatorTest {
val eventLog = createEventLog(context = createOpenExplorationActivity())
val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
- assertThat(typeName).isEqualTo("open_exploration_activity")
- assertThat(bundle).hasSize(10)
+ assertThat(typeName).isEqualTo("open_exploration_player_screen")
+ assertThat(bundle).hasSize(14)
assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(OPEN_EXPLORATION_ACTIVITY.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
assertThat(bundle).string("topic_id").isEqualTo(TEST_TOPIC_ID)
assertThat(bundle).string("story_id").isEqualTo(TEST_STORY_ID)
assertThat(bundle).string("exploration_id").isEqualTo(TEST_EXPLORATION_ID)
@@ -338,10 +392,14 @@ class EventBundleCreatorTest {
val eventLog = createEventLog(context = createOpenInfoTab())
val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
- assertThat(typeName).isEqualTo("open_info_tab")
- assertThat(bundle).hasSize(3)
+ assertThat(typeName).isEqualTo("select_topic_info_tab")
+ assertThat(bundle).hasSize(7)
assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(OPEN_INFO_TAB.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
assertThat(bundle).string("topic_id").isEqualTo(TEST_TOPIC_ID)
}
@@ -353,10 +411,14 @@ class EventBundleCreatorTest {
val eventLog = createEventLog(context = createOpenLessonsTab())
val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
- assertThat(typeName).isEqualTo("open_lessons_tab")
- assertThat(bundle).hasSize(3)
+ assertThat(typeName).isEqualTo("select_topic_lessons_tab")
+ assertThat(bundle).hasSize(7)
assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(OPEN_LESSONS_TAB.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
assertThat(bundle).string("topic_id").isEqualTo(TEST_TOPIC_ID)
}
@@ -513,10 +575,14 @@ class EventBundleCreatorTest {
val eventLog = createEventLog(context = createOpenPracticeTab())
val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
- assertThat(typeName).isEqualTo("open_practice_tab")
- assertThat(bundle).hasSize(3)
+ assertThat(typeName).isEqualTo("select_topic_practice_tab")
+ assertThat(bundle).hasSize(7)
assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(OPEN_PRACTICE_TAB.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
assertThat(bundle).string("topic_id").isEqualTo(TEST_TOPIC_ID)
}
@@ -528,10 +594,14 @@ class EventBundleCreatorTest {
val eventLog = createEventLog(context = createOpenRevisionTab())
val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
- assertThat(typeName).isEqualTo("open_revision_tab")
- assertThat(bundle).hasSize(3)
+ assertThat(typeName).isEqualTo("select_topic_revision_tab")
+ assertThat(bundle).hasSize(7)
assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(OPEN_REVISION_TAB.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
assertThat(bundle).string("topic_id").isEqualTo(TEST_TOPIC_ID)
}
@@ -543,10 +613,14 @@ class EventBundleCreatorTest {
val eventLog = createEventLog(context = createOpenQuestionPlayer())
val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
- assertThat(typeName).isEqualTo("open_question_player")
- assertThat(bundle).hasSize(4)
+ assertThat(typeName).isEqualTo("open_question_player_screen")
+ assertThat(bundle).hasSize(8)
assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(OPEN_QUESTION_PLAYER.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
assertThat(bundle).string("question_id").isEqualTo(TEST_QUESTION_ID)
assertThat(bundle).string("skill_ids").isEqualTo("$TEST_SKILL_ID_1,$TEST_SKILL_ID_2")
}
@@ -559,10 +633,14 @@ class EventBundleCreatorTest {
val eventLog = createEventLog(context = createOpenStoryActivity())
val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
- assertThat(typeName).isEqualTo("open_story_activity")
- assertThat(bundle).hasSize(4)
+ assertThat(typeName).isEqualTo("open_story_chapter_list_screen")
+ assertThat(bundle).hasSize(8)
assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(OPEN_STORY_ACTIVITY.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
assertThat(bundle).string("topic_id").isEqualTo(TEST_TOPIC_ID)
assertThat(bundle).string("story_id").isEqualTo(TEST_STORY_ID)
}
@@ -576,9 +654,13 @@ class EventBundleCreatorTest {
val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
assertThat(typeName).isEqualTo("open_concept_card")
- assertThat(bundle).hasSize(3)
+ assertThat(bundle).hasSize(7)
assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(OPEN_CONCEPT_CARD.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
assertThat(bundle).string("skill_id").isEqualTo(TEST_SKILL_ID_1)
}
@@ -591,9 +673,13 @@ class EventBundleCreatorTest {
val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
assertThat(typeName).isEqualTo("open_revision_card")
- assertThat(bundle).hasSize(4)
+ assertThat(bundle).hasSize(8)
assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(OPEN_REVISION_CARD.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
assertThat(bundle).string("topic_id").isEqualTo(TEST_TOPIC_ID)
assertThat(bundle).string("subtopic_index").isEqualTo(TEST_SUB_TOPIC_INDEX_STR)
}
@@ -606,10 +692,14 @@ class EventBundleCreatorTest {
val eventLog = createEventLog(context = createStartCardContext())
val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
- assertThat(typeName).isEqualTo("start_card_context")
- assertThat(bundle).hasSize(9)
+ assertThat(typeName).isEqualTo("start_exploration_card")
+ assertThat(bundle).hasSize(13)
assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(START_CARD_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
assertThat(bundle).string("ed_topic_id").isEqualTo(TEST_TOPIC_ID)
assertThat(bundle).string("ed_story_id").isEqualTo(TEST_STORY_ID)
assertThat(bundle).string("ed_exploration_id").isEqualTo(TEST_EXPLORATION_ID)
@@ -627,10 +717,14 @@ class EventBundleCreatorTest {
val eventLog = createEventLog(context = createStartCardContext())
val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
- assertThat(typeName).isEqualTo("start_card_context")
- assertThat(bundle).hasSize(11)
+ assertThat(typeName).isEqualTo("start_exploration_card")
+ assertThat(bundle).hasSize(15)
assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(START_CARD_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
assertThat(bundle).string("ed_topic_id").isEqualTo(TEST_TOPIC_ID)
assertThat(bundle).string("ed_story_id").isEqualTo(TEST_STORY_ID)
assertThat(bundle).string("ed_exploration_id").isEqualTo(TEST_EXPLORATION_ID)
@@ -650,10 +744,14 @@ class EventBundleCreatorTest {
val eventLog = createEventLog(context = createEndCardContext())
val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
- assertThat(typeName).isEqualTo("end_card_context")
- assertThat(bundle).hasSize(9)
+ assertThat(typeName).isEqualTo("end_exploration_card")
+ assertThat(bundle).hasSize(13)
assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(END_CARD_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
assertThat(bundle).string("ed_topic_id").isEqualTo(TEST_TOPIC_ID)
assertThat(bundle).string("ed_story_id").isEqualTo(TEST_STORY_ID)
assertThat(bundle).string("ed_exploration_id").isEqualTo(TEST_EXPLORATION_ID)
@@ -671,10 +769,14 @@ class EventBundleCreatorTest {
val eventLog = createEventLog(context = createEndCardContext())
val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
- assertThat(typeName).isEqualTo("end_card_context")
- assertThat(bundle).hasSize(11)
+ assertThat(typeName).isEqualTo("end_exploration_card")
+ assertThat(bundle).hasSize(15)
assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(END_CARD_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
assertThat(bundle).string("ed_topic_id").isEqualTo(TEST_TOPIC_ID)
assertThat(bundle).string("ed_story_id").isEqualTo(TEST_STORY_ID)
assertThat(bundle).string("ed_exploration_id").isEqualTo(TEST_EXPLORATION_ID)
@@ -694,10 +796,14 @@ class EventBundleCreatorTest {
val eventLog = createEventLog(context = createHintOfferedContext())
val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
- assertThat(typeName).isEqualTo("hint_offered_context")
- assertThat(bundle).hasSize(9)
+ assertThat(typeName).isEqualTo("receive_hint_offer")
+ assertThat(bundle).hasSize(13)
assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(HINT_OFFERED_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
assertThat(bundle).string("ed_topic_id").isEqualTo(TEST_TOPIC_ID)
assertThat(bundle).string("ed_story_id").isEqualTo(TEST_STORY_ID)
assertThat(bundle).string("ed_exploration_id").isEqualTo(TEST_EXPLORATION_ID)
@@ -715,10 +821,14 @@ class EventBundleCreatorTest {
val eventLog = createEventLog(context = createHintOfferedContext())
val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
- assertThat(typeName).isEqualTo("hint_offered_context")
- assertThat(bundle).hasSize(11)
+ assertThat(typeName).isEqualTo("receive_hint_offer")
+ assertThat(bundle).hasSize(15)
assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(HINT_OFFERED_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
assertThat(bundle).string("ed_topic_id").isEqualTo(TEST_TOPIC_ID)
assertThat(bundle).string("ed_story_id").isEqualTo(TEST_STORY_ID)
assertThat(bundle).string("ed_exploration_id").isEqualTo(TEST_EXPLORATION_ID)
@@ -738,10 +848,14 @@ class EventBundleCreatorTest {
val eventLog = createEventLog(context = createAccessHintContext())
val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
- assertThat(typeName).isEqualTo("access_hint_context")
- assertThat(bundle).hasSize(9)
+ assertThat(typeName).isEqualTo("reveal_hint")
+ assertThat(bundle).hasSize(13)
assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(ACCESS_HINT_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
assertThat(bundle).string("ed_topic_id").isEqualTo(TEST_TOPIC_ID)
assertThat(bundle).string("ed_story_id").isEqualTo(TEST_STORY_ID)
assertThat(bundle).string("ed_exploration_id").isEqualTo(TEST_EXPLORATION_ID)
@@ -759,10 +873,14 @@ class EventBundleCreatorTest {
val eventLog = createEventLog(context = createAccessHintContext())
val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
- assertThat(typeName).isEqualTo("access_hint_context")
- assertThat(bundle).hasSize(11)
+ assertThat(typeName).isEqualTo("reveal_hint")
+ assertThat(bundle).hasSize(15)
assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(ACCESS_HINT_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
assertThat(bundle).string("ed_topic_id").isEqualTo(TEST_TOPIC_ID)
assertThat(bundle).string("ed_story_id").isEqualTo(TEST_STORY_ID)
assertThat(bundle).string("ed_exploration_id").isEqualTo(TEST_EXPLORATION_ID)
@@ -782,10 +900,14 @@ class EventBundleCreatorTest {
val eventLog = createEventLog(context = createSolutionOfferedContext())
val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
- assertThat(typeName).isEqualTo("solution_offered_context")
- assertThat(bundle).hasSize(8)
+ assertThat(typeName).isEqualTo("receive_solution_offer")
+ assertThat(bundle).hasSize(12)
assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(SOLUTION_OFFERED_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
assertThat(bundle).string("topic_id").isEqualTo(TEST_TOPIC_ID)
assertThat(bundle).string("story_id").isEqualTo(TEST_STORY_ID)
assertThat(bundle).string("exploration_id").isEqualTo(TEST_EXPLORATION_ID)
@@ -802,10 +924,14 @@ class EventBundleCreatorTest {
val eventLog = createEventLog(context = createSolutionOfferedContext())
val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
- assertThat(typeName).isEqualTo("solution_offered_context")
- assertThat(bundle).hasSize(10)
+ assertThat(typeName).isEqualTo("receive_solution_offer")
+ assertThat(bundle).hasSize(14)
assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(SOLUTION_OFFERED_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
assertThat(bundle).string("topic_id").isEqualTo(TEST_TOPIC_ID)
assertThat(bundle).string("story_id").isEqualTo(TEST_STORY_ID)
assertThat(bundle).string("exploration_id").isEqualTo(TEST_EXPLORATION_ID)
@@ -824,10 +950,14 @@ class EventBundleCreatorTest {
val eventLog = createEventLog(context = createAccessSolutionContext())
val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
- assertThat(typeName).isEqualTo("access_solution_context")
- assertThat(bundle).hasSize(8)
+ assertThat(typeName).isEqualTo("reveal_solution")
+ assertThat(bundle).hasSize(12)
assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(ACCESS_SOLUTION_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
assertThat(bundle).string("topic_id").isEqualTo(TEST_TOPIC_ID)
assertThat(bundle).string("story_id").isEqualTo(TEST_STORY_ID)
assertThat(bundle).string("exploration_id").isEqualTo(TEST_EXPLORATION_ID)
@@ -844,10 +974,14 @@ class EventBundleCreatorTest {
val eventLog = createEventLog(context = createAccessSolutionContext())
val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
- assertThat(typeName).isEqualTo("access_solution_context")
- assertThat(bundle).hasSize(10)
+ assertThat(typeName).isEqualTo("reveal_solution")
+ assertThat(bundle).hasSize(14)
assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(ACCESS_SOLUTION_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
assertThat(bundle).string("topic_id").isEqualTo(TEST_TOPIC_ID)
assertThat(bundle).string("story_id").isEqualTo(TEST_STORY_ID)
assertThat(bundle).string("exploration_id").isEqualTo(TEST_EXPLORATION_ID)
@@ -866,10 +1000,14 @@ class EventBundleCreatorTest {
val eventLog = createEventLog(context = createSubmitAnswerContext())
val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
- assertThat(typeName).isEqualTo("submit_answer_context")
- assertThat(bundle).hasSize(10)
+ assertThat(typeName).isEqualTo("submit_answer")
+ assertThat(bundle).hasSize(14)
assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(SUBMIT_ANSWER_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
assertThat(bundle).string("ed_topic_id").isEqualTo(TEST_TOPIC_ID)
assertThat(bundle).string("ed_story_id").isEqualTo(TEST_STORY_ID)
assertThat(bundle).string("ed_exploration_id").isEqualTo(TEST_EXPLORATION_ID)
@@ -888,10 +1026,14 @@ class EventBundleCreatorTest {
val eventLog = createEventLog(context = createSubmitAnswerContext())
val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
- assertThat(typeName).isEqualTo("submit_answer_context")
- assertThat(bundle).hasSize(12)
+ assertThat(typeName).isEqualTo("submit_answer")
+ assertThat(bundle).hasSize(16)
assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(SUBMIT_ANSWER_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
assertThat(bundle).string("ed_topic_id").isEqualTo(TEST_TOPIC_ID)
assertThat(bundle).string("ed_story_id").isEqualTo(TEST_STORY_ID)
assertThat(bundle).string("ed_exploration_id").isEqualTo(TEST_EXPLORATION_ID)
@@ -912,10 +1054,14 @@ class EventBundleCreatorTest {
val eventLog = createEventLog(context = createPlayVoiceOverContext())
val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
- assertThat(typeName).isEqualTo("play_voice_over_context")
- assertThat(bundle).hasSize(9)
+ assertThat(typeName).isEqualTo("click_play_voiceover_button")
+ assertThat(bundle).hasSize(13)
assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(PLAY_VOICE_OVER_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
assertThat(bundle).string("ed_topic_id").isEqualTo(TEST_TOPIC_ID)
assertThat(bundle).string("ed_story_id").isEqualTo(TEST_STORY_ID)
assertThat(bundle).string("ed_exploration_id").isEqualTo(TEST_EXPLORATION_ID)
@@ -933,10 +1079,14 @@ class EventBundleCreatorTest {
val eventLog = createEventLog(context = createPlayVoiceOverContext())
val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
- assertThat(typeName).isEqualTo("play_voice_over_context")
- assertThat(bundle).hasSize(11)
+ assertThat(typeName).isEqualTo("click_play_voiceover_button")
+ assertThat(bundle).hasSize(15)
assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(PLAY_VOICE_OVER_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
assertThat(bundle).string("ed_topic_id").isEqualTo(TEST_TOPIC_ID)
assertThat(bundle).string("ed_story_id").isEqualTo(TEST_STORY_ID)
assertThat(bundle).string("ed_exploration_id").isEqualTo(TEST_EXPLORATION_ID)
@@ -956,10 +1106,14 @@ class EventBundleCreatorTest {
val eventLog = createEventLog(context = createAppInBackgroundContext())
val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
- assertThat(typeName).isEqualTo("app_in_background_context")
- assertThat(bundle).hasSize(2)
+ assertThat(typeName).isEqualTo("send_app_to_background")
+ assertThat(bundle).hasSize(6)
assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(APP_IN_BACKGROUND_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
}
@Test
@@ -970,10 +1124,14 @@ class EventBundleCreatorTest {
val eventLog = createEventLog(context = createAppInBackgroundContext())
val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
- assertThat(typeName).isEqualTo("app_in_background_context")
- assertThat(bundle).hasSize(4)
+ assertThat(typeName).isEqualTo("send_app_to_background")
+ assertThat(bundle).hasSize(8)
assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(APP_IN_BACKGROUND_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
assertThat(bundle).string("learner_id").isEqualTo(TEST_LEARNER_ID)
assertThat(bundle).string("install_id").isEqualTo(TEST_INSTALLATION_ID)
}
@@ -986,10 +1144,14 @@ class EventBundleCreatorTest {
val eventLog = createEventLog(context = createAppInForegroundContext())
val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
- assertThat(typeName).isEqualTo("app_in_foreground_context")
- assertThat(bundle).hasSize(2)
+ assertThat(typeName).isEqualTo("bring_app_to_foreground")
+ assertThat(bundle).hasSize(6)
assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(APP_IN_FOREGROUND_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
}
@Test
@@ -1000,10 +1162,14 @@ class EventBundleCreatorTest {
val eventLog = createEventLog(context = createAppInForegroundContext())
val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
- assertThat(typeName).isEqualTo("app_in_foreground_context")
- assertThat(bundle).hasSize(4)
+ assertThat(typeName).isEqualTo("bring_app_to_foreground")
+ assertThat(bundle).hasSize(8)
assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(APP_IN_FOREGROUND_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
assertThat(bundle).string("learner_id").isEqualTo(TEST_LEARNER_ID)
assertThat(bundle).string("install_id").isEqualTo(TEST_INSTALLATION_ID)
}
@@ -1016,10 +1182,14 @@ class EventBundleCreatorTest {
val eventLog = createEventLog(context = createExitExplorationContext())
val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
- assertThat(typeName).isEqualTo("exit_exploration_context")
- assertThat(bundle).hasSize(8)
+ assertThat(typeName).isEqualTo("leave_exploration")
+ assertThat(bundle).hasSize(12)
assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(EXIT_EXPLORATION_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
assertThat(bundle).string("topic_id").isEqualTo(TEST_TOPIC_ID)
assertThat(bundle).string("story_id").isEqualTo(TEST_STORY_ID)
assertThat(bundle).string("exploration_id").isEqualTo(TEST_EXPLORATION_ID)
@@ -1036,10 +1206,14 @@ class EventBundleCreatorTest {
val eventLog = createEventLog(context = createExitExplorationContext())
val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
- assertThat(typeName).isEqualTo("exit_exploration_context")
- assertThat(bundle).hasSize(10)
+ assertThat(typeName).isEqualTo("leave_exploration")
+ assertThat(bundle).hasSize(14)
assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(EXIT_EXPLORATION_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
assertThat(bundle).string("topic_id").isEqualTo(TEST_TOPIC_ID)
assertThat(bundle).string("story_id").isEqualTo(TEST_STORY_ID)
assertThat(bundle).string("exploration_id").isEqualTo(TEST_EXPLORATION_ID)
@@ -1058,10 +1232,14 @@ class EventBundleCreatorTest {
val eventLog = createEventLog(context = createFinishExplorationContext())
val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
- assertThat(typeName).isEqualTo("finish_exploration_context")
- assertThat(bundle).hasSize(8)
+ assertThat(typeName).isEqualTo("complete_exploration")
+ assertThat(bundle).hasSize(12)
assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(FINISH_EXPLORATION_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
assertThat(bundle).string("topic_id").isEqualTo(TEST_TOPIC_ID)
assertThat(bundle).string("story_id").isEqualTo(TEST_STORY_ID)
assertThat(bundle).string("exploration_id").isEqualTo(TEST_EXPLORATION_ID)
@@ -1078,10 +1256,14 @@ class EventBundleCreatorTest {
val eventLog = createEventLog(context = createFinishExplorationContext())
val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
- assertThat(typeName).isEqualTo("finish_exploration_context")
- assertThat(bundle).hasSize(10)
+ assertThat(typeName).isEqualTo("complete_exploration")
+ assertThat(bundle).hasSize(14)
assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(FINISH_EXPLORATION_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
assertThat(bundle).string("topic_id").isEqualTo(TEST_TOPIC_ID)
assertThat(bundle).string("story_id").isEqualTo(TEST_STORY_ID)
assertThat(bundle).string("exploration_id").isEqualTo(TEST_EXPLORATION_ID)
@@ -1100,10 +1282,14 @@ class EventBundleCreatorTest {
val eventLog = createEventLog(context = createResumeExplorationContext())
val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
- assertThat(typeName).isEqualTo("resume_exploration_context")
- assertThat(bundle).hasSize(2)
+ assertThat(typeName).isEqualTo("resume_in_progress_exploration")
+ assertThat(bundle).hasSize(6)
assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(RESUME_EXPLORATION_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
}
@Test
@@ -1114,10 +1300,14 @@ class EventBundleCreatorTest {
val eventLog = createEventLog(context = createResumeExplorationContext())
val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
- assertThat(typeName).isEqualTo("resume_exploration_context")
- assertThat(bundle).hasSize(4)
+ assertThat(typeName).isEqualTo("resume_in_progress_exploration")
+ assertThat(bundle).hasSize(8)
assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(RESUME_EXPLORATION_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
assertThat(bundle).string("learner_id").isEqualTo(TEST_LEARNER_ID)
assertThat(bundle).string("install_id").isEqualTo(TEST_INSTALLATION_ID)
}
@@ -1130,10 +1320,14 @@ class EventBundleCreatorTest {
val eventLog = createEventLog(context = createStartOverExplorationContext())
val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
- assertThat(typeName).isEqualTo("start_over_exploration_context")
- assertThat(bundle).hasSize(2)
+ assertThat(typeName).isEqualTo("restart_in_progress_exploration")
+ assertThat(bundle).hasSize(6)
assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(START_OVER_EXPLORATION_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
}
@Test
@@ -1144,10 +1338,14 @@ class EventBundleCreatorTest {
val eventLog = createEventLog(context = createStartOverExplorationContext())
val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
- assertThat(typeName).isEqualTo("start_over_exploration_context")
- assertThat(bundle).hasSize(4)
+ assertThat(typeName).isEqualTo("restart_in_progress_exploration")
+ assertThat(bundle).hasSize(8)
assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(START_OVER_EXPLORATION_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
assertThat(bundle).string("learner_id").isEqualTo(TEST_LEARNER_ID)
assertThat(bundle).string("install_id").isEqualTo(TEST_INSTALLATION_ID)
}
@@ -1160,10 +1358,14 @@ class EventBundleCreatorTest {
val eventLog = createEventLog(context = createDeleteProfileContext())
val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
- assertThat(typeName).isEqualTo("delete_profile_context")
- assertThat(bundle).hasSize(2)
+ assertThat(typeName).isEqualTo("delete_profile")
+ assertThat(bundle).hasSize(6)
assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(DELETE_PROFILE_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
}
@Test
@@ -1174,10 +1376,14 @@ class EventBundleCreatorTest {
val eventLog = createEventLog(context = createDeleteProfileContext())
val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
- assertThat(typeName).isEqualTo("delete_profile_context")
- assertThat(bundle).hasSize(4)
+ assertThat(typeName).isEqualTo("delete_profile")
+ assertThat(bundle).hasSize(8)
assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(DELETE_PROFILE_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
assertThat(bundle).string("learner_id").isEqualTo(TEST_LEARNER_ID)
assertThat(bundle).string("install_id").isEqualTo(TEST_INSTALLATION_ID)
}
@@ -1190,10 +1396,14 @@ class EventBundleCreatorTest {
val eventLog = createEventLog(context = createOpenHomeContext())
val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
- assertThat(typeName).isEqualTo("open_home")
- assertThat(bundle).hasSize(2)
+ assertThat(typeName).isEqualTo("open_home_screen")
+ assertThat(bundle).hasSize(6)
assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(OPEN_HOME.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
}
@Test
@@ -1204,10 +1414,14 @@ class EventBundleCreatorTest {
val eventLog = createEventLog(context = createOpenProfileChooserContext())
val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
- assertThat(typeName).isEqualTo("open_profile_chooser")
- assertThat(bundle).hasSize(2)
+ assertThat(typeName).isEqualTo("open_profile_chooser_screen")
+ assertThat(bundle).hasSize(6)
assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(OPEN_PROFILE_CHOOSER.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
}
@Test
@@ -1218,10 +1432,14 @@ class EventBundleCreatorTest {
val eventLog = createEventLog(context = createInstallationIdForFailedAnalyticsLogContext())
val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
- assertThat(typeName).isEqualTo("failed_analytics_log")
- assertThat(bundle).hasSize(2)
+ assertThat(typeName).isEqualTo("ERROR_internal_logging_failure")
+ assertThat(bundle).hasSize(6)
assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(INSTALL_ID_FOR_FAILED_ANALYTICS_LOG.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
}
@Test
@@ -1232,10 +1450,14 @@ class EventBundleCreatorTest {
val eventLog = createEventLog(context = createInstallationIdForFailedAnalyticsLogContext())
val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
- assertThat(typeName).isEqualTo("failed_analytics_log")
- assertThat(bundle).hasSize(3)
+ assertThat(typeName).isEqualTo("ERROR_internal_logging_failure")
+ assertThat(bundle).hasSize(7)
assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(INSTALL_ID_FOR_FAILED_ANALYTICS_LOG.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
assertThat(bundle).string("install_id").isEqualTo(TEST_INSTALLATION_ID)
}
@@ -1458,6 +1680,22 @@ class EventBundleCreatorTest {
this.contentId = contentId
}.build()
+ private fun registerTestApplication() {
+ val packageManager = Shadows.shadowOf(context.packageManager)
+ val applicationInfo =
+ ApplicationInfoBuilder.newBuilder()
+ .setPackageName(context.packageName)
+ .build()
+ val packageInfo =
+ PackageInfoBuilder.newBuilder()
+ .setPackageName(context.packageName)
+ .setApplicationInfo(applicationInfo)
+ .build()
+ packageInfo.versionName = TEST_APP_VERSION_NAME
+ packageInfo.versionCode = TEST_APP_VERSION_CODE
+ packageManager.installPackage(packageInfo)
+ }
+
private fun createApkSizeLoggableMetric() = OppiaMetricLog.LoggableMetric.newBuilder()
.setApkSizeMetric(
OppiaMetricLog.ApkSizeMetric.newBuilder()
@@ -1502,6 +1740,7 @@ class EventBundleCreatorTest {
).build()
private fun setUpTestApplicationComponentWithoutLearnerAnalyticsStudy() {
+ TestModule.enableLearnerStudyAnalytics = false
setUpTestApplicationComponent()
}
@@ -1512,6 +1751,7 @@ class EventBundleCreatorTest {
private fun setUpTestApplicationComponent() {
ApplicationProvider.getApplicationContext().inject(this)
+ registerTestApplication()
}
// TODO(#89): Move this to a common test application component.
@@ -1545,7 +1785,7 @@ class EventBundleCreatorTest {
// TODO(#89): Move this to a common test application component.
@Singleton
- @Component(modules = [TestModule::class])
+ @Component(modules = [TestModule::class, EventLoggingConfigurationModule::class])
interface TestApplicationComponent {
@Component.Builder
interface Builder {
diff --git a/utility/src/test/java/org/oppia/android/util/logging/EventLoggingConfigurationModuleTest.kt b/utility/src/test/java/org/oppia/android/util/logging/EventLoggingConfigurationModuleTest.kt
new file mode 100644
index 00000000000..4bd1ea8e445
--- /dev/null
+++ b/utility/src/test/java/org/oppia/android/util/logging/EventLoggingConfigurationModuleTest.kt
@@ -0,0 +1,70 @@
+package org.oppia.android.util.logging
+
+import android.app.Application
+import android.content.Context
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.google.common.truth.Truth.assertThat
+import dagger.BindsInstance
+import dagger.Component
+import dagger.Module
+import dagger.Provides
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.robolectric.annotation.Config
+import org.robolectric.annotation.LooperMode
+import javax.inject.Inject
+import javax.inject.Singleton
+
+/** Tests for [EventLoggingConfigurationModule]. */
+// FunctionName: test names are conventionally named with underscores.
+@Suppress("FunctionName")
+@RunWith(AndroidJUnit4::class)
+@LooperMode(LooperMode.Mode.PAUSED)
+@Config(manifest = Config.NONE)
+class EventLoggingConfigurationModuleTest {
+ @Inject lateinit var eventTypeToHumanReadableNameConverter: EventTypeToHumanReadableNameConverter
+
+ @Before
+ fun setUp() {
+ setUpTestApplicationComponent()
+ }
+
+ @Test
+ fun testModule_injectedEventTypeToHumanReadableNameConverter_isStandardImplementation() {
+ assertThat(eventTypeToHumanReadableNameConverter)
+ .isInstanceOf(StandardEventTypeToHumanReadableNameConverterImpl::class.java)
+ }
+
+ private fun setUpTestApplicationComponent() {
+ DaggerEventLoggingConfigurationModuleTest_TestApplicationComponent
+ .builder()
+ .setApplication(ApplicationProvider.getApplicationContext()).build().inject(this)
+ }
+
+ // TODO(#89): Move this to a common test application component.
+ @Module
+ class TestModule {
+ @Provides
+ @Singleton
+ fun provideContext(application: Application): Context {
+ return application
+ }
+ }
+
+ // TODO(#89): Move this to a common test application component.
+ @Singleton
+ @Component(modules = [EventLoggingConfigurationModule::class])
+ interface TestApplicationComponent {
+ @Component.Builder
+ interface Builder {
+ @BindsInstance
+ fun setApplication(application: Application): Builder
+
+ fun build(): TestApplicationComponent
+ }
+
+ fun inject(test: EventLoggingConfigurationModuleTest)
+ }
+}
diff --git a/utility/src/test/java/org/oppia/android/util/logging/KenyaAlphaEventBundleCreatorTest.kt b/utility/src/test/java/org/oppia/android/util/logging/KenyaAlphaEventBundleCreatorTest.kt
new file mode 100644
index 00000000000..7f8b6f0225d
--- /dev/null
+++ b/utility/src/test/java/org/oppia/android/util/logging/KenyaAlphaEventBundleCreatorTest.kt
@@ -0,0 +1,1445 @@
+package org.oppia.android.util.logging
+
+import android.app.Application
+import android.content.Context
+import android.os.Bundle
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.core.content.pm.ApplicationInfoBuilder
+import androidx.test.core.content.pm.PackageInfoBuilder
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.ext.truth.os.BundleSubject.assertThat
+import com.google.common.truth.Truth.assertThat
+import dagger.BindsInstance
+import dagger.Component
+import dagger.Module
+import dagger.Provides
+import org.junit.After
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.oppia.android.app.model.EventLog
+import org.oppia.android.app.model.EventLog.CardContext
+import org.oppia.android.app.model.EventLog.ConceptCardContext
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.ACCESS_HINT_CONTEXT
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.ACCESS_SOLUTION_CONTEXT
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.ACTIVITYCONTEXT_NOT_SET
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.APP_IN_BACKGROUND_CONTEXT
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.APP_IN_FOREGROUND_CONTEXT
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.DELETE_PROFILE_CONTEXT
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.END_CARD_CONTEXT
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.EXIT_EXPLORATION_CONTEXT
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.FINISH_EXPLORATION_CONTEXT
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.HINT_OFFERED_CONTEXT
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.INSTALL_ID_FOR_FAILED_ANALYTICS_LOG
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.OPEN_CONCEPT_CARD
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.OPEN_EXPLORATION_ACTIVITY
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.OPEN_HOME
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.OPEN_INFO_TAB
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.OPEN_LESSONS_TAB
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.OPEN_PRACTICE_TAB
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.OPEN_PROFILE_CHOOSER
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.OPEN_QUESTION_PLAYER
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.OPEN_REVISION_CARD
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.OPEN_REVISION_TAB
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.OPEN_STORY_ACTIVITY
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.PLAY_VOICE_OVER_CONTEXT
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.RESUME_EXPLORATION_CONTEXT
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.SOLUTION_OFFERED_CONTEXT
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.START_CARD_CONTEXT
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.START_OVER_EXPLORATION_CONTEXT
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase.SUBMIT_ANSWER_CONTEXT
+import org.oppia.android.app.model.EventLog.ExplorationContext
+import org.oppia.android.app.model.EventLog.HintContext
+import org.oppia.android.app.model.EventLog.LearnerDetailsContext
+import org.oppia.android.app.model.EventLog.PlayVoiceOverContext
+import org.oppia.android.app.model.EventLog.Priority.ESSENTIAL
+import org.oppia.android.app.model.EventLog.Priority.OPTIONAL
+import org.oppia.android.app.model.EventLog.QuestionContext
+import org.oppia.android.app.model.EventLog.RevisionCardContext
+import org.oppia.android.app.model.EventLog.StoryContext
+import org.oppia.android.app.model.EventLog.SubmitAnswerContext
+import org.oppia.android.app.model.EventLog.TopicContext
+import org.oppia.android.util.platformparameter.LEARNER_STUDY_ANALYTICS_DEFAULT_VALUE
+import org.oppia.android.util.platformparameter.LearnerStudyAnalytics
+import org.oppia.android.util.platformparameter.PlatformParameterValue
+import org.robolectric.Shadows
+import org.robolectric.annotation.Config
+import org.robolectric.annotation.LooperMode
+import javax.inject.Inject
+import javax.inject.Singleton
+import org.oppia.android.app.model.EventLog.Context.Builder as EventContextBuilder
+
+private const val TEST_ANDROID_SDK_VERSION = 30
+
+// TODO(#4419): Remove this test suite post-Kenya user study.
+/**
+ * Variant of [EventBundleCreatorTest] but for testing behaviors specific to alpha builds of the app
+ * intended for users in the Kenya user study.
+ */
+// FunctionName: test names are conventionally named with underscores.
+@Suppress("FunctionName")
+@RunWith(AndroidJUnit4::class)
+@LooperMode(LooperMode.Mode.PAUSED)
+@Config(
+ application = KenyaAlphaEventBundleCreatorTest.TestApplication::class,
+ sdk = [TEST_ANDROID_SDK_VERSION]
+)
+class KenyaAlphaEventBundleCreatorTest {
+ private companion object {
+ private const val TEST_TIMESTAMP_1 = 1556094120000
+ private const val TEST_TIMESTAMP_2 = 1234567898765
+ private const val TEST_TOPIC_ID = "test_topic_id"
+ private const val TEST_STORY_ID = "test_story_id"
+ private const val TEST_EXPLORATION_ID = "test_exploration_id"
+ private const val TEST_QUESTION_ID = "test_question_id"
+ private const val TEST_SKILL_ID_1 = "test_skill_id_1"
+ private const val TEST_SKILL_ID_2 = "test_skill_id_2"
+ private const val TEST_SUB_TOPIC_INDEX = 1
+ private const val TEST_SUB_TOPIC_INDEX_STR = "1"
+ private const val TEST_LEARNER_ID = "test_ed_ld_learner_id"
+ private const val TEST_INSTALLATION_ID = "test_installation_id"
+ private const val TEST_LEARNER_SESSION_ID = "test_session_id"
+ private const val TEST_EXPLORATION_VERSION = 5
+ private const val TEST_EXPLORATION_VERSION_STR = "5"
+ private const val TEST_STATE_NAME = "test_state_name"
+ private const val TEST_HINT_INDEX = 1
+ private const val TEST_HINT_INDEX_STR = "1"
+ private const val TEST_IS_ANSWER_CORRECT = true
+ private const val TEST_IS_ANSWER_CORRECT_STR = "true"
+ private const val TEST_CONTENT_ID = "test_content_id"
+ private const val TEST_APP_VERSION_NAME = "oppia-android-test-0123456789"
+ private const val TEST_APP_VERSION_CODE = 125
+ }
+
+ @Inject lateinit var context: Context
+ @Inject lateinit var eventBundleCreator: EventBundleCreator
+
+ @After
+ fun tearDown() {
+ TestModule.enableLearnerStudyAnalytics = LEARNER_STUDY_ANALYTICS_DEFAULT_VALUE
+ }
+
+ @Test
+ fun testFillEventBundle_defaultEvent_defaultsBundleAndReturnsUnknownActivityContext() {
+ setUpTestApplicationComponent()
+ val bundle = Bundle()
+
+ val typeName = eventBundleCreator.fillEventBundle(EventLog.getDefaultInstance(), bundle)
+
+ assertThat(typeName).isEqualTo("unknown_activity_context")
+ assertThat(bundle).hasSize(6)
+ assertThat(bundle).longInt("timestamp").isEqualTo(0)
+ assertThat(bundle).string("priority").isEqualTo("unspecified_priority")
+ assertThat(bundle).integer("event_type").isEqualTo(ACTIVITYCONTEXT_NOT_SET.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
+ }
+
+ @Test
+ fun testFillEventBundle_eventWithDefaultedContext_fillsPriorityAndTimeAndRetsUnknownContext() {
+ setUpTestApplicationComponent()
+ val bundle = Bundle()
+ val eventLog = createEventLog(timestamp = TEST_TIMESTAMP_1, priority = ESSENTIAL)
+
+ val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
+
+ assertThat(typeName).isEqualTo("unknown_activity_context")
+ assertThat(bundle).hasSize(6)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(ACTIVITYCONTEXT_NOT_SET.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
+ }
+
+ @Test
+ fun testFillEventBundle_eventWithDifferentTimestamp_savesDifferentTimestampInBundle() {
+ setUpTestApplicationComponent()
+ val bundle = Bundle()
+ val eventLog = createEventLog(timestamp = TEST_TIMESTAMP_2)
+
+ eventBundleCreator.fillEventBundle(eventLog, bundle)
+
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_2)
+ }
+
+ @Test
+ fun testFillEventBundle_eventWithDifferentPriority_savesDifferentPriorityInBundle() {
+ setUpTestApplicationComponent()
+ val bundle = Bundle()
+ val eventLog = createEventLog(priority = OPTIONAL)
+
+ eventBundleCreator.fillEventBundle(eventLog, bundle)
+
+ assertThat(bundle).string("priority").isEqualTo("optional")
+ }
+
+ @Test
+ fun testFillEventBundle_openExpActivityEvent_studyOff_fillsOnlyNonSensitiveFieldsAndRetsName() {
+ setUpTestApplicationComponentWithoutLearnerAnalyticsStudy()
+ val bundle = Bundle()
+
+ val eventLog = createEventLog(context = createOpenExplorationActivity())
+
+ val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
+ assertThat(typeName).isEqualTo("open_exploration_activity")
+ assertThat(bundle).hasSize(12)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(OPEN_EXPLORATION_ACTIVITY.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
+ assertThat(bundle).string("topic_id").isEqualTo(TEST_TOPIC_ID)
+ assertThat(bundle).string("story_id").isEqualTo(TEST_STORY_ID)
+ assertThat(bundle).string("exploration_id").isEqualTo(TEST_EXPLORATION_ID)
+ assertThat(bundle).string("session_id").isEqualTo(TEST_LEARNER_SESSION_ID)
+ assertThat(bundle).string("exploration_version").isEqualTo(TEST_EXPLORATION_VERSION_STR)
+ assertThat(bundle).string("state_name").isEqualTo(TEST_STATE_NAME)
+ }
+
+ @Test
+ fun testFillEventBundle_openExpActivityEvent_studyOn_fillsOnlyNonSensitiveFieldsAndRetsName() {
+ setUpTestApplicationComponentWithLearnerAnalyticsStudy()
+ val bundle = Bundle()
+
+ val eventLog = createEventLog(context = createOpenExplorationActivity())
+
+ val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
+ assertThat(typeName).isEqualTo("open_exploration_activity")
+ assertThat(bundle).hasSize(14)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(OPEN_EXPLORATION_ACTIVITY.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
+ assertThat(bundle).string("topic_id").isEqualTo(TEST_TOPIC_ID)
+ assertThat(bundle).string("story_id").isEqualTo(TEST_STORY_ID)
+ assertThat(bundle).string("exploration_id").isEqualTo(TEST_EXPLORATION_ID)
+ assertThat(bundle).string("session_id").isEqualTo(TEST_LEARNER_SESSION_ID)
+ assertThat(bundle).string("exploration_version").isEqualTo(TEST_EXPLORATION_VERSION_STR)
+ assertThat(bundle).string("state_name").isEqualTo(TEST_STATE_NAME)
+ assertThat(bundle).string("ld_learner_id").isEqualTo(TEST_LEARNER_ID)
+ assertThat(bundle).string("ld_install_id").isEqualTo(TEST_INSTALLATION_ID)
+ }
+
+ @Test
+ fun testFillEventBundle_openInfoTabContextEvent_fillsAllFieldsInBundleAndReturnsName() {
+ setUpTestApplicationComponent()
+ val bundle = Bundle()
+
+ val eventLog = createEventLog(context = createOpenInfoTab())
+
+ val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
+ assertThat(typeName).isEqualTo("open_info_tab")
+ assertThat(bundle).hasSize(7)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(OPEN_INFO_TAB.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
+ assertThat(bundle).string("topic_id").isEqualTo(TEST_TOPIC_ID)
+ }
+
+ @Test
+ fun testFillEventBundle_openLessonsTabContextEvent_fillsAllFieldsInBundleAndReturnsName() {
+ setUpTestApplicationComponent()
+ val bundle = Bundle()
+
+ val eventLog = createEventLog(context = createOpenLessonsTab())
+
+ val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
+ assertThat(typeName).isEqualTo("open_lessons_tab")
+ assertThat(bundle).hasSize(7)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(OPEN_LESSONS_TAB.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
+ assertThat(bundle).string("topic_id").isEqualTo(TEST_TOPIC_ID)
+ }
+
+ @Test
+ fun testFillEventBundle_openPracticeTabContextEvent_fillsAllFieldsInBundleAndReturnsName() {
+ setUpTestApplicationComponent()
+ val bundle = Bundle()
+
+ val eventLog = createEventLog(context = createOpenPracticeTab())
+
+ val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
+ assertThat(typeName).isEqualTo("open_practice_tab")
+ assertThat(bundle).hasSize(7)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(OPEN_PRACTICE_TAB.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
+ assertThat(bundle).string("topic_id").isEqualTo(TEST_TOPIC_ID)
+ }
+
+ @Test
+ fun testFillEventBundle_openRevisionTabContextEvent_fillsAllFieldsInBundleAndReturnsName() {
+ setUpTestApplicationComponent()
+ val bundle = Bundle()
+
+ val eventLog = createEventLog(context = createOpenRevisionTab())
+
+ val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
+ assertThat(typeName).isEqualTo("open_revision_tab")
+ assertThat(bundle).hasSize(7)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(OPEN_REVISION_TAB.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
+ assertThat(bundle).string("topic_id").isEqualTo(TEST_TOPIC_ID)
+ }
+
+ @Test
+ fun testFillEventBundle_openQuestionPlayerContextEvent_fillsAllFieldsInBundleAndReturnsName() {
+ setUpTestApplicationComponent()
+ val bundle = Bundle()
+
+ val eventLog = createEventLog(context = createOpenQuestionPlayer())
+
+ val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
+ assertThat(typeName).isEqualTo("open_question_player")
+ assertThat(bundle).hasSize(8)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(OPEN_QUESTION_PLAYER.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
+ assertThat(bundle).string("question_id").isEqualTo(TEST_QUESTION_ID)
+ assertThat(bundle).string("skill_ids").isEqualTo("$TEST_SKILL_ID_1,$TEST_SKILL_ID_2")
+ }
+
+ @Test
+ fun testFillEventBundle_openStoryActivityContextEvent_fillsAllFieldsInBundleAndReturnsName() {
+ setUpTestApplicationComponent()
+ val bundle = Bundle()
+
+ val eventLog = createEventLog(context = createOpenStoryActivity())
+
+ val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
+ assertThat(typeName).isEqualTo("open_story_activity")
+ assertThat(bundle).hasSize(8)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(OPEN_STORY_ACTIVITY.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
+ assertThat(bundle).string("topic_id").isEqualTo(TEST_TOPIC_ID)
+ assertThat(bundle).string("story_id").isEqualTo(TEST_STORY_ID)
+ }
+
+ @Test
+ fun testFillEventBundle_openConceptCardContextEvent_fillsAllFieldsInBundleAndReturnsName() {
+ setUpTestApplicationComponent()
+ val bundle = Bundle()
+
+ val eventLog = createEventLog(context = createOpenConceptCard())
+
+ val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
+ assertThat(typeName).isEqualTo("open_concept_card")
+ assertThat(bundle).hasSize(7)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(OPEN_CONCEPT_CARD.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
+ assertThat(bundle).string("skill_id").isEqualTo(TEST_SKILL_ID_1)
+ }
+
+ @Test
+ fun testFillEventBundle_openRevisionCardContextEvent_fillsAllFieldsInBundleAndReturnsName() {
+ setUpTestApplicationComponent()
+ val bundle = Bundle()
+
+ val eventLog = createEventLog(context = createOpenRevisionCard())
+
+ val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
+ assertThat(typeName).isEqualTo("open_revision_card")
+ assertThat(bundle).hasSize(8)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(OPEN_REVISION_CARD.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
+ assertThat(bundle).string("topic_id").isEqualTo(TEST_TOPIC_ID)
+ assertThat(bundle).string("subtopic_index").isEqualTo(TEST_SUB_TOPIC_INDEX_STR)
+ }
+
+ @Test
+ fun testFillEventBundle_startCardContextEvent_studyOff_fillsOnlyNonSensitiveFieldsAndRetsName() {
+ setUpTestApplicationComponentWithoutLearnerAnalyticsStudy()
+ val bundle = Bundle()
+
+ val eventLog = createEventLog(context = createStartCardContext())
+
+ val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
+ assertThat(typeName).isEqualTo("start_card_context")
+ assertThat(bundle).hasSize(13)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(START_CARD_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
+ assertThat(bundle).string("ed_topic_id").isEqualTo(TEST_TOPIC_ID)
+ assertThat(bundle).string("ed_story_id").isEqualTo(TEST_STORY_ID)
+ assertThat(bundle).string("ed_exploration_id").isEqualTo(TEST_EXPLORATION_ID)
+ assertThat(bundle).string("ed_session_id").isEqualTo(TEST_LEARNER_SESSION_ID)
+ assertThat(bundle).string("ed_exploration_version").isEqualTo(TEST_EXPLORATION_VERSION_STR)
+ assertThat(bundle).string("ed_state_name").isEqualTo(TEST_STATE_NAME)
+ assertThat(bundle).string("skill_id").isEqualTo(TEST_SKILL_ID_1)
+ }
+
+ @Test
+ fun testFillEventBundle_startCardContextEvent_studyOn_fillsOnlyNonSensitiveFieldsAndRetsName() {
+ setUpTestApplicationComponentWithLearnerAnalyticsStudy()
+ val bundle = Bundle()
+
+ val eventLog = createEventLog(context = createStartCardContext())
+
+ val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
+ assertThat(typeName).isEqualTo("start_card_context")
+ assertThat(bundle).hasSize(15)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(START_CARD_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
+ assertThat(bundle).string("ed_topic_id").isEqualTo(TEST_TOPIC_ID)
+ assertThat(bundle).string("ed_story_id").isEqualTo(TEST_STORY_ID)
+ assertThat(bundle).string("ed_exploration_id").isEqualTo(TEST_EXPLORATION_ID)
+ assertThat(bundle).string("ed_session_id").isEqualTo(TEST_LEARNER_SESSION_ID)
+ assertThat(bundle).string("ed_exploration_version").isEqualTo(TEST_EXPLORATION_VERSION_STR)
+ assertThat(bundle).string("ed_state_name").isEqualTo(TEST_STATE_NAME)
+ assertThat(bundle).string("skill_id").isEqualTo(TEST_SKILL_ID_1)
+ assertThat(bundle).string("ed_ld_learner_id").isEqualTo(TEST_LEARNER_ID)
+ assertThat(bundle).string("ed_ld_install_id").isEqualTo(TEST_INSTALLATION_ID)
+ }
+
+ @Test
+ fun testFillEventBundle_endCardContextEvent_studyOff_fillsOnlyNonSensitiveFieldsAndRetsName() {
+ setUpTestApplicationComponentWithoutLearnerAnalyticsStudy()
+ val bundle = Bundle()
+
+ val eventLog = createEventLog(context = createEndCardContext())
+
+ val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
+ assertThat(typeName).isEqualTo("end_card_context")
+ assertThat(bundle).hasSize(13)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(END_CARD_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
+ assertThat(bundle).string("ed_topic_id").isEqualTo(TEST_TOPIC_ID)
+ assertThat(bundle).string("ed_story_id").isEqualTo(TEST_STORY_ID)
+ assertThat(bundle).string("ed_exploration_id").isEqualTo(TEST_EXPLORATION_ID)
+ assertThat(bundle).string("ed_session_id").isEqualTo(TEST_LEARNER_SESSION_ID)
+ assertThat(bundle).string("ed_exploration_version").isEqualTo(TEST_EXPLORATION_VERSION_STR)
+ assertThat(bundle).string("ed_state_name").isEqualTo(TEST_STATE_NAME)
+ assertThat(bundle).string("skill_id").isEqualTo(TEST_SKILL_ID_1)
+ }
+
+ @Test
+ fun testFillEventBundle_endCardContextEvent_studyOn_fillsOnlyNonSensitiveFieldsAndRetsName() {
+ setUpTestApplicationComponentWithLearnerAnalyticsStudy()
+ val bundle = Bundle()
+
+ val eventLog = createEventLog(context = createEndCardContext())
+
+ val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
+ assertThat(typeName).isEqualTo("end_card_context")
+ assertThat(bundle).hasSize(15)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(END_CARD_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
+ assertThat(bundle).string("ed_topic_id").isEqualTo(TEST_TOPIC_ID)
+ assertThat(bundle).string("ed_story_id").isEqualTo(TEST_STORY_ID)
+ assertThat(bundle).string("ed_exploration_id").isEqualTo(TEST_EXPLORATION_ID)
+ assertThat(bundle).string("ed_session_id").isEqualTo(TEST_LEARNER_SESSION_ID)
+ assertThat(bundle).string("ed_exploration_version").isEqualTo(TEST_EXPLORATION_VERSION_STR)
+ assertThat(bundle).string("ed_state_name").isEqualTo(TEST_STATE_NAME)
+ assertThat(bundle).string("skill_id").isEqualTo(TEST_SKILL_ID_1)
+ assertThat(bundle).string("ed_ld_learner_id").isEqualTo(TEST_LEARNER_ID)
+ assertThat(bundle).string("ed_ld_install_id").isEqualTo(TEST_INSTALLATION_ID)
+ }
+
+ @Test
+ fun testFillEventBundle_hintOfferedEvent_studyOff_fillsOnlyNonSensitiveFieldsAndRetsName() {
+ setUpTestApplicationComponentWithoutLearnerAnalyticsStudy()
+ val bundle = Bundle()
+
+ val eventLog = createEventLog(context = createHintOfferedContext())
+
+ val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
+ assertThat(typeName).isEqualTo("hint_offered_context")
+ assertThat(bundle).hasSize(13)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(HINT_OFFERED_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
+ assertThat(bundle).string("ed_topic_id").isEqualTo(TEST_TOPIC_ID)
+ assertThat(bundle).string("ed_story_id").isEqualTo(TEST_STORY_ID)
+ assertThat(bundle).string("ed_exploration_id").isEqualTo(TEST_EXPLORATION_ID)
+ assertThat(bundle).string("ed_session_id").isEqualTo(TEST_LEARNER_SESSION_ID)
+ assertThat(bundle).string("ed_exploration_version").isEqualTo(TEST_EXPLORATION_VERSION_STR)
+ assertThat(bundle).string("ed_state_name").isEqualTo(TEST_STATE_NAME)
+ assertThat(bundle).string("hint_index").isEqualTo(TEST_HINT_INDEX_STR)
+ }
+
+ @Test
+ fun testFillEventBundle_hintOfferedEvent_studyOn_fillsOnlyNonSensitiveFieldsAndRetsName() {
+ setUpTestApplicationComponentWithLearnerAnalyticsStudy()
+ val bundle = Bundle()
+
+ val eventLog = createEventLog(context = createHintOfferedContext())
+
+ val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
+ assertThat(typeName).isEqualTo("hint_offered_context")
+ assertThat(bundle).hasSize(15)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(HINT_OFFERED_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
+ assertThat(bundle).string("ed_topic_id").isEqualTo(TEST_TOPIC_ID)
+ assertThat(bundle).string("ed_story_id").isEqualTo(TEST_STORY_ID)
+ assertThat(bundle).string("ed_exploration_id").isEqualTo(TEST_EXPLORATION_ID)
+ assertThat(bundle).string("ed_session_id").isEqualTo(TEST_LEARNER_SESSION_ID)
+ assertThat(bundle).string("ed_exploration_version").isEqualTo(TEST_EXPLORATION_VERSION_STR)
+ assertThat(bundle).string("ed_state_name").isEqualTo(TEST_STATE_NAME)
+ assertThat(bundle).string("hint_index").isEqualTo(TEST_HINT_INDEX_STR)
+ assertThat(bundle).string("ed_ld_learner_id").isEqualTo(TEST_LEARNER_ID)
+ assertThat(bundle).string("ed_ld_install_id").isEqualTo(TEST_INSTALLATION_ID)
+ }
+
+ @Test
+ fun testFillEventBundle_accessHintContextEvent_studyOff_fillsOnlyNonSensitiveFieldsAndRetsName() {
+ setUpTestApplicationComponentWithoutLearnerAnalyticsStudy()
+ val bundle = Bundle()
+
+ val eventLog = createEventLog(context = createAccessHintContext())
+
+ val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
+ assertThat(typeName).isEqualTo("access_hint_context")
+ assertThat(bundle).hasSize(13)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(ACCESS_HINT_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
+ assertThat(bundle).string("ed_topic_id").isEqualTo(TEST_TOPIC_ID)
+ assertThat(bundle).string("ed_story_id").isEqualTo(TEST_STORY_ID)
+ assertThat(bundle).string("ed_exploration_id").isEqualTo(TEST_EXPLORATION_ID)
+ assertThat(bundle).string("ed_session_id").isEqualTo(TEST_LEARNER_SESSION_ID)
+ assertThat(bundle).string("ed_exploration_version").isEqualTo(TEST_EXPLORATION_VERSION_STR)
+ assertThat(bundle).string("ed_state_name").isEqualTo(TEST_STATE_NAME)
+ assertThat(bundle).string("hint_index").isEqualTo(TEST_HINT_INDEX_STR)
+ }
+
+ @Test
+ fun testFillEventBundle_accessHintContextEvent_studyOn_fillsOnlyNonSensitiveFieldsAndRetsName() {
+ setUpTestApplicationComponentWithLearnerAnalyticsStudy()
+ val bundle = Bundle()
+
+ val eventLog = createEventLog(context = createAccessHintContext())
+
+ val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
+ assertThat(typeName).isEqualTo("access_hint_context")
+ assertThat(bundle).hasSize(15)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(ACCESS_HINT_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
+ assertThat(bundle).string("ed_topic_id").isEqualTo(TEST_TOPIC_ID)
+ assertThat(bundle).string("ed_story_id").isEqualTo(TEST_STORY_ID)
+ assertThat(bundle).string("ed_exploration_id").isEqualTo(TEST_EXPLORATION_ID)
+ assertThat(bundle).string("ed_session_id").isEqualTo(TEST_LEARNER_SESSION_ID)
+ assertThat(bundle).string("ed_exploration_version").isEqualTo(TEST_EXPLORATION_VERSION_STR)
+ assertThat(bundle).string("ed_state_name").isEqualTo(TEST_STATE_NAME)
+ assertThat(bundle).string("hint_index").isEqualTo(TEST_HINT_INDEX_STR)
+ assertThat(bundle).string("ed_ld_learner_id").isEqualTo(TEST_LEARNER_ID)
+ assertThat(bundle).string("ed_ld_install_id").isEqualTo(TEST_INSTALLATION_ID)
+ }
+
+ @Test
+ fun testFillEventBundle_solutionOfferedEvent_studyOff_fillsOnlyNonSensitiveFieldsAndRetsName() {
+ setUpTestApplicationComponentWithoutLearnerAnalyticsStudy()
+ val bundle = Bundle()
+
+ val eventLog = createEventLog(context = createSolutionOfferedContext())
+
+ val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
+ assertThat(typeName).isEqualTo("solution_offered_context")
+ assertThat(bundle).hasSize(12)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(SOLUTION_OFFERED_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
+ assertThat(bundle).string("topic_id").isEqualTo(TEST_TOPIC_ID)
+ assertThat(bundle).string("story_id").isEqualTo(TEST_STORY_ID)
+ assertThat(bundle).string("exploration_id").isEqualTo(TEST_EXPLORATION_ID)
+ assertThat(bundle).string("session_id").isEqualTo(TEST_LEARNER_SESSION_ID)
+ assertThat(bundle).string("exploration_version").isEqualTo(TEST_EXPLORATION_VERSION_STR)
+ assertThat(bundle).string("state_name").isEqualTo(TEST_STATE_NAME)
+ }
+
+ @Test
+ fun testFillEventBundle_solutionOfferedEvent_studyOn_fillsOnlyNonSensitiveFieldsAndRetsName() {
+ setUpTestApplicationComponentWithLearnerAnalyticsStudy()
+ val bundle = Bundle()
+
+ val eventLog = createEventLog(context = createSolutionOfferedContext())
+
+ val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
+ assertThat(typeName).isEqualTo("solution_offered_context")
+ assertThat(bundle).hasSize(14)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(SOLUTION_OFFERED_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
+ assertThat(bundle).string("topic_id").isEqualTo(TEST_TOPIC_ID)
+ assertThat(bundle).string("story_id").isEqualTo(TEST_STORY_ID)
+ assertThat(bundle).string("exploration_id").isEqualTo(TEST_EXPLORATION_ID)
+ assertThat(bundle).string("session_id").isEqualTo(TEST_LEARNER_SESSION_ID)
+ assertThat(bundle).string("exploration_version").isEqualTo(TEST_EXPLORATION_VERSION_STR)
+ assertThat(bundle).string("state_name").isEqualTo(TEST_STATE_NAME)
+ assertThat(bundle).string("ld_learner_id").isEqualTo(TEST_LEARNER_ID)
+ assertThat(bundle).string("ld_install_id").isEqualTo(TEST_INSTALLATION_ID)
+ }
+
+ @Test
+ fun testFillEventBundle_accessSolutionEvent_studyOff_fillsOnlyNonSensitiveFieldsAndRetsName() {
+ setUpTestApplicationComponentWithoutLearnerAnalyticsStudy()
+ val bundle = Bundle()
+
+ val eventLog = createEventLog(context = createAccessSolutionContext())
+
+ val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
+ assertThat(typeName).isEqualTo("access_solution_context")
+ assertThat(bundle).hasSize(12)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(ACCESS_SOLUTION_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
+ assertThat(bundle).string("topic_id").isEqualTo(TEST_TOPIC_ID)
+ assertThat(bundle).string("story_id").isEqualTo(TEST_STORY_ID)
+ assertThat(bundle).string("exploration_id").isEqualTo(TEST_EXPLORATION_ID)
+ assertThat(bundle).string("session_id").isEqualTo(TEST_LEARNER_SESSION_ID)
+ assertThat(bundle).string("exploration_version").isEqualTo(TEST_EXPLORATION_VERSION_STR)
+ assertThat(bundle).string("state_name").isEqualTo(TEST_STATE_NAME)
+ }
+
+ @Test
+ fun testFillEventBundle_accessSolutionEvent_studyOn_fillsOnlyNonSensitiveFieldsAndRetsName() {
+ setUpTestApplicationComponentWithLearnerAnalyticsStudy()
+ val bundle = Bundle()
+
+ val eventLog = createEventLog(context = createAccessSolutionContext())
+
+ val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
+ assertThat(typeName).isEqualTo("access_solution_context")
+ assertThat(bundle).hasSize(14)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(ACCESS_SOLUTION_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
+ assertThat(bundle).string("topic_id").isEqualTo(TEST_TOPIC_ID)
+ assertThat(bundle).string("story_id").isEqualTo(TEST_STORY_ID)
+ assertThat(bundle).string("exploration_id").isEqualTo(TEST_EXPLORATION_ID)
+ assertThat(bundle).string("session_id").isEqualTo(TEST_LEARNER_SESSION_ID)
+ assertThat(bundle).string("exploration_version").isEqualTo(TEST_EXPLORATION_VERSION_STR)
+ assertThat(bundle).string("state_name").isEqualTo(TEST_STATE_NAME)
+ assertThat(bundle).string("ld_learner_id").isEqualTo(TEST_LEARNER_ID)
+ assertThat(bundle).string("ld_install_id").isEqualTo(TEST_INSTALLATION_ID)
+ }
+
+ @Test
+ fun testFillEventBundle_submitAnswerEvent_studyOff_fillsOnlyNonSensitiveFieldsAndRetsName() {
+ setUpTestApplicationComponentWithoutLearnerAnalyticsStudy()
+ val bundle = Bundle()
+
+ val eventLog = createEventLog(context = createSubmitAnswerContext())
+
+ val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
+ assertThat(typeName).isEqualTo("submit_answer_context")
+ assertThat(bundle).hasSize(14)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(SUBMIT_ANSWER_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
+ assertThat(bundle).string("ed_topic_id").isEqualTo(TEST_TOPIC_ID)
+ assertThat(bundle).string("ed_story_id").isEqualTo(TEST_STORY_ID)
+ assertThat(bundle).string("ed_exploration_id").isEqualTo(TEST_EXPLORATION_ID)
+ assertThat(bundle).string("ed_session_id").isEqualTo(TEST_LEARNER_SESSION_ID)
+ assertThat(bundle).string("ed_exploration_version").isEqualTo(TEST_EXPLORATION_VERSION_STR)
+ assertThat(bundle).string("ed_state_name").isEqualTo(TEST_STATE_NAME)
+ assertThat(bundle).string("submitted_answer").isEmpty()
+ assertThat(bundle).string("is_answer_correct").isEqualTo(TEST_IS_ANSWER_CORRECT_STR)
+ }
+
+ @Test
+ fun testFillEventBundle_submitAnswerEvent_studyOn_fillsOnlyNonSensitiveFieldsAndRetsName() {
+ setUpTestApplicationComponentWithLearnerAnalyticsStudy()
+ val bundle = Bundle()
+
+ val eventLog = createEventLog(context = createSubmitAnswerContext())
+
+ val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
+ assertThat(typeName).isEqualTo("submit_answer_context")
+ assertThat(bundle).hasSize(16)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(SUBMIT_ANSWER_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
+ assertThat(bundle).string("ed_topic_id").isEqualTo(TEST_TOPIC_ID)
+ assertThat(bundle).string("ed_story_id").isEqualTo(TEST_STORY_ID)
+ assertThat(bundle).string("ed_exploration_id").isEqualTo(TEST_EXPLORATION_ID)
+ assertThat(bundle).string("ed_session_id").isEqualTo(TEST_LEARNER_SESSION_ID)
+ assertThat(bundle).string("ed_exploration_version").isEqualTo(TEST_EXPLORATION_VERSION_STR)
+ assertThat(bundle).string("ed_state_name").isEqualTo(TEST_STATE_NAME)
+ assertThat(bundle).string("submitted_answer").isEmpty()
+ assertThat(bundle).string("is_answer_correct").isEqualTo(TEST_IS_ANSWER_CORRECT_STR)
+ assertThat(bundle).string("ed_ld_learner_id").isEqualTo(TEST_LEARNER_ID)
+ assertThat(bundle).string("ed_ld_install_id").isEqualTo(TEST_INSTALLATION_ID)
+ }
+
+ @Test
+ fun testFillEventBundle_playVoiceOverEvent_studyOff_fillsOnlyNonSensitiveFieldsAndRetsName() {
+ setUpTestApplicationComponentWithoutLearnerAnalyticsStudy()
+ val bundle = Bundle()
+
+ val eventLog = createEventLog(context = createPlayVoiceOverContext())
+
+ val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
+ assertThat(typeName).isEqualTo("play_voice_over_context")
+ assertThat(bundle).hasSize(13)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(PLAY_VOICE_OVER_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
+ assertThat(bundle).string("ed_topic_id").isEqualTo(TEST_TOPIC_ID)
+ assertThat(bundle).string("ed_story_id").isEqualTo(TEST_STORY_ID)
+ assertThat(bundle).string("ed_exploration_id").isEqualTo(TEST_EXPLORATION_ID)
+ assertThat(bundle).string("ed_session_id").isEqualTo(TEST_LEARNER_SESSION_ID)
+ assertThat(bundle).string("ed_exploration_version").isEqualTo(TEST_EXPLORATION_VERSION_STR)
+ assertThat(bundle).string("ed_state_name").isEqualTo(TEST_STATE_NAME)
+ assertThat(bundle).string("content_id").isEqualTo(TEST_CONTENT_ID)
+ }
+
+ @Test
+ fun testFillEventBundle_playVoiceOverEvent_studyOn_fillsOnlyNonSensitiveFieldsAndRetsName() {
+ setUpTestApplicationComponentWithLearnerAnalyticsStudy()
+ val bundle = Bundle()
+
+ val eventLog = createEventLog(context = createPlayVoiceOverContext())
+
+ val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
+ assertThat(typeName).isEqualTo("play_voice_over_context")
+ assertThat(bundle).hasSize(15)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(PLAY_VOICE_OVER_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
+ assertThat(bundle).string("ed_topic_id").isEqualTo(TEST_TOPIC_ID)
+ assertThat(bundle).string("ed_story_id").isEqualTo(TEST_STORY_ID)
+ assertThat(bundle).string("ed_exploration_id").isEqualTo(TEST_EXPLORATION_ID)
+ assertThat(bundle).string("ed_session_id").isEqualTo(TEST_LEARNER_SESSION_ID)
+ assertThat(bundle).string("ed_exploration_version").isEqualTo(TEST_EXPLORATION_VERSION_STR)
+ assertThat(bundle).string("ed_state_name").isEqualTo(TEST_STATE_NAME)
+ assertThat(bundle).string("content_id").isEqualTo(TEST_CONTENT_ID)
+ assertThat(bundle).string("ed_ld_learner_id").isEqualTo(TEST_LEARNER_ID)
+ assertThat(bundle).string("ed_ld_install_id").isEqualTo(TEST_INSTALLATION_ID)
+ }
+
+ @Test
+ fun testFillEventBundle_appInBackgroundEvent_studyOff_fillsOnlyNonSensitiveFieldsAndRetsName() {
+ setUpTestApplicationComponentWithoutLearnerAnalyticsStudy()
+ val bundle = Bundle()
+
+ val eventLog = createEventLog(context = createAppInBackgroundContext())
+
+ val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
+ assertThat(typeName).isEqualTo("app_in_background_context")
+ assertThat(bundle).hasSize(6)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(APP_IN_BACKGROUND_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
+ }
+
+ @Test
+ fun testFillEventBundle_appInBackgroundEvent_studyOn_fillsOnlyNonSensitiveFieldsAndRetsName() {
+ setUpTestApplicationComponentWithLearnerAnalyticsStudy()
+ val bundle = Bundle()
+
+ val eventLog = createEventLog(context = createAppInBackgroundContext())
+
+ val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
+ assertThat(typeName).isEqualTo("app_in_background_context")
+ assertThat(bundle).hasSize(8)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(APP_IN_BACKGROUND_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
+ assertThat(bundle).string("learner_id").isEqualTo(TEST_LEARNER_ID)
+ assertThat(bundle).string("install_id").isEqualTo(TEST_INSTALLATION_ID)
+ }
+
+ @Test
+ fun testFillEventBundle_appInForegroundEvent_studyOff_fillsOnlyNonSensitiveFieldsAndRetsName() {
+ setUpTestApplicationComponentWithoutLearnerAnalyticsStudy()
+ val bundle = Bundle()
+
+ val eventLog = createEventLog(context = createAppInForegroundContext())
+
+ val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
+ assertThat(typeName).isEqualTo("app_in_foreground_context")
+ assertThat(bundle).hasSize(6)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(APP_IN_FOREGROUND_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
+ }
+
+ @Test
+ fun testFillEventBundle_appInForegroundEvent_studyOn_fillsOnlyNonSensitiveFieldsAndRetsName() {
+ setUpTestApplicationComponentWithLearnerAnalyticsStudy()
+ val bundle = Bundle()
+
+ val eventLog = createEventLog(context = createAppInForegroundContext())
+
+ val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
+ assertThat(typeName).isEqualTo("app_in_foreground_context")
+ assertThat(bundle).hasSize(8)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(APP_IN_FOREGROUND_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
+ assertThat(bundle).string("learner_id").isEqualTo(TEST_LEARNER_ID)
+ assertThat(bundle).string("install_id").isEqualTo(TEST_INSTALLATION_ID)
+ }
+
+ @Test
+ fun testFillEventBundle_exitExplorationEvent_studyOff_fillsOnlyNonSensitiveFieldsAndRetsName() {
+ setUpTestApplicationComponentWithoutLearnerAnalyticsStudy()
+ val bundle = Bundle()
+
+ val eventLog = createEventLog(context = createExitExplorationContext())
+
+ val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
+ assertThat(typeName).isEqualTo("exit_exploration_context")
+ assertThat(bundle).hasSize(12)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(EXIT_EXPLORATION_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
+ assertThat(bundle).string("topic_id").isEqualTo(TEST_TOPIC_ID)
+ assertThat(bundle).string("story_id").isEqualTo(TEST_STORY_ID)
+ assertThat(bundle).string("exploration_id").isEqualTo(TEST_EXPLORATION_ID)
+ assertThat(bundle).string("session_id").isEqualTo(TEST_LEARNER_SESSION_ID)
+ assertThat(bundle).string("exploration_version").isEqualTo(TEST_EXPLORATION_VERSION_STR)
+ assertThat(bundle).string("state_name").isEqualTo(TEST_STATE_NAME)
+ }
+
+ @Test
+ fun testFillEventBundle_exitExplorationEvent_studyOn_fillsOnlyNonSensitiveFieldsAndRetsName() {
+ setUpTestApplicationComponentWithLearnerAnalyticsStudy()
+ val bundle = Bundle()
+
+ val eventLog = createEventLog(context = createExitExplorationContext())
+
+ val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
+ assertThat(typeName).isEqualTo("exit_exploration_context")
+ assertThat(bundle).hasSize(14)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(EXIT_EXPLORATION_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
+ assertThat(bundle).string("topic_id").isEqualTo(TEST_TOPIC_ID)
+ assertThat(bundle).string("story_id").isEqualTo(TEST_STORY_ID)
+ assertThat(bundle).string("exploration_id").isEqualTo(TEST_EXPLORATION_ID)
+ assertThat(bundle).string("session_id").isEqualTo(TEST_LEARNER_SESSION_ID)
+ assertThat(bundle).string("exploration_version").isEqualTo(TEST_EXPLORATION_VERSION_STR)
+ assertThat(bundle).string("state_name").isEqualTo(TEST_STATE_NAME)
+ assertThat(bundle).string("ld_learner_id").isEqualTo(TEST_LEARNER_ID)
+ assertThat(bundle).string("ld_install_id").isEqualTo(TEST_INSTALLATION_ID)
+ }
+
+ @Test
+ fun testFillEventBundle_finishExplorationEvent_studyOff_fillsOnlyNonSensitiveFieldsAndRetsName() {
+ setUpTestApplicationComponentWithoutLearnerAnalyticsStudy()
+ val bundle = Bundle()
+
+ val eventLog = createEventLog(context = createFinishExplorationContext())
+
+ val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
+ assertThat(typeName).isEqualTo("finish_exploration_context")
+ assertThat(bundle).hasSize(12)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(FINISH_EXPLORATION_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
+ assertThat(bundle).string("topic_id").isEqualTo(TEST_TOPIC_ID)
+ assertThat(bundle).string("story_id").isEqualTo(TEST_STORY_ID)
+ assertThat(bundle).string("exploration_id").isEqualTo(TEST_EXPLORATION_ID)
+ assertThat(bundle).string("session_id").isEqualTo(TEST_LEARNER_SESSION_ID)
+ assertThat(bundle).string("exploration_version").isEqualTo(TEST_EXPLORATION_VERSION_STR)
+ assertThat(bundle).string("state_name").isEqualTo(TEST_STATE_NAME)
+ }
+
+ @Test
+ fun testFillEventBundle_finishExplorationEvent_studyOn_fillsOnlyNonSensitiveFieldsAndRetsName() {
+ setUpTestApplicationComponentWithLearnerAnalyticsStudy()
+ val bundle = Bundle()
+
+ val eventLog = createEventLog(context = createFinishExplorationContext())
+
+ val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
+ assertThat(typeName).isEqualTo("finish_exploration_context")
+ assertThat(bundle).hasSize(14)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(FINISH_EXPLORATION_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
+ assertThat(bundle).string("topic_id").isEqualTo(TEST_TOPIC_ID)
+ assertThat(bundle).string("story_id").isEqualTo(TEST_STORY_ID)
+ assertThat(bundle).string("exploration_id").isEqualTo(TEST_EXPLORATION_ID)
+ assertThat(bundle).string("session_id").isEqualTo(TEST_LEARNER_SESSION_ID)
+ assertThat(bundle).string("exploration_version").isEqualTo(TEST_EXPLORATION_VERSION_STR)
+ assertThat(bundle).string("state_name").isEqualTo(TEST_STATE_NAME)
+ assertThat(bundle).string("ld_learner_id").isEqualTo(TEST_LEARNER_ID)
+ assertThat(bundle).string("ld_install_id").isEqualTo(TEST_INSTALLATION_ID)
+ }
+
+ @Test
+ fun testFillEventBundle_resumeExplorationEvent_studyOff_fillsOnlyNonSensitiveFieldsAndRetsName() {
+ setUpTestApplicationComponentWithoutLearnerAnalyticsStudy()
+ val bundle = Bundle()
+
+ val eventLog = createEventLog(context = createResumeExplorationContext())
+
+ val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
+ assertThat(typeName).isEqualTo("resume_exploration_context")
+ assertThat(bundle).hasSize(6)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(RESUME_EXPLORATION_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
+ }
+
+ @Test
+ fun testFillEventBundle_resumeExplorationEvent_studyOn_fillsOnlyNonSensitiveFieldsAndRetsName() {
+ setUpTestApplicationComponentWithLearnerAnalyticsStudy()
+ val bundle = Bundle()
+
+ val eventLog = createEventLog(context = createResumeExplorationContext())
+
+ val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
+ assertThat(typeName).isEqualTo("resume_exploration_context")
+ assertThat(bundle).hasSize(8)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(RESUME_EXPLORATION_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
+ assertThat(bundle).string("learner_id").isEqualTo(TEST_LEARNER_ID)
+ assertThat(bundle).string("install_id").isEqualTo(TEST_INSTALLATION_ID)
+ }
+
+ @Test
+ fun testFillEventBundle_startOverExpEvent_studyOff_fillsOnlyNonSensitiveFieldsAndRetsName() {
+ setUpTestApplicationComponentWithoutLearnerAnalyticsStudy()
+ val bundle = Bundle()
+
+ val eventLog = createEventLog(context = createStartOverExplorationContext())
+
+ val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
+ assertThat(typeName).isEqualTo("start_over_exploration_context")
+ assertThat(bundle).hasSize(6)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(START_OVER_EXPLORATION_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
+ }
+
+ @Test
+ fun testFillEventBundle_startOverExpEvent_studyOn_fillsOnlyNonSensitiveFieldsAndRetsName() {
+ setUpTestApplicationComponentWithLearnerAnalyticsStudy()
+ val bundle = Bundle()
+
+ val eventLog = createEventLog(context = createStartOverExplorationContext())
+
+ val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
+ assertThat(typeName).isEqualTo("start_over_exploration_context")
+ assertThat(bundle).hasSize(8)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(START_OVER_EXPLORATION_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
+ assertThat(bundle).string("learner_id").isEqualTo(TEST_LEARNER_ID)
+ assertThat(bundle).string("install_id").isEqualTo(TEST_INSTALLATION_ID)
+ }
+
+ @Test
+ fun testFillEventBundle_deleteProfileEvent_studyOff_fillsOnlyNonSensitiveFieldsAndRetsName() {
+ setUpTestApplicationComponentWithoutLearnerAnalyticsStudy()
+ val bundle = Bundle()
+
+ val eventLog = createEventLog(context = createDeleteProfileContext())
+
+ val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
+ assertThat(typeName).isEqualTo("delete_profile_context")
+ assertThat(bundle).hasSize(6)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(DELETE_PROFILE_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
+ }
+
+ @Test
+ fun testFillEventBundle_deleteProfileEvent_studyOn_fillsOnlyNonSensitiveFieldsAndRetsName() {
+ setUpTestApplicationComponentWithLearnerAnalyticsStudy()
+ val bundle = Bundle()
+
+ val eventLog = createEventLog(context = createDeleteProfileContext())
+
+ val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
+ assertThat(typeName).isEqualTo("delete_profile_context")
+ assertThat(bundle).hasSize(8)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(DELETE_PROFILE_CONTEXT.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
+ assertThat(bundle).string("learner_id").isEqualTo(TEST_LEARNER_ID)
+ assertThat(bundle).string("install_id").isEqualTo(TEST_INSTALLATION_ID)
+ }
+
+ @Test
+ fun testFillEventBundle_openHomeContextEvent_fillsAllFieldsInBundleAndReturnsName() {
+ setUpTestApplicationComponent()
+ val bundle = Bundle()
+
+ val eventLog = createEventLog(context = createOpenHomeContext())
+
+ val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
+ assertThat(typeName).isEqualTo("open_home")
+ assertThat(bundle).hasSize(6)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(OPEN_HOME.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
+ }
+
+ @Test
+ fun testFillEventBundle_openProfileChooserContextEvent_fillsAllFieldsInBundleAndReturnsName() {
+ setUpTestApplicationComponent()
+ val bundle = Bundle()
+
+ val eventLog = createEventLog(context = createOpenProfileChooserContext())
+
+ val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
+ assertThat(typeName).isEqualTo("open_profile_chooser")
+ assertThat(bundle).hasSize(6)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(OPEN_PROFILE_CHOOSER.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
+ }
+
+ @Test
+ fun testFillEventBundle_failedEventInstallId_studyOff_fillsOnlyNonSensitiveFieldsAndRetsName() {
+ setUpTestApplicationComponentWithoutLearnerAnalyticsStudy()
+ val bundle = Bundle()
+
+ val eventLog = createEventLog(context = createInstallationIdForFailedAnalyticsLogContext())
+
+ val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
+ assertThat(typeName).isEqualTo("failed_analytics_log")
+ assertThat(bundle).hasSize(6)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(INSTALL_ID_FOR_FAILED_ANALYTICS_LOG.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
+ }
+
+ @Test
+ fun testFillEventBundle_failedEventInstallId_studyOn_fillsOnlyNonSensitiveFieldsAndRetsName() {
+ setUpTestApplicationComponentWithLearnerAnalyticsStudy()
+ val bundle = Bundle()
+
+ val eventLog = createEventLog(context = createInstallationIdForFailedAnalyticsLogContext())
+
+ val typeName = eventBundleCreator.fillEventBundle(eventLog, bundle)
+ assertThat(typeName).isEqualTo("failed_analytics_log")
+ assertThat(bundle).hasSize(7)
+ assertThat(bundle).longInt("timestamp").isEqualTo(TEST_TIMESTAMP_1)
+ assertThat(bundle).string("priority").isEqualTo("essential")
+ assertThat(bundle).integer("event_type").isEqualTo(INSTALL_ID_FOR_FAILED_ANALYTICS_LOG.number)
+ assertThat(bundle).integer("android_sdk").isEqualTo(TEST_ANDROID_SDK_VERSION)
+ assertThat(bundle).string("app_version_name").isEqualTo(TEST_APP_VERSION_NAME)
+ assertThat(bundle).integer("app_version_code").isEqualTo(TEST_APP_VERSION_CODE)
+ assertThat(bundle).string("install_id").isEqualTo(TEST_INSTALLATION_ID)
+ }
+
+ private fun createEventLog(
+ timestamp: Long = TEST_TIMESTAMP_1,
+ priority: EventLog.Priority = ESSENTIAL,
+ context: EventLog.Context = EventLog.Context.getDefaultInstance()
+ ) = EventLog.newBuilder().apply {
+ this.timestamp = timestamp
+ this.priority = priority
+ this.context = context
+ }.build()
+
+ private fun createOpenExplorationActivity(
+ explorationContext: ExplorationContext = createExplorationContext()
+ ) = createEventContext(explorationContext, EventContextBuilder::setOpenExplorationActivity)
+
+ private fun createOpenInfoTab(topicContext: TopicContext = createTopicContext()) =
+ createEventContext(topicContext, EventContextBuilder::setOpenInfoTab)
+
+ private fun createOpenLessonsTab(topicContext: TopicContext = createTopicContext()) =
+ createEventContext(topicContext, EventContextBuilder::setOpenLessonsTab)
+
+ private fun createOpenPracticeTab(topicContext: TopicContext = createTopicContext()) =
+ createEventContext(topicContext, EventContextBuilder::setOpenPracticeTab)
+
+ private fun createOpenRevisionTab(topicContext: TopicContext = createTopicContext()) =
+ createEventContext(topicContext, EventContextBuilder::setOpenRevisionTab)
+
+ private fun createOpenQuestionPlayer(questionContext: QuestionContext = createQuestionContext()) =
+ createEventContext(questionContext, EventContextBuilder::setOpenQuestionPlayer)
+
+ private fun createOpenStoryActivity(storyContext: StoryContext = createStoryContext()) =
+ createEventContext(storyContext, EventContextBuilder::setOpenStoryActivity)
+
+ private fun createOpenConceptCard(
+ conceptCardContext: ConceptCardContext = createConceptCardContext()
+ ) = createEventContext(conceptCardContext, EventContextBuilder::setOpenConceptCard)
+
+ private fun createOpenRevisionCard(
+ revisionCardContext: RevisionCardContext = createRevisionCardContext()
+ ) = createEventContext(revisionCardContext, EventContextBuilder::setOpenRevisionCard)
+
+ private fun createStartCardContext(cardContext: CardContext = createCardContext()) =
+ createEventContext(cardContext, EventContextBuilder::setStartCardContext)
+
+ private fun createEndCardContext(cardContext: CardContext = createCardContext()) =
+ createEventContext(cardContext, EventContextBuilder::setEndCardContext)
+
+ private fun createHintOfferedContext(hintContext: HintContext = createHintContext()) =
+ createEventContext(hintContext, EventContextBuilder::setHintOfferedContext)
+
+ private fun createAccessHintContext(hintContext: HintContext = createHintContext()) =
+ createEventContext(hintContext, EventContextBuilder::setAccessHintContext)
+
+ private fun createSolutionOfferedContext(
+ explorationContext: ExplorationContext = createExplorationContext()
+ ) = createEventContext(explorationContext, EventContextBuilder::setSolutionOfferedContext)
+
+ private fun createAccessSolutionContext(
+ explorationContext: ExplorationContext = createExplorationContext()
+ ) = createEventContext(explorationContext, EventContextBuilder::setAccessSolutionContext)
+
+ private fun createSubmitAnswerContext(
+ submitAnswerContext: SubmitAnswerContext = createSubmitAnswerContextDetails()
+ ) = createEventContext(submitAnswerContext, EventContextBuilder::setSubmitAnswerContext)
+
+ private fun createPlayVoiceOverContext(
+ playVoiceOverContext: PlayVoiceOverContext = createPlayVoiceOverContextDetails()
+ ) = createEventContext(playVoiceOverContext, EventContextBuilder::setPlayVoiceOverContext)
+
+ private fun createAppInBackgroundContext(
+ learnerDetails: LearnerDetailsContext = createLearnerDetailsContext()
+ ) = createEventContext(learnerDetails, EventContextBuilder::setAppInBackgroundContext)
+
+ private fun createAppInForegroundContext(
+ learnerDetails: LearnerDetailsContext = createLearnerDetailsContext()
+ ) = createEventContext(learnerDetails, EventContextBuilder::setAppInForegroundContext)
+
+ private fun createExitExplorationContext(
+ explorationContext: ExplorationContext = createExplorationContext()
+ ) = createEventContext(explorationContext, EventContextBuilder::setExitExplorationContext)
+
+ private fun createFinishExplorationContext(
+ explorationContext: ExplorationContext = createExplorationContext()
+ ) = createEventContext(explorationContext, EventContextBuilder::setFinishExplorationContext)
+
+ private fun createResumeExplorationContext(
+ learnerDetails: LearnerDetailsContext = createLearnerDetailsContext()
+ ) = createEventContext(learnerDetails, EventContextBuilder::setResumeExplorationContext)
+
+ private fun createStartOverExplorationContext(
+ learnerDetails: LearnerDetailsContext = createLearnerDetailsContext()
+ ) = createEventContext(learnerDetails, EventContextBuilder::setStartOverExplorationContext)
+
+ private fun createDeleteProfileContext(
+ learnerDetails: LearnerDetailsContext = createLearnerDetailsContext()
+ ) = createEventContext(learnerDetails, EventContextBuilder::setDeleteProfileContext)
+
+ private fun createOpenHomeContext() =
+ createEventContext(value = true, EventContextBuilder::setOpenHome)
+
+ private fun createOpenProfileChooserContext() =
+ createEventContext(value = true, EventContextBuilder::setOpenProfileChooser)
+
+ private fun createInstallationIdForFailedAnalyticsLogContext(
+ installationId: String = TEST_INSTALLATION_ID
+ ) = createEventContext(installationId, EventContextBuilder::setInstallIdForFailedAnalyticsLog)
+
+ private fun createEventContext(
+ value: T,
+ setter: EventContextBuilder.(T) -> EventContextBuilder
+ ) = EventLog.Context.newBuilder().setter(value).build()
+
+ private fun createExplorationContext(
+ topicId: String = TEST_TOPIC_ID,
+ storyId: String = TEST_STORY_ID,
+ explorationId: String = TEST_EXPLORATION_ID,
+ sessionId: String = TEST_LEARNER_SESSION_ID,
+ explorationVersion: Int = TEST_EXPLORATION_VERSION,
+ stateName: String = TEST_STATE_NAME,
+ learnerDetails: LearnerDetailsContext = createLearnerDetailsContext()
+ ) = ExplorationContext.newBuilder().apply {
+ this.topicId = topicId
+ this.storyId = storyId
+ this.explorationId = explorationId
+ this.sessionId = sessionId
+ this.explorationVersion = explorationVersion
+ this.stateName = stateName
+ this.learnerDetails = learnerDetails
+ }.build()
+
+ private fun createLearnerDetailsContext(
+ learnerId: String = TEST_LEARNER_ID,
+ installId: String = TEST_INSTALLATION_ID
+ ) = LearnerDetailsContext.newBuilder().apply {
+ this.learnerId = learnerId
+ this.installId = installId
+ }.build()
+
+ private fun createTopicContext(topicId: String = TEST_TOPIC_ID) =
+ TopicContext.newBuilder().apply { this.topicId = topicId }.build()
+
+ private fun createQuestionContext(
+ questionId: String = TEST_QUESTION_ID,
+ skillIds: List = listOf(TEST_SKILL_ID_1, TEST_SKILL_ID_2)
+ ) = QuestionContext.newBuilder().apply {
+ this.questionId = questionId
+ addAllSkillId(skillIds)
+ }.build()
+
+ private fun createStoryContext(
+ topicId: String = TEST_TOPIC_ID,
+ storyId: String = TEST_STORY_ID
+ ) = StoryContext.newBuilder().apply {
+ this.topicId = topicId
+ this.storyId = storyId
+ }.build()
+
+ private fun createConceptCardContext(skillId: String = TEST_SKILL_ID_1) =
+ ConceptCardContext.newBuilder().apply { this.skillId = skillId }.build()
+
+ private fun createRevisionCardContext(
+ topicId: String = TEST_TOPIC_ID,
+ subTopicIndex: Int = TEST_SUB_TOPIC_INDEX
+ ) = RevisionCardContext.newBuilder().apply {
+ this.topicId = topicId
+ subTopicId = subTopicIndex
+ }.build()
+
+ private fun createCardContext(
+ explorationDetails: ExplorationContext = createExplorationContext(),
+ skillId: String = TEST_SKILL_ID_1
+ ) = CardContext.newBuilder().apply {
+ this.explorationDetails = explorationDetails
+ this.skillId = skillId
+ }.build()
+
+ private fun createHintContext(
+ explorationDetails: ExplorationContext = createExplorationContext(),
+ hintIndex: Int = TEST_HINT_INDEX
+ ) = HintContext.newBuilder().apply {
+ this.explorationDetails = explorationDetails
+ this.hintIndex = hintIndex
+ }.build()
+
+ private fun createSubmitAnswerContextDetails(
+ explorationDetails: ExplorationContext = createExplorationContext(),
+ isAnswerCorrect: Boolean = TEST_IS_ANSWER_CORRECT
+ ) = SubmitAnswerContext.newBuilder().apply {
+ this.explorationDetails = explorationDetails
+ this.isAnswerCorrect = isAnswerCorrect
+ }.build()
+
+ private fun createPlayVoiceOverContextDetails(
+ explorationDetails: ExplorationContext = createExplorationContext(),
+ contentId: String = TEST_CONTENT_ID
+ ) = PlayVoiceOverContext.newBuilder().apply {
+ this.explorationDetails = explorationDetails
+ this.contentId = contentId
+ }.build()
+
+ private fun registerTestApplication() {
+ val packageManager = Shadows.shadowOf(context.packageManager)
+ val applicationInfo =
+ ApplicationInfoBuilder.newBuilder()
+ .setPackageName(context.packageName)
+ .build()
+ val packageInfo =
+ PackageInfoBuilder.newBuilder()
+ .setPackageName(context.packageName)
+ .setApplicationInfo(applicationInfo)
+ .build()
+ packageInfo.versionName = TEST_APP_VERSION_NAME
+ packageInfo.versionCode = TEST_APP_VERSION_CODE
+ packageManager.installPackage(packageInfo)
+ }
+
+ private fun setUpTestApplicationComponentWithoutLearnerAnalyticsStudy() {
+ TestModule.enableLearnerStudyAnalytics = false
+ setUpTestApplicationComponent()
+ }
+
+ private fun setUpTestApplicationComponentWithLearnerAnalyticsStudy() {
+ TestModule.enableLearnerStudyAnalytics = true
+ setUpTestApplicationComponent()
+ }
+
+ private fun setUpTestApplicationComponent() {
+ ApplicationProvider.getApplicationContext().inject(this)
+ registerTestApplication()
+ }
+
+ // TODO(#89): Move this to a common test application component.
+ @Module
+ class TestModule {
+ internal companion object {
+ // This is expected to be off by default, so this helps the tests above confirm that the
+ // feature's default value is, indeed, off.
+ var enableLearnerStudyAnalytics = LEARNER_STUDY_ANALYTICS_DEFAULT_VALUE
+ }
+
+ @Provides
+ @Singleton
+ fun provideContext(application: Application): Context {
+ return application
+ }
+
+ // The scoping here is to ensure changes to the module value above don't change the parameter
+ // within the same application instance.
+ @Provides
+ @Singleton
+ @LearnerStudyAnalytics
+ fun provideLearnerStudyAnalytics(): PlatformParameterValue {
+ // Snapshot the value so that it doesn't change between injection and use.
+ val enableFeature = enableLearnerStudyAnalytics
+ return object : PlatformParameterValue {
+ override val value: Boolean = enableFeature
+ }
+ }
+ }
+
+ // TODO(#89): Move this to a common test application component.
+ @Singleton
+ @Component(modules = [TestModule::class, KenyaAlphaEventLoggingConfigurationModule::class])
+ interface TestApplicationComponent {
+ @Component.Builder
+ interface Builder {
+ @BindsInstance
+ fun setApplication(application: Application): Builder
+
+ fun build(): TestApplicationComponent
+ }
+
+ fun inject(test: KenyaAlphaEventBundleCreatorTest)
+ }
+
+ class TestApplication : Application() {
+ private val component: TestApplicationComponent by lazy {
+ DaggerKenyaAlphaEventBundleCreatorTest_TestApplicationComponent.builder()
+ .setApplication(this)
+ .build()
+ }
+
+ fun inject(test: KenyaAlphaEventBundleCreatorTest) {
+ component.inject(test)
+ }
+ }
+}
diff --git a/utility/src/test/java/org/oppia/android/util/logging/KenyaAlphaEventLoggingConfigurationModuleTest.kt b/utility/src/test/java/org/oppia/android/util/logging/KenyaAlphaEventLoggingConfigurationModuleTest.kt
new file mode 100644
index 00000000000..31d1130c3d0
--- /dev/null
+++ b/utility/src/test/java/org/oppia/android/util/logging/KenyaAlphaEventLoggingConfigurationModuleTest.kt
@@ -0,0 +1,70 @@
+package org.oppia.android.util.logging
+
+import android.app.Application
+import android.content.Context
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.google.common.truth.Truth.assertThat
+import dagger.BindsInstance
+import dagger.Component
+import dagger.Module
+import dagger.Provides
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.robolectric.annotation.Config
+import org.robolectric.annotation.LooperMode
+import javax.inject.Inject
+import javax.inject.Singleton
+
+/** Tests for [KenyaAlphaEventLoggingConfigurationModule]. */
+// FunctionName: test names are conventionally named with underscores.
+@Suppress("FunctionName")
+@RunWith(AndroidJUnit4::class)
+@LooperMode(LooperMode.Mode.PAUSED)
+@Config(manifest = Config.NONE)
+class KenyaAlphaEventLoggingConfigurationModuleTest {
+ @Inject lateinit var eventTypeToHumanReadableNameConverter: EventTypeToHumanReadableNameConverter
+
+ @Before
+ fun setUp() {
+ setUpTestApplicationComponent()
+ }
+
+ @Test
+ fun testModule_injectedEventTypeToHumanReadableNameConverter_isStudySpecificImplementation() {
+ assertThat(eventTypeToHumanReadableNameConverter)
+ .isInstanceOf(KenyaAlphaEventTypeToHumanReadableNameConverterImpl::class.java)
+ }
+
+ private fun setUpTestApplicationComponent() {
+ DaggerKenyaAlphaEventLoggingConfigurationModuleTest_TestApplicationComponent
+ .builder()
+ .setApplication(ApplicationProvider.getApplicationContext()).build().inject(this)
+ }
+
+ // TODO(#89): Move this to a common test application component.
+ @Module
+ class TestModule {
+ @Provides
+ @Singleton
+ fun provideContext(application: Application): Context {
+ return application
+ }
+ }
+
+ // TODO(#89): Move this to a common test application component.
+ @Singleton
+ @Component(modules = [KenyaAlphaEventLoggingConfigurationModule::class])
+ interface TestApplicationComponent {
+ @Component.Builder
+ interface Builder {
+ @BindsInstance
+ fun setApplication(application: Application): Builder
+
+ fun build(): TestApplicationComponent
+ }
+
+ fun inject(test: KenyaAlphaEventLoggingConfigurationModuleTest)
+ }
+}
diff --git a/utility/src/test/java/org/oppia/android/util/logging/StandardEventTypeToHumanReadableNameConverterImplTest.kt b/utility/src/test/java/org/oppia/android/util/logging/StandardEventTypeToHumanReadableNameConverterImplTest.kt
new file mode 100644
index 00000000000..82047919161
--- /dev/null
+++ b/utility/src/test/java/org/oppia/android/util/logging/StandardEventTypeToHumanReadableNameConverterImplTest.kt
@@ -0,0 +1,117 @@
+package org.oppia.android.util.logging
+
+import android.app.Application
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.google.common.truth.Truth.assertThat
+import com.google.common.truth.Truth.assertWithMessage
+import dagger.BindsInstance
+import dagger.Component
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.oppia.android.app.model.EventLog.Context.ActivityContextCase
+import org.robolectric.annotation.Config
+import org.robolectric.annotation.LooperMode
+import javax.inject.Inject
+import javax.inject.Singleton
+
+/**
+ * Tests for [StandardEventTypeToHumanReadableNameConverterImpl].
+ *
+ * Note that this suite has special change detector tests to ensure that the converter conforms to
+ * event logger restrictions (such as not having an event name longer than a certain number), which
+ * means some of these tests don't necessarily follow best practices when it comes to minimizing
+ * control flow--that's fine for these. The actual domain correctness of these names are verified
+ * elsewhere (e.g. in [EventBundleCreatorTest]).
+ */
+// FunctionName: test names are conventionally named with underscores.
+@Suppress("FunctionName")
+@RunWith(AndroidJUnit4::class)
+@LooperMode(LooperMode.Mode.PAUSED)
+@Config(application = StandardEventTypeToHumanReadableNameConverterImplTest.TestApplication::class)
+class StandardEventTypeToHumanReadableNameConverterImplTest {
+ @Inject lateinit var converterImpl: StandardEventTypeToHumanReadableNameConverterImpl
+
+ private companion object {
+ private val FAILURE_TYPES = setOf(
+ ActivityContextCase.INSTALL_ID_FOR_FAILED_ANALYTICS_LOG,
+ ActivityContextCase.ACTIVITYCONTEXT_NOT_SET
+ )
+ }
+
+ @Before
+ fun setUp() {
+ setUpTestApplicationComponent()
+ }
+
+ @Test
+ fun testConvertToHumanReadableName_nonErrorTypes_returnsUniqueNameForEach() {
+ val nonErrorContexts = ActivityContextCase.values().toSet() - FAILURE_TYPES
+
+ val nonErrorNames = nonErrorContexts.map(converterImpl::convertToHumanReadableName)
+
+ assertThat(nonErrorNames).containsNoDuplicates()
+ }
+
+ @Test
+ fun testConvertToHumanReadableName_errorTypes_shareTheSameName() {
+ val errorContexts = FAILURE_TYPES
+
+ val errorNames = errorContexts.map(converterImpl::convertToHumanReadableName)
+
+ assertThat(errorNames.toSet()).hasSize(1)
+ }
+
+ @Test
+ fun testConvertToHumanReadableName_errorTypes_doNotShareNamesWithNonErrorTypes() {
+ val errorContexts = FAILURE_TYPES
+ val nonErrorContexts = ActivityContextCase.values().toSet() - errorContexts
+
+ val nonErrorNames = nonErrorContexts.map(converterImpl::convertToHumanReadableName).toSet()
+ val errorNames = errorContexts.map(converterImpl::convertToHumanReadableName).toSet()
+
+ assertThat(errorNames).containsNoneIn(nonErrorNames)
+ }
+
+ @Test
+ fun testConvertToHumanReadableName_allNamesLessThan40Chars() {
+ val allContexts = ActivityContextCase.values()
+ val allNames = allContexts.map(converterImpl::convertToHumanReadableName)
+
+ val namesLongerThan40 = allNames.filter { it.length > 40 }
+
+ assertWithMessage("Expected no names longer than 40 chars").that(namesLongerThan40).isEmpty()
+ }
+
+ private fun setUpTestApplicationComponent() {
+ ApplicationProvider.getApplicationContext().inject(this)
+ }
+
+ // TODO(#89): Move this to a common test application component.
+ @Singleton
+ @Component(modules = [])
+ interface TestApplicationComponent {
+ @Component.Builder
+ interface Builder {
+ @BindsInstance
+ fun setApplication(application: Application): Builder
+
+ fun build(): TestApplicationComponent
+ }
+
+ fun inject(test: StandardEventTypeToHumanReadableNameConverterImplTest)
+ }
+
+ class TestApplication : Application() {
+ private val component: TestApplicationComponent by lazy {
+ DaggerStandardEventTypeToHumanReadableNameConverterImplTest_TestApplicationComponent.builder()
+ .setApplication(this)
+ .build()
+ }
+
+ fun inject(test: StandardEventTypeToHumanReadableNameConverterImplTest) {
+ component.inject(test)
+ }
+ }
+}
diff --git a/utility/src/test/java/org/oppia/android/util/logging/firebase/BUILD.bazel b/utility/src/test/java/org/oppia/android/util/logging/firebase/BUILD.bazel
new file mode 100644
index 00000000000..7d96eebedab
--- /dev/null
+++ b/utility/src/test/java/org/oppia/android/util/logging/firebase/BUILD.bazel
@@ -0,0 +1,32 @@
+"""
+Tests for logging utility implementations backed by Firebase.
+"""
+
+load("@dagger//:workspace_defs.bzl", "dagger_rules")
+load("//:oppia_android_test.bzl", "oppia_android_test")
+
+oppia_android_test(
+ name = "LogReportingModuleTest",
+ srcs = ["LogReportingModuleTest.kt"],
+ custom_package = "org.oppia.android.util.logging.firebase",
+ test_class = "org.oppia.android.util.logging.firebase.LogReportingModuleTest",
+ test_manifest = "//utility:test_manifest",
+ deps = [
+ ":dagger",
+ "//testing",
+ "//testing/src/main/java/org/oppia/android/testing/robolectric:test_module",
+ "//testing/src/main/java/org/oppia/android/testing/threading:test_module",
+ "//testing/src/main/java/org/oppia/android/testing/time:test_module",
+ "//third_party:androidx_test_ext_junit",
+ "//third_party:androidx_test_ext_truth",
+ "//third_party:com_google_truth_truth",
+ "//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:standard_event_logging_configuration_module",
+ "//utility/src/main/java/org/oppia/android/util/logging/firebase:prod_module",
+ "//utility/src/main/java/org/oppia/android/util/networking:debug_module",
+ ],
+)
+
+dagger_rules()
diff --git a/utility/src/test/java/org/oppia/android/util/logging/firebase/LogReportingModuleTest.kt b/utility/src/test/java/org/oppia/android/util/logging/firebase/LogReportingModuleTest.kt
index 83f50f95c21..5cb00d9c2bb 100644
--- a/utility/src/test/java/org/oppia/android/util/logging/firebase/LogReportingModuleTest.kt
+++ b/utility/src/test/java/org/oppia/android/util/logging/firebase/LogReportingModuleTest.kt
@@ -20,6 +20,7 @@ import org.oppia.android.util.data.DataProvidersInjector
import org.oppia.android.util.data.DataProvidersInjectorProvider
import org.oppia.android.util.locale.LocaleProdModule
import org.oppia.android.util.logging.EventLogger
+import org.oppia.android.util.logging.EventLoggingConfigurationModule
import org.oppia.android.util.logging.LoggerModule
import org.oppia.android.util.logging.SyncStatusModule
import org.oppia.android.util.logging.performancemetrics.PerformanceMetricsEventLogger
@@ -120,7 +121,8 @@ class LogReportingModuleTest {
TestModule::class, LogReportingModule::class, TestDispatcherModule::class,
RobolectricModule::class, FakeOppiaClockModule::class,
NetworkConnectionUtilDebugModule::class, LocaleProdModule::class,
- TestPlatformParameterModule::class, LoggerModule::class, SyncStatusModule::class
+ TestPlatformParameterModule::class, LoggerModule::class, SyncStatusModule::class,
+ EventLoggingConfigurationModule::class
]
)
interface TestApplicationComponent : DataProvidersInjector {
diff --git a/utility/src/test/java/org/oppia/android/util/logging/performancemetrics/BUILD.bazel b/utility/src/test/java/org/oppia/android/util/logging/performancemetrics/BUILD.bazel
new file mode 100644
index 00000000000..c24d6682d12
--- /dev/null
+++ b/utility/src/test/java/org/oppia/android/util/logging/performancemetrics/BUILD.bazel
@@ -0,0 +1,80 @@
+"""
+Tests for general-purpose utilities for performance metrics logging.
+"""
+
+load("@dagger//:workspace_defs.bzl", "dagger_rules")
+load("//:oppia_android_test.bzl", "oppia_android_test")
+
+oppia_android_test(
+ name = "PerformanceMetricsAssessorImplTest",
+ srcs = ["PerformanceMetricsAssessorImplTest.kt"],
+ custom_package = "org.oppia.android.util.logging.performancemetrics",
+ test_class = "org.oppia.android.util.logging.performancemetrics.PerformanceMetricsAssessorImplTest",
+ test_manifest = "//utility:test_manifest",
+ deps = [
+ ":dagger",
+ "//testing",
+ "//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/platformparameter:test_module",
+ "//testing/src/main/java/org/oppia/android/testing/robolectric:oppia_shadow_activity_manager",
+ "//testing/src/main/java/org/oppia/android/testing/robolectric:oppia_shadow_traffic_stats",
+ "//testing/src/main/java/org/oppia/android/testing/robolectric:test_module",
+ "//testing/src/main/java/org/oppia/android/testing/threading:test_module",
+ "//testing/src/main/java/org/oppia/android/testing/time:test_module",
+ "//third_party:androidx_test_ext_truth",
+ "//third_party:com_google_truth_truth",
+ "//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/performancemetrics:performance_metrics_assessor_impl",
+ "//utility/src/main/java/org/oppia/android/util/logging/performancemetrics:performance_metrics_configurations_module",
+ "//utility/src/main/java/org/oppia/android/util/networking:debug_module",
+ ],
+)
+
+oppia_android_test(
+ name = "PerformanceMetricsAssessorModuleTest",
+ srcs = ["PerformanceMetricsAssessorModuleTest.kt"],
+ custom_package = "org.oppia.android.util.logging.performancemetrics",
+ test_class = "org.oppia.android.util.logging.performancemetrics.PerformanceMetricsAssessorModuleTest",
+ test_manifest = "//utility:test_manifest",
+ deps = [
+ ":dagger",
+ "//testing",
+ "//testing/src/main/java/org/oppia/android/testing/robolectric:test_module",
+ "//testing/src/main/java/org/oppia/android/testing/threading:test_module",
+ "//third_party:androidx_test_ext_junit",
+ "//third_party:androidx_test_ext_truth",
+ "//third_party:com_google_truth_truth",
+ "//third_party:org_robolectric_robolectric",
+ "//third_party:robolectric_android-all",
+ "//utility/src/main/java/org/oppia/android/util/logging/firebase:prod_module",
+ "//utility/src/main/java/org/oppia/android/util/logging/performancemetrics:performance_metrics_assessor_module",
+ "//utility/src/main/java/org/oppia/android/util/logging/performancemetrics:performance_metrics_configurations_module",
+ ],
+)
+
+oppia_android_test(
+ name = "PerformanceMetricsConfigurationsModuleTest",
+ srcs = ["PerformanceMetricsConfigurationsModuleTest.kt"],
+ custom_package = "org.oppia.android.util.logging.performancemetrics",
+ test_class = "org.oppia.android.util.logging.performancemetrics.PerformanceMetricsConfigurationsModuleTest",
+ test_manifest = "//utility:test_manifest",
+ deps = [
+ ":dagger",
+ "//testing",
+ "//testing/src/main/java/org/oppia/android/testing/robolectric:test_module",
+ "//testing/src/main/java/org/oppia/android/testing/threading:test_module",
+ "//third_party:androidx_test_ext_junit",
+ "//third_party:androidx_test_ext_truth",
+ "//third_party:com_google_truth_truth",
+ "//third_party:org_robolectric_robolectric",
+ "//third_party:robolectric_android-all",
+ "//utility/src/main/java/org/oppia/android/util/logging/firebase:prod_module",
+ "//utility/src/main/java/org/oppia/android/util/logging/performancemetrics:performance_metrics_assessor_module",
+ "//utility/src/main/java/org/oppia/android/util/logging/performancemetrics:performance_metrics_configurations_module",
+ ],
+)
+
+dagger_rules()
From 5be4b791808737568f64c59018e401733fd694a7 Mon Sep 17 00:00:00 2001
From: Ben Henning
Date: Thu, 8 Sep 2022 03:06:10 -0700
Subject: [PATCH 37/57] Fix #4224 and #4306, part of #1051: Expand written
translations support to titles & descriptions (#4555)
## Explanation
Fixes #4224
Fixes #4306
Fixes part of #1051
This PR introduces expanded support for translating content strings. In particular, previous support for written content translations only extended as far as exploration state content and interactions. Now, all topics, stories, chapters, exploration, and revision cards titles and descriptions now also support translations. When considered in conjunction with app string translations, this now means that nearly the entire app is translatable.
### Technical approach
At a high-level, this PR expands the existing pattern for content translations for titles and descriptions for structures: explorations, topics, revision cards (subtopics), stories, and chapters (story nodes). This required changing existing structures (and corresponding test assets) to use ``SubtitledHtml`` instead of raw strings for their titles and descriptions, and to now include written translation tables. New ephemeral structures have been introduced to compute the translations that can be consumed by the UI to ensure the correct string is displayed.
Note that the test JSON assets have not been updated since it was a bit easier to just translate the title/description strings into ``SubtitledHtml``s during parsing time (which seems like a reasonable stopgap since the JSON loading pipeline is temporary and only developer-facing).
Due to new ephemeral structures needing to be computed in a bunch of places, profile ID now needs to be passed in more places. This has led to some minor refactoring to push more UI components over to passing around the ``ProfileId`` structure rather than the internal integer ID.
This PR also fixes part of #1051 by migrating more fragment presenters over to injecting their view models rather than retrieving them from Jetpack's view model provider (which means each of these changed presenters no longer expose potential
memory leaks in the corresponding view model).
### Caveats
This PR doesn't technically directly address #4224 and #4306, but it does indirectly. The new structures are linked to the assets download script which has been subsequently updated to cross-reference the translations for topics, stories, chapters, and subtopics from Oppia web's repository (which has temporary hardcoded translations for many of the titles and descriptions). This means that:
- Not everything will be translated despite the app now supporting it (example: revision card content isn't available to cross-reference).
- Many translation languages are missing (the team is currently focusing on Brazilian Portuguese ahead of the upcoming Beta MR1 app launch).
- Longer term, Oppia web will provide the translations directly with the structures like it does for explorations (this is an ongoing backend project).
Another caveat is that this PR further reveals the specific need to be able to compute a ``DataProvider`` based on the result of another. This is a limitation that the current ``DataProviders`` utility methods cannot handle, and the workaround is to call ``retrieveData()`` on the computed ``DataProvider`` directly which has updating inconsistency issues. Some of the providers modified as part of this PR should be updated to leverage a new dynamic transform method (see #4564 for the tracking issue). This was unfortunately dropped from the project due to limited time, but #4484 is the WIP PR.
### Test changes (or lack thereof)
Due to this PR being especially high priority, tests have been omitted from this PR in favor of merging it faster. Instead, tests will be added in a follow-up PR (#4567 is tracking to make sure that this happens). The changes have been manually tested, and will be tested more prior to many users interacting with the new functionality.
## Essential Checklist
- [x] The PR title and explanation each start with "Fix #bugnum: " (If this PR fixes part of an issue, prefix the title with "Fix part of #bugnum: ...".)
- [x] Any changes to [scripts/assets](https://github.com/oppia/oppia-android/tree/develop/scripts/assets) files have their rationale included in the PR explanation.
- [x] The PR follows the [style guide](https://github.com/oppia/oppia-android/wiki/Coding-style-guide).
- [x] The PR does not contain any unnecessary code changes from Android Studio ([reference](https://github.com/oppia/oppia-android/wiki/Guidance-on-submitting-a-PR#undo-unnecessary-changes)).
- [x] The PR is made from a branch that's **not** called "develop" and is up-to-date with "develop".
- [x] The PR is **assigned** to the appropriate reviewers ([reference](https://github.com/oppia/oppia-android/wiki/Guidance-on-submitting-a-PR#clarification-regarding-assignees-and-reviewers-section)).
## For UI-specific PRs only
While this PR is highly end user-facing, for the sake of time screenshots and video demonstrations have been omitted from the PR. They will be added at a later date (after the PR is merged), and #4567 is tracking the work item to make sure that this happens.
Commits:
* Create dedicated alpha application component.
This simplifies application component management significantly and
allows individual build flavors to have their own unique module lists.
* Add beta & GA update notices.
This also introduces dedicated beta & GA build flavors which is a
necessary prerequisite.
It also introduces an extra beta, alpha, and dev mode labels for the splash
screen (the latter 2 were extra) with 2 second minimum wait timers for
beta and alpha to ensure they are seen. A 5-second safety timer was
added to ensure the splash screen can always be passed even if something
goes wrong at the domain level (since there are now quite a few moving
pieces to determine the user's current onboarding state).
* Add build tests for the new beta & GA flavors.
* Initial support for dynamic data provider xforms.
* Stabilization improvements.
To ensure that the new dynamic DataProvider can't result in a soft lock
if in-memory cache-backed providers (such as PersistentCacheStore)
circularly reference each other (since they depend on a single thread),
InMemoryBlockingCache was updated to use the standard background in
conjunction with an actor channel. This ensures the lockless
synchronization mechanism can continue without cross-cache contention
occurring due to using a shared test.
This commit also subsequently updates all blocking caches to use the
same actor model, instead, and outright removes the blocking dispatcher
to ensure these situations can never occur in the future.
* Update codebase to Kotlin 1.6.
* Add support for build-specific asset handling.
* Fix build & Kotlin warnings (that are now errors).
One test needed to be ignored due to the Kotlin coroutines update, so
follow-up work will be needed to address this.
Note that this commit also restricts access to the Kotlin reflection
library (since it shouldn't be used broadly).
This commit also updates Gradle to use Kotlin 1.6 (though only the app
build has been verified).
Proguard building support hasn't yet been verified.
* Fix broken test per earlier changes.
* Fix general broken tests & builds.
Tests broken due to changes to the app startup experience haven't yet
been fixed.
* Lint fixes.
* Introduce coordinated executors for tests.
This commit replaces coroutine dispatchers with lower-level executors
that perform the actual state management and coordination for all
multi-threaded task handling in the app. This is actually a major
simplification as it allows for:
- Proper threading resource sharing between the app and its libraries
(such as OkHttp)
- Proper thread synchronization between executors and coroutines in
tests without leveraging the extremely complicated
CoroutineExecutorService
- Less custom coroutine infrastructure which can be difficult to
maintain
* Fix broken tests & lint issues.
* Post-merge & static check fixes.
Does not include new tests that need to be added, or lint fixes.
* Lots of test fixes.
This also includes fixing some core issues in
AsyncDataSubscriptionManager and InMemoryBlockingCache that went
previously unnoticed.
More tests still need to be added yet.
* First part of new tests.
(This is an in-progress commit that's needed so that I can transfer
changes to a different machine).
* First part of adding tests for GA notices.
There's a bunch left to do here, this is mainly needed so that I can
transfer changes to a different machine.
* Update TransformAndroidManifestTest.kt
Correct typos.
* Fix tests & static checks.
This also removes temporary debug code and TODOs, and finishes the tests
for SplashActivity.
* Post-merge fixes.
* Test fixes.
* Fix Gradle test.
* Initial commit for expanded xlations support.
This commit introduces the base changes needed to introduce translations
support for all other content strings in the app outside core lessons.
* Undo executors, Kotlin upgrade, and dynamic xform.
This undoes the work of PRs #4484 and others not yet created in order to
isolate the expanded translations support directly off of the develop
branch to expedite getting it finished for the upcoming beta release.
* Part 1 of post-"rebase" fixes.
* Some post-merge fixes.
* Undo changes from #4436.
Isolating domain assets shouldn't be necessary for the expanded
translations support, and it will be easier to manage this PR with fewer
extra things being added to it.
* Fix various tests & update test assets.
Also, remove temporary TODOs.
* Static fixes.
* Add some string resource checks/tools.
Also, fixes major performance issue with all file-based CI checks.
* Ensure newline consistency in translated strings.
Also, fix reporting in new validation check script.
* Add tests & fix static checks.
* Fix broken tests.
* Update version codes & pt-BR strings.
The strings were manually pulled Translatewiki.
* Follow-up adjustments after self-review.
* Undo changes from #4565.
This commit allows the PR to be "rebased" back onto develop so that it
can be prepped for merging.
---
.../CompletedStoryItemViewModel.kt | 14 +-
.../CompletedStoryListViewModel.kt | 5 +-
.../ChapterSummaryViewModel.kt | 18 +-
.../MarkChaptersCompletedFragmentPresenter.kt | 25 +-
.../MarkChaptersCompletedViewModel.kt | 36 ++-
.../StorySummaryViewModel.kt | 2 +-
.../MarkStoriesCompletedFragmentPresenter.kt | 26 +-
.../MarkStoriesCompletedViewModel.kt | 31 +-
.../StorySummaryViewModel.kt | 20 +-
.../MarkTopicsCompletedFragmentPresenter.kt | 23 +-
.../MarkTopicsCompletedViewModel.kt | 28 +-
.../marktopicscompleted/TopicViewModel.kt | 17 +-
.../android/app/home/HomeFragmentPresenter.kt | 7 +-
.../oppia/android/app/home/HomeViewModel.kt | 19 +-
.../promotedlist/ComingSoonTopicsViewModel.kt | 8 +-
.../promotedlist/PromotedStoryViewModel.kt | 20 +-
.../recentlyplayed/OngoingStoryViewModel.kt | 22 +-
.../RecentlyPlayedFragmentPresenter.kt | 15 +-
.../home/topiclist/TopicSummaryViewModel.kt | 16 +-
.../OngoingTopicItemViewModel.kt | 13 +-
.../OngoingTopicListViewModel.kt | 14 +-
.../ExplorationActivityPresenter.kt | 70 ++---
.../ProfileProgressViewModel.kt | 12 +-
.../RecentlyPlayedStorySummaryViewModel.kt | 21 +-
.../ResumeLessonFragmentPresenter.kt | 53 ++--
.../app/resumelesson/ResumeLessonViewModel.kt | 3 +
.../app/story/StoryFragmentPresenter.kt | 7 +-
.../oppia/android/app/story/StoryViewModel.kt | 51 ++--
.../StoryChapterSummaryViewModel.kt | 30 +-
.../app/topic/TopicFragmentPresenter.kt | 8 +-
.../oppia/android/app/topic/TopicViewModel.kt | 32 +-
.../topic/info/TopicInfoFragmentPresenter.kt | 45 ++-
.../app/topic/info/TopicInfoViewModel.kt | 26 +-
.../topic/lessons/ChapterSummaryViewModel.kt | 6 +-
.../topic/lessons/StorySummaryViewModel.kt | 27 +-
.../app/topic/lessons/TopicLessonViewModel.kt | 37 +--
.../lessons/TopicLessonsFragmentPresenter.kt | 10 +-
.../TopicPracticeFragmentPresenter.kt | 17 +-
.../topic/practice/TopicPracticeViewModel.kt | 32 +-
.../TopicPracticeSubtopicViewModel.kt | 15 +-
.../TopicRevisionFragmentPresenter.kt | 11 +-
.../topic/revision/TopicRevisionViewModel.kt | 30 +-
.../TopicRevisionItemViewModel.kt | 18 +-
.../RevisionCardActivityPresenter.kt | 9 +-
.../end/WalkthroughFinalFragmentPresenter.kt | 30 +-
.../WalkthroughTopicListFragmentPresenter.kt | 16 +-
.../topiclist/WalkthroughTopicViewModel.kt | 25 +-
.../WalkthroughTopicSummaryViewModel.kt | 16 +-
.../layout-land/resume_lesson_fragment.xml | 2 +-
.../res/layout-land/topic_info_fragment.xml | 2 +-
.../resume_lesson_fragment.xml | 2 +-
.../topic_info_fragment.xml | 2 +-
.../topic_lessons_story_summary.xml | 2 +-
.../topic_info_fragment.xml | 2 +-
.../res/layout/coming_soon_topic_view.xml | 2 +-
.../main/res/layout/completed_story_item.xml | 6 +-
.../main/res/layout/lessons_chapter_view.xml | 2 +-
...hapters_completed_chapter_summary_view.xml | 2 +-
..._chapters_completed_story_summary_view.xml | 2 +-
...k_stories_completed_story_summary_view.xml | 2 +-
.../mark_topics_completed_topic_view.xml | 2 +-
.../main/res/layout/ongoing_story_card.xml | 4 +-
.../main/res/layout/ongoing_topic_item.xml | 2 +-
...le_progress_recently_played_story_card.xml | 4 +-
.../main/res/layout/promoted_story_card.xml | 6 +-
.../res/layout/resume_lesson_fragment.xml | 2 +-
.../main/res/layout/topic_info_fragment.xml | 2 +-
.../layout/topic_lessons_story_summary.xml | 2 +-
.../res/layout/topic_practice_subtopic.xml | 2 +-
.../layout/topic_revision_summary_view.xml | 2 +-
.../main/res/layout/topic_summary_view.xml | 2 +-
.../app/home/TopicSummaryViewModelTest.kt | 73 +++--
.../PromotedStoryListViewModelTest.kt | 28 +-
.../PromotedStoryViewModelTest.kt | 48 +--
domain/src/main/assets/13.textproto | 20 +-
domain/src/main/assets/2mzzFVDLuAj8.textproto | 20 +-
domain/src/main/assets/5NWuolNcwH6e.textproto | 20 +-
domain/src/main/assets/GJ2rLXRKD5hw.textproto | 20 +-
.../src/main/assets/GJ2rLXRKD5hw_1.textproto | 10 +-
.../src/main/assets/GJ2rLXRKD5hw_2.textproto | 10 +-
.../src/main/assets/GJ2rLXRKD5hw_3.textproto | 10 +-
.../src/main/assets/GJ2rLXRKD5hw_4.textproto | 10 +-
domain/src/main/assets/MjZzEVOG47_1.textproto | 21 +-
domain/src/main/assets/k2bQ7z5XHNbK.textproto | 20 +-
domain/src/main/assets/omzF4oqgeTXd.textproto | 20 +-
.../src/main/assets/omzF4oqgeTXd_1.textproto | 10 +-
domain/src/main/assets/questions.textproto | 1 -
domain/src/main/assets/tIoSb3HZFN6e.textproto | 20 +-
.../src/main/assets/test_exp_id_2.textproto | 20 +-
.../src/main/assets/test_exp_id_4.textproto | 20 +-
.../src/main/assets/test_exp_id_5.textproto | 20 +-
...e_state_exp_no_hints_no_solution.textproto | 20 +-
...tate_exp_with_hints_and_solution.textproto | 20 +-
...xp_with_one_hint_and_no_solution.textproto | 20 +-
...e_exp_with_one_hint_and_solution.textproto | 20 +-
...ive_state_exp_with_only_solution.textproto | 20 +-
...exp_with_solution_missing_answer.textproto | 20 +-
.../src/main/assets/test_story_id_0.textproto | 68 ++++-
.../src/main/assets/test_story_id_2.textproto | 28 +-
.../src/main/assets/test_topic_id_0.textproto | 20 +-
.../main/assets/test_topic_id_0_1.textproto | 10 +-
.../src/main/assets/test_topic_id_1.textproto | 20 +-
.../src/main/assets/test_topic_id_2.textproto | 10 +-
domain/src/main/assets/umPkwp0L1M0-.textproto | 20 +-
domain/src/main/assets/wAMdg4oOClga.textproto | 46 ++-
domain/src/main/assets/wANbh4oOClga.textproto | 50 +++-
domain/src/main/assets/xBSdg4oOClga.textproto | 46 ++-
.../ModifyLessonProgressController.kt | 82 ++---
.../exploration/ExplorationDataController.kt | 39 ++-
.../ExplorationProgressController.kt | 2 +-
.../exploration/ExplorationRetriever.kt | 15 +-
.../domain/topic/RevisionCardRetriever.kt | 15 +-
.../domain/topic/StoryProgressController.kt | 25 +-
.../android/domain/topic/TopicController.kt | 280 ++++++++++++++----
.../domain/topic/TopicListController.kt | 259 ++++++++++------
.../domain/audio/AudioPlayerControllerTest.kt | 6 +-
.../ModifyLessonProgressControllerTest.kt | 78 ++---
.../ExplorationDataControllerTest.kt | 48 +--
.../ExplorationProgressControllerTest.kt | 8 +-
.../analytics/LearnerAnalyticsLoggerTest.kt | 7 +-
.../domain/topic/TopicControllerTest.kt | 102 +++----
.../domain/topic/TopicListControllerTest.kt | 77 +++--
model/src/main/proto/exploration.proto | 16 +-
model/src/main/proto/topic.proto | 254 +++++++++++++---
.../story/StoryProgressTestHelperTest.kt | 2 +-
125 files changed, 2280 insertions(+), 988 deletions(-)
diff --git a/app/src/main/java/org/oppia/android/app/completedstorylist/CompletedStoryItemViewModel.kt b/app/src/main/java/org/oppia/android/app/completedstorylist/CompletedStoryItemViewModel.kt
index ce634b15ccc..fff1d388067 100644
--- a/app/src/main/java/org/oppia/android/app/completedstorylist/CompletedStoryItemViewModel.kt
+++ b/app/src/main/java/org/oppia/android/app/completedstorylist/CompletedStoryItemViewModel.kt
@@ -5,6 +5,7 @@ import org.oppia.android.app.home.RouteToTopicPlayStoryListener
import org.oppia.android.app.model.CompletedStory
import org.oppia.android.app.shim.IntentFactoryShim
import org.oppia.android.app.viewmodel.ObservableViewModel
+import org.oppia.android.domain.translation.TranslationController
/** Completed story view model for the recycler view in [CompletedStoryListFragment]. */
class CompletedStoryItemViewModel(
@@ -12,8 +13,19 @@ class CompletedStoryItemViewModel(
private val internalProfileId: Int,
val completedStory: CompletedStory,
val entityType: String,
- private val intentFactoryShim: IntentFactoryShim
+ private val intentFactoryShim: IntentFactoryShim,
+ translationController: TranslationController
) : ObservableViewModel(), RouteToTopicPlayStoryListener {
+ val completedStoryName by lazy {
+ translationController.extractString(
+ completedStory.storyTitle, completedStory.storyWrittenTranslationContext
+ )
+ }
+ val topicName by lazy {
+ translationController.extractString(
+ completedStory.topicTitle, completedStory.topicWrittenTranslationContext
+ )
+ }
fun onCompletedStoryItemClicked() {
routeToTopicPlayStory(internalProfileId, completedStory.topicId, completedStory.storyId)
diff --git a/app/src/main/java/org/oppia/android/app/completedstorylist/CompletedStoryListViewModel.kt b/app/src/main/java/org/oppia/android/app/completedstorylist/CompletedStoryListViewModel.kt
index 4086552343e..5499e461e66 100644
--- a/app/src/main/java/org/oppia/android/app/completedstorylist/CompletedStoryListViewModel.kt
+++ b/app/src/main/java/org/oppia/android/app/completedstorylist/CompletedStoryListViewModel.kt
@@ -10,6 +10,7 @@ import org.oppia.android.app.shim.IntentFactoryShim
import org.oppia.android.app.viewmodel.ObservableViewModel
import org.oppia.android.domain.oppialogger.OppiaLogger
import org.oppia.android.domain.topic.TopicController
+import org.oppia.android.domain.translation.TranslationController
import org.oppia.android.util.data.AsyncResult
import org.oppia.android.util.data.DataProviders.Companion.toLiveData
import org.oppia.android.util.parser.html.StoryHtmlParserEntityType
@@ -22,6 +23,7 @@ class CompletedStoryListViewModel @Inject constructor(
private val intentFactoryShim: IntentFactoryShim,
private val topicController: TopicController,
private val oppiaLogger: OppiaLogger,
+ private val translationController: TranslationController,
@StoryHtmlParserEntityType private val entityType: String
) : ObservableViewModel() {
/** [internalProfileId] needs to be set before any of the live data members can be accessed. */
@@ -73,7 +75,8 @@ class CompletedStoryListViewModel @Inject constructor(
internalProfileId,
completedStory,
entityType,
- intentFactoryShim
+ intentFactoryShim,
+ translationController
)
}
)
diff --git a/app/src/main/java/org/oppia/android/app/devoptions/markchapterscompleted/ChapterSummaryViewModel.kt b/app/src/main/java/org/oppia/android/app/devoptions/markchapterscompleted/ChapterSummaryViewModel.kt
index 27ac347f097..6b9dd7a112e 100644
--- a/app/src/main/java/org/oppia/android/app/devoptions/markchapterscompleted/ChapterSummaryViewModel.kt
+++ b/app/src/main/java/org/oppia/android/app/devoptions/markchapterscompleted/ChapterSummaryViewModel.kt
@@ -1,16 +1,28 @@
package org.oppia.android.app.devoptions.markchapterscompleted
import org.oppia.android.app.model.ChapterPlayState
-import org.oppia.android.app.model.ChapterSummary
+import org.oppia.android.app.model.EphemeralChapterSummary
+import org.oppia.android.domain.translation.TranslationController
/** [MarkChaptersCompletedItemViewModel] for displaying a chapter summary. */
class ChapterSummaryViewModel(
val chapterIndex: Int,
- val chapterSummary: ChapterSummary,
+ ephemeralChapterSummary: EphemeralChapterSummary,
val nextStoryIndex: Int,
val storyId: String,
- val topicId: String
+ val topicId: String,
+ translationController: TranslationController
) : MarkChaptersCompletedItemViewModel() {
+ /** The summary of the chapter being displayed. */
+ val chapterSummary = ephemeralChapterSummary.chapterSummary
+
+ /** The localized title of the chapter being displayed. */
+ val chapterTitle by lazy {
+ translationController.extractString(
+ chapterSummary.title, ephemeralChapterSummary.writtenTranslationContext
+ )
+ }
+
/** Returns whether the chapter represented by the current view model is completed. */
fun checkIfChapterIsCompleted(): Boolean =
chapterSummary.chapterPlayState == ChapterPlayState.COMPLETED
diff --git a/app/src/main/java/org/oppia/android/app/devoptions/markchapterscompleted/MarkChaptersCompletedFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/devoptions/markchapterscompleted/MarkChaptersCompletedFragmentPresenter.kt
index 69bfbe61824..8458664151b 100644
--- a/app/src/main/java/org/oppia/android/app/devoptions/markchapterscompleted/MarkChaptersCompletedFragmentPresenter.kt
+++ b/app/src/main/java/org/oppia/android/app/devoptions/markchapterscompleted/MarkChaptersCompletedFragmentPresenter.kt
@@ -10,7 +10,6 @@ import androidx.recyclerview.widget.RecyclerView
import org.oppia.android.app.fragment.FragmentScope
import org.oppia.android.app.model.ProfileId
import org.oppia.android.app.recyclerview.BindableAdapter
-import org.oppia.android.app.viewmodel.ViewModelProvider
import org.oppia.android.databinding.MarkChaptersCompletedChapterSummaryViewBinding
import org.oppia.android.databinding.MarkChaptersCompletedFragmentBinding
import org.oppia.android.databinding.MarkChaptersCompletedStorySummaryViewBinding
@@ -22,7 +21,7 @@ import javax.inject.Inject
class MarkChaptersCompletedFragmentPresenter @Inject constructor(
private val activity: AppCompatActivity,
private val fragment: Fragment,
- private val viewModelProvider: ViewModelProvider,
+ private val viewModel: MarkChaptersCompletedViewModel,
private val modifyLessonProgressController: ModifyLessonProgressController
) : ChapterSelector {
private lateinit var binding: MarkChaptersCompletedFragmentBinding
@@ -49,13 +48,13 @@ class MarkChaptersCompletedFragmentPresenter @Inject constructor(
binding.apply {
this.lifecycleOwner = fragment
- this.viewModel = getMarkChaptersCompletedViewModel()
+ this.viewModel = this@MarkChaptersCompletedFragmentPresenter.viewModel
}
this.selectedExplorationIdList = selectedExplorationIdList
profileId = ProfileId.newBuilder().setInternalId(internalProfileId).build()
- getMarkChaptersCompletedViewModel().setProfileId(profileId)
+ viewModel.setProfileId(profileId)
linearLayoutManager = LinearLayoutManager(activity.applicationContext)
@@ -68,7 +67,7 @@ class MarkChaptersCompletedFragmentPresenter @Inject constructor(
binding.markChaptersCompletedAllCheckBoxContainer.setOnClickListener {
if (binding.isAllChecked == null || binding.isAllChecked == false) {
binding.isAllChecked = true
- getMarkChaptersCompletedViewModel().getItemList().forEach { viewModel ->
+ viewModel.getItemList().forEach { viewModel ->
if (viewModel is ChapterSummaryViewModel) {
if (!viewModel.checkIfChapterIsCompleted())
chapterSelected(
@@ -84,8 +83,7 @@ class MarkChaptersCompletedFragmentPresenter @Inject constructor(
binding.markChaptersCompletedMarkCompletedTextView.setOnClickListener {
modifyLessonProgressController.markMultipleChaptersCompleted(
profileId = profileId,
- chapterMap = getMarkChaptersCompletedViewModel().getChapterMap()
- .filterKeys { selectedExplorationIdList.contains(it) }
+ chapterMap = viewModel.getChapterMap().filterKeys { selectedExplorationIdList.contains(it) }
)
activity.finish()
}
@@ -122,7 +120,7 @@ class MarkChaptersCompletedFragmentPresenter @Inject constructor(
model: ChapterSummaryViewModel
) {
binding.viewModel = model
- val notCompletedChapterCount = getMarkChaptersCompletedViewModel().getItemList().count {
+ val notCompletedChapterCount = viewModel.getItemList().count {
it is ChapterSummaryViewModel && !it.checkIfChapterIsCompleted()
}
if (notCompletedChapterCount == 0) {
@@ -155,16 +153,12 @@ class MarkChaptersCompletedFragmentPresenter @Inject constructor(
}
}
- private fun getMarkChaptersCompletedViewModel(): MarkChaptersCompletedViewModel {
- return viewModelProvider.getForFragment(fragment, MarkChaptersCompletedViewModel::class.java)
- }
-
override fun chapterSelected(chapterIndex: Int, nextStoryIndex: Int, explorationId: String) {
if (!selectedExplorationIdList.contains(explorationId)) {
selectedExplorationIdList.add(explorationId)
}
if (selectedExplorationIdList.size ==
- getMarkChaptersCompletedViewModel().getItemList().count {
+ viewModel.getItemList().count {
it is ChapterSummaryViewModel && !it.checkIfChapterIsCompleted()
}
) {
@@ -182,14 +176,13 @@ class MarkChaptersCompletedFragmentPresenter @Inject constructor(
override fun chapterUnselected(chapterIndex: Int, nextStoryIndex: Int) {
for (index in chapterIndex until nextStoryIndex) {
val explorationId =
- (getMarkChaptersCompletedViewModel().getItemList()[index] as ChapterSummaryViewModel)
- .chapterSummary.explorationId
+ (viewModel.getItemList()[index] as ChapterSummaryViewModel).chapterSummary.explorationId
if (selectedExplorationIdList.contains(explorationId)) {
selectedExplorationIdList.remove(explorationId)
}
}
if (selectedExplorationIdList.size !=
- getMarkChaptersCompletedViewModel().getItemList().count {
+ viewModel.getItemList().count {
it is ChapterSummaryViewModel && !it.checkIfChapterIsCompleted()
}
) {
diff --git a/app/src/main/java/org/oppia/android/app/devoptions/markchapterscompleted/MarkChaptersCompletedViewModel.kt b/app/src/main/java/org/oppia/android/app/devoptions/markchapterscompleted/MarkChaptersCompletedViewModel.kt
index 24d1b7fc4e7..3c7fe863f5e 100644
--- a/app/src/main/java/org/oppia/android/app/devoptions/markchapterscompleted/MarkChaptersCompletedViewModel.kt
+++ b/app/src/main/java/org/oppia/android/app/devoptions/markchapterscompleted/MarkChaptersCompletedViewModel.kt
@@ -3,11 +3,12 @@ package org.oppia.android.app.devoptions.markchapterscompleted
import androidx.lifecycle.LiveData
import androidx.lifecycle.Transformations
import org.oppia.android.app.fragment.FragmentScope
+import org.oppia.android.app.model.EphemeralStorySummary
import org.oppia.android.app.model.ProfileId
-import org.oppia.android.app.model.StorySummary
import org.oppia.android.app.viewmodel.ObservableViewModel
import org.oppia.android.domain.devoptions.ModifyLessonProgressController
import org.oppia.android.domain.oppialogger.OppiaLogger
+import org.oppia.android.domain.translation.TranslationController
import org.oppia.android.util.data.AsyncResult
import org.oppia.android.util.data.DataProviders.Companion.toLiveData
import javax.inject.Inject
@@ -19,7 +20,8 @@ import javax.inject.Inject
@FragmentScope
class MarkChaptersCompletedViewModel @Inject constructor(
private val oppiaLogger: OppiaLogger,
- private val modifyLessonProgressController: ModifyLessonProgressController
+ private val modifyLessonProgressController: ModifyLessonProgressController,
+ private val translationController: TranslationController
) : ObservableViewModel() {
private lateinit var profileId: ProfileId
@@ -34,20 +36,22 @@ class MarkChaptersCompletedViewModel @Inject constructor(
Transformations.map(storyMapLiveData, ::processStoryMap)
}
- private val storyMapLiveData: LiveData