Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions app/src/main/kotlin/com/x8bit/bitwarden/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,14 @@ class MainActivity : AppCompatActivity() {
.takeIf { it }
?: super.dispatchKeyEvent(event)

override fun onPostCreate(savedInstanceState: Bundle?) {
super.onPostCreate(savedInstanceState)
// resize only one time at the start
if (!mainViewModel.stateFlow.value.hasResizeBeenRequested) {
setHorizonOSAppLayout()
}
}

@Composable
private fun SetupEventsEffect(navController: NavController) {
EventsEffect(viewModel = mainViewModel) { event ->
Expand Down Expand Up @@ -257,4 +265,31 @@ class MainActivity : AppCompatActivity() {
window.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
}
}

private fun isHorizonOSDevice(): Boolean {
return Build.MANUFACTURER.equals("Oculus", ignoreCase = true) ||
Build.MANUFACTURER.equals("Meta", ignoreCase = true)
}

@Suppress("MagicNumber", "TooGenericExceptionCaught")
private fun setHorizonOSAppLayout() {
if (!isHorizonOSDevice()) {
return
}
window.decorView.post {
try {
val clazz = Class.forName("horizonos.view.WindowExt")
val method = clazz.getMethod(
"requestWindowResize",
android.view.Window::class.java,
Int::class.javaPrimitiveType,
Int::class.javaPrimitiveType,
)
method.invoke(null, window, 1024, 640)
mainViewModel.trySendAction(MainAction.Internal.ResizeHasBeenRequested)
} catch (t: Throwable) {
// Not Horizon OS / API not present / request ignored by system
}
}
}
}
12 changes: 12 additions & 0 deletions app/src/main/kotlin/com/x8bit/bitwarden/MainViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ class MainViewModel @Inject constructor(
theme = settingsRepository.appTheme,
isScreenCaptureAllowed = settingsRepository.isScreenCaptureAllowed,
isDynamicColorsEnabled = settingsRepository.isDynamicColorsEnabled,
hasResizeBeenRequested = false,
),
) {
private var specialCircumstance: SpecialCircumstance?
Expand Down Expand Up @@ -228,6 +229,7 @@ class MainViewModel @Inject constructor(
is MainAction.Internal.ThemeUpdate -> handleAppThemeUpdated(action)
is MainAction.Internal.DynamicColorsUpdate -> handleDynamicColorsUpdate(action)
is MainAction.Internal.CookieAcquisitionReady -> handleCookieAcquisitionReady()
is MainAction.Internal.ResizeHasBeenRequested -> handleResizeHasBeenRequested()
}
}

Expand Down Expand Up @@ -296,6 +298,10 @@ class MainViewModel @Inject constructor(
sendEvent(MainEvent.NavigateToCookieAcquisition)
}

private fun handleResizeHasBeenRequested() {
mutableStateFlow.update { it.copy(hasResizeBeenRequested = true) }
}

private fun handleFirstIntentReceived(action: MainAction.ReceiveFirstIntent) {
handleIntent(
intent = action.intent,
Expand Down Expand Up @@ -517,6 +523,7 @@ data class MainState(
val theme: AppTheme,
val isScreenCaptureAllowed: Boolean,
val isDynamicColorsEnabled: Boolean,
val hasResizeBeenRequested: Boolean,
) : Parcelable {
/**
* Contains all feature flags that are available to the UI.
Expand Down Expand Up @@ -620,6 +627,11 @@ sealed class MainAction {
* should proceed.
*/
data object CookieAcquisitionReady : Internal()

/**
* Indicates that resize has been requested on the Activity
*/
data object ResizeHasBeenRequested : Internal()
}
}

Expand Down
25 changes: 25 additions & 0 deletions app/src/test/kotlin/com/x8bit/bitwarden/MainViewModelTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -1185,6 +1185,30 @@ class MainViewModelTest : BaseViewModelTest() {
}
}

@Test
fun `on handleResizeHasBeenRequested should set hasResizeBeenRequested as true`() = runTest {
val viewModel = createViewModel()
val initialState = MainState(
theme = settingsRepository.appTheme,
isScreenCaptureAllowed = settingsRepository.isScreenCaptureAllowed,
isDynamicColorsEnabled = settingsRepository.isDynamicColorsEnabled,
hasResizeBeenRequested = false,
)
viewModel.stateFlow.test {
assertEquals(
initialState,
awaitItem(),
)
viewModel.trySendAction(MainAction.Internal.ResizeHasBeenRequested)
assertEquals(
initialState.copy(
hasResizeBeenRequested = true,
),
awaitItem(),
)
}
}

private fun createViewModel(
initialSpecialCircumstance: SpecialCircumstance? = null,
) = MainViewModel(
Expand Down Expand Up @@ -1213,6 +1237,7 @@ private val DEFAULT_STATE: MainState = MainState(
theme = AppTheme.DEFAULT,
isScreenCaptureAllowed = true,
isDynamicColorsEnabled = false,
hasResizeBeenRequested = false,
)

private val DEFAULT_FIRST_TIME_STATE = FirstTimeState(
Expand Down
Loading