Settings Screen: Java/XML to Kotlin/Compose migration + tests#101
Settings Screen: Java/XML to Kotlin/Compose migration + tests#101m4pl wants to merge 11 commits intoGrapheneOS:mainfrom
Conversation
38013d9 to
05688c9
Compare
| import dagger.hilt.components.SingletonComponent | ||
|
|
||
| @Module | ||
| @InstallIn(SingletonComponent::class) |
There was a problem hiding this comment.
Should be ViewModelComponent probably
50c7726 to
af392d1
Compare
af392d1 to
90cc047
Compare
| is SettingsNavRoute.SubscriptionSettings -> { | ||
| val sub = uiState.subscriptionSettings.find { it.subId == route.subId } | ||
| if (sub != null) { | ||
| SubscriptionSettingsScreen( | ||
| subscriptionSettings = sub, | ||
| title = route.title, | ||
| screenModel = screenModel, | ||
| onNavigateBack = navigateUp, | ||
| ) | ||
| } | ||
| } |
There was a problem hiding this comment.
On a dual-SIM setup, if looking at settings for a SIM and that SIM is removed (eSIM is disabled or physical SIM is removed), sub will be null. Since nothing is used for sub == null case, the entire screen turns white until back gesture.
We should show something (e.g. make SubscriptionSettingsScreen accept a nullable subscriptionSettings and handle it inside) or force the user to go back when SIM is removed (i.e., when sub is null) while SubscriptionSettingsScreen is currently being used (and then add a test for this case)
There was a problem hiding this comment.
Good catch, this definitely needs to be handled
| val displayPhoneNumber = when { | ||
| !savedPhoneNumber.isNullOrEmpty() -> phoneUtils.formatForDisplay(savedPhoneNumber) | ||
| !defaultPhoneNumber.isNullOrEmpty() -> phoneUtils.formatForDisplay(defaultPhoneNumber) | ||
| else -> context.getString(R.string.unknown_phone_number_pref_display_value) | ||
| } |
There was a problem hiding this comment.
Current code only uses the equivalent of PhoneUtils.get(mSubId).formatForDisplay(value)
Previous code used PhoneUtils.get(mSubId).formatForDisplay(value) then bidiFormatter.unicodeWrap(displayValue, TextDirectionHeuristicsCompat.LTR); for phone number preference summary.
It seems we should add this back. There's also the Compose-equivalent of this like TextStyle(textDirection = TextDirection.ContentOrLtr) for phone number Text or OutlinedTextFields. The BidiFormatter usage seems easier/more unconditional though + it would help if string is embedded somewhere else.
| Switch( | ||
| checked = checked, | ||
| onCheckedChange = null, | ||
| ) |
There was a problem hiding this comment.
the enabled flag should be passed to the switch. Currently the switch is not dimmed when the SettingsSwitchItem's enabled is false
e.g., disable the Auto-retrieve preference and look at the switch for Roaming auto-retrieve, especially when Roaming auto-retrieve is on
There was a problem hiding this comment.
Agreed, I’ll update it so it is less confusing for users
| ) | ||
| } | ||
|
|
||
| items(subscriptions) { subscription -> |
There was a problem hiding this comment.
| items(subscriptions) { subscription -> | |
| items(subscriptions, key = { it.subId }) { subscription -> |
| @Before | ||
| fun setUpDefaultSmsApp() { | ||
| val instrumentation = InstrumentationRegistry.getInstrumentation() | ||
| val packageName = instrumentation.targetContext.packageName | ||
| val command = "cmd role add-role-holder android.app.role.SMS $packageName" | ||
| val parcelFileDescriptor = instrumentation.uiAutomation.executeShellCommand(command) | ||
|
|
||
| ParcelFileDescriptor.AutoCloseInputStream(parcelFileDescriptor).use { inputStream -> | ||
| val result = String(inputStream.readBytes()) | ||
| println("Role assignment result: $result") | ||
| } | ||
| } |
There was a problem hiding this comment.
This seems like it could be in a @BeforeClass as well (if more tests are added, it'll run for every test)
There was a problem hiding this comment.
Yes, that is a good idea for future tests. I’ll update it
| <activity | ||
| android:name=".ui.appsettings.SettingsActivity" | ||
| android:label="@string/settings_activity_title" | ||
| android:theme="@style/BugleTheme.SettingsActivity" | ||
| android:configChanges="orientation|screenSize|keyboardHidden" | ||
| android:screenOrientation="user" | ||
| android:parentActivityName="com.android.messaging.ui.conversationlist.ConversationListActivity"> | ||
| <meta-data | ||
| android:name="android.support.PARENT_ACTIVITY" | ||
| android:value="com.android.messaging.ui.conversationlist.ConversationListActivity" /> | ||
| </activity> | ||
|
|
||
| <activity | ||
| android:name=".ui.appsettings.PerSubscriptionSettingsActivity" | ||
| android:label="@string/advanced_settings_activity_title" | ||
| android:theme="@style/BugleTheme.SettingsActivity" | ||
| android:allowEmbedded="true" | ||
| android:configChanges="orientation|screenSize|keyboardHidden" | ||
| android:screenOrientation="user" | ||
| android:parentActivityName="com.android.messaging.ui.appsettings.SettingsActivity"> | ||
| <meta-data | ||
| android:name="android.support.PARENT_ACTIVITY" | ||
| android:value="com.android.messaging.ui.appsettings.SettingsActivity" /> | ||
| </activity> | ||
|
|
||
| <activity | ||
| android:name=".ui.appsettings.ApplicationSettingsActivity" | ||
| android:exported="true" |
There was a problem hiding this comment.
Technically, this is removing the exported Activity .ui.appsettings.ApplicationSettingsActivity and just using .ui.appsettings.SettingsActivity now.
Since .ui.appsettings.ApplicationSettingsActivity used to be exported, for completeness, maybe an activity-alias could be added here for .ui.appsettings.ApplicationSettingsActivity with android:targetActivity=".ui.appsettings.SettingsActivity">
Migrated the Settings screen from Java + XML to Kotlin + Compose. Added unit tests for Composable(s) and ViewModel. Additionally, wrote an E2E test covering the flow: user opens Conversations list screen and navigates to a conversation.
Screenshots
Figma
https://figma.com/design/JtQuS3wQQs9YdwrtZtGw0y