-
Notifications
You must be signed in to change notification settings - Fork 537
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix #3728, #3817, #3810, part of #1607: Integrate automatic app string language selection support #3795
Fix #3728, #3817, #3810, part of #1607: Integrate automatic app string language selection support #3795
Conversation
There are a lot of details to cover here--see the PR for the complete context.
- Add missing codeowner - Add support for configuring base branch reference - Update CI for dev/alpha AAB builds to use 'develop' since there's no origin configured by default in the workflows
This is needed to open a PR on GitHub. This commit is being made so that the PR can start off in a broken Actions state. This also initially disables most non-Bazel workflows to make workflow iteration faster and less impacting on other team members.
This introduces a new mechanism for passing lists of tests to sharded test targets in CI, and hooks it up. No actual sharding is occurring yet. This led to some simplifications in the CI workflow since the script can be more dynamic in computing the full list of targets (which also works around a previous bug with instrumentation tests being run). Java proto lite also needed to be upgraded for the scripts to be able to use it. More testing/documentation needed as this functionality continues to expand.
This simply partitions bucketed groups of targets into chunks of 10 for each run. Only 3 buckets are currently retained to test sharding in CI before introducing full support.
Fixes some caching bucket and output bugs. Also, introduces while loop & keep_going to introduce resilience against app test build failures (or just test failures in general).
Also, enable other workflows. Note that CI shouldn't fully pass yet since some documentation and testing needs to be added yet, but this is meant to be a more realistic test of the CI environment before the PR is finished.
Adds a human-readable prefix to make the shards look a bit nicer. Also, adds more fine-tuned partitioning to bucket & reduce shard counts to improve overall timing. Will need to be tested in CI.
A newly computed variable wasn't updated to be used in an earlier change.
Add docstrings for proto.
…/oppia-android into add-bundles-proguard-build-flavors
See #3757 (comment) for context.
Neither 'mv -t' nor piping to mv work on OSX so we needed to find an alternative (in this case just trying to move everything). This actually works a bit better since it's doing a per-file move rather than accommodating for files that shouldn't be moved (which isn't an issue since the destination directory is different than the one containing the AAB file).
Documentation, thorough tests, and detailed description of these changes are still needed.
This demonstrates working string selection for system-based and overwritten app languages, including necessary activity recreation & layout direction overwriting. This also includes a bunch of Dagger infra refactoring so that some app layer packages can now be modularized (including the new packages).
…o localization-part5-introduce-app-string-translations-support-and-refactor
This involves MANY broad changes to ensure consistent string retrieval (for arrays and plurals), formatting, and string transformations throughout the codebase. Some extra patterns to added to fix things that were needed, and a few issues were fixed along the way.
Gradle CI failure:
Given this is a new suite, this could be a flake. I'll restart the CI job, but I'll also run the suite locally in this branch to see how flaky it actually is. |
Looks like it's flaky and will require some investigationg: //testing/src/test/java/org/oppia/android/testing/data:DataProviderTestMonitorTest FAILED in 4 out of 160 in 31.2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks.
@@ -22,7 +23,7 @@ class OppiaApplication : | |||
.build() | |||
} | |||
|
|||
override fun createActivityComponent(activity: AppCompatActivity): ActivityComponent { | |||
override fun createActivityComponent(activity: AppCompatActivity): ActivityComponentImpl { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be renamed to createActivityComponentImpl
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The contract comes from ActivityComponentFactory which must return ActivityComponent (in order for the dependencies to build correctly in Gradle, and conceptually an impl shouldn't be returned). This is just overriding the return type to be more specific.
Updated this to return ActivityComponent instead since it doesn't need to actually be more specific in order to build.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looked over test files. Need to look over the domain file as well in the next pass.
app/src/sharedTest/java/org/oppia/android/app/player/state/StateFragmentTest.kt
Outdated
Show resolved
Hide resolved
Unassigning @anandwana001 since the review is done. |
…ranslations-support-and-refactor Conflicts: app/src/sharedTest/java/org/oppia/android/app/testing/ImageRegionSelectionInteractionViewTest.kt
I think both of your comments are addressed. PTAL @rt4914 & @anandwana001. Also, @anandwana001 PTAL at eec5a9f specifically since it came in after your last review round. |
Unassigning @BenHenning since a re-review was requested. @BenHenning, please make sure you have addressed all review comments. Thanks! |
This LGTM |
Ah, I forgot to include this earlier but https://app.buildbuddy.io/invocation/036f70b3-353d-4536-bc84-5f1ad6f4b9da are the results demonstrating that DataProviderMonitorTest is no longer flaky. |
Unassigning @vinitamurthi since they have already approved the PR. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Domain files LGTM
Thanks all! Going ahead and merging this to avoid new changes causing conflicts. @rt4914 if you have any concerns with my resolution of your comment above, please follow up with me. I'm taking your approval to mean that you're fine with me merging this as-is. |
Explanation
Fix #3728
Fix #3817
Fix #3810
Fix part of #1607
This PR introduces support for automatic app string translations based on the system language. Note that while Android takes care of most of the heavy lifting here, this PR is set up specifically to support both in-app language selection (which will be implemented in #52) and custom languages that the Android system doesn't natively support (such as Hinglish). Both of these have been tested manually to work with this system, but aren't yet hooked up to real situations. See the design document linked in & overview from #3794 for more details.
Two other major aspects that contribute to the complexity of this PR:
How language selection works
At a high-level, language selection works by building an Android Locale from an OppiaLocaleContext that can be used for string transformations, bidirectional wrapping, date/time computations, and string selection. The locale context is computed based either on pre-configured language definitions (via textproto files introduced in #3794), or the system locale. The app currently defaults to the system locale, but #52 will introduce an in-app language picker that will let users overwrite this behavior to select a specific language, instead.
Note essentially all locale operations are forcibly hidden via API changes & regex checks behind domain & utility classes that can ensure the correct locale is used in the correct circumstance. For users, this generally comes down deciding between two things:
There's a lot of complexity behind the formatting changes above, and both this & #3794's PR descriptions cover those in more detail.
The main complexity in this PR is around the app string piece. We can't actually tell Android (easily) to use a particular Locale when selecting a language. However, we can force it by overriding the default Locale in the application context & recreating the activity (if the locale changes), so long as we override the locale prior to activity initialization happening. This is why InjectableAppCompatActivity has changed a lot, and why bootstrapping is now needed in both SplashActivity & throughout tests. I'm not yet sure if this is the final approach we want to take for language selection, but it seems like it might be the only option if we want to either support an in-app language selector or non-native Android languages (since the resource qualifying will work even for non-standard or non-natively supported locales; I've tested app strings successfully with Hinglish as a proof-of-concept).
To aid with this complexity, a mixin was introduced to detect when to automatically recreate the activity. Some care is taken to ensure an infinite loop doesn't get introduced, either, since the app language can depend on the system language & the system language can trigger a configuration change/activity recreation from the system. Note that it's expected language selections from the system language menu can cause 2 activity recreations before the app stabilizes, but this is generally hidden from the user. This is also an area where we can probably make improvements in the future.
One key design philosophy here was ensuring that the display locale be fixed for the lifetime of the activity (hence the need for recreation). Besides the fact that the force-locale mechanism seems to work much better when done during activity initialization, this also simplifies the design since it allows the existing of an activity-scoped resource handler which can managed access to the display locale directly & automatically tie it to the activity's resources for a nicer resource retrieval mechanism. This has the added side effect of more complexity in tests, though, since we now need an activity in many more cases than we did before.
Finally, one design alternative that was considered (& is currently documented in the design doc for this project) was to use an intent to carry the Oppia locale (via its context) through the activity tree. This would have prevented #3800 at the cost of more boilerplate (especially around activity starting). However, I discovered during implementation that the activity's intent is not available in onAttachBase since it hasn't yet been initialized, so this approach isn't possible unfortunately (which is why the singleton needed to be introduced, instead).
New tests & test changes
New tests:
Test considerations:
TestActivity
was introduced for this purpose, and may serve as our long-term test staging activity once Dagger Hilt provides a means to get rid of all specialized test activities.Specific known issues & fix explanations
Script exemptions
Other miscellaneous considerations
Essential Checklist
For UI-specific PRs only
Overview screenshots & video (with real RTL language screenshots)
Note that there aren't meaningful "before" screenshots for this feature since it's introducing infrastructural support for something that the system natively supports (automatic string switching when a language is chosen within the system). Screenshots & a video are provided below to help better understand the nature of the changes behind this PR. Also, note that only the home screen is covered for the portrait/landscape screen as an example. Every activity in the app is affected by this PR.
Portrait (with changes) -- English:
Portrait (with changes) -- Arabic:
Landscape (with changes) -- English:
Landscape (with changes) -- Arabic:
Video demonstration of the feature:
https://user-images.githubusercontent.com/12983742/134875862-4a3eba7a-430c-4120-880a-e93c1b4a4955.mp4
Accessibility overview
Accessibility isn't expected to be changed as part of this PR, but for thoroughness here's the same video above with Talkback enabled for both supported languages.
Video with Talkback for English -> Arabic:
https://user-images.githubusercontent.com/12983742/134876927-1a58e1ff-3d24-490e-b5cc-09aebbcdc763.mp4
Video with Talkback for English -> Brazilian Portuguese:
https://user-images.githubusercontent.com/12983742/134876968-3f6c885d-605b-4dea-befd-6f51b2b44c6a.mp4
Espresso tests
The two Espresso tests directly affected by this PR are HomeActivityTest & SplashActivityTest. As mentioned above, the former is having issues on Espresso so that's not being demonstrated here. See the following screenshot for SplashActivityTest changes passing: