1 package com.android.systemui.unfold.util 2 3 import android.content.Context 4 import android.os.RemoteException 5 import android.view.IRotationWatcher 6 import android.view.IWindowManager 7 import android.view.Surface 8 import com.android.systemui.unfold.UnfoldTransitionProgressProvider 9 import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener 10 11 /** 12 * [UnfoldTransitionProgressProvider] that emits transition progress only when the display has 13 * default rotation or 180 degrees opposite rotation (ROTATION_0 or ROTATION_180). 14 * It could be helpful to run the animation only when the display's rotation is perpendicular 15 * to the fold. 16 */ 17 class NaturalRotationUnfoldProgressProvider( 18 private val context: Context, 19 private val windowManagerInterface: IWindowManager, 20 unfoldTransitionProgressProvider: UnfoldTransitionProgressProvider 21 ) : UnfoldTransitionProgressProvider { 22 23 private val scopedUnfoldTransitionProgressProvider = 24 ScopedUnfoldTransitionProgressProvider(unfoldTransitionProgressProvider) 25 private val rotationWatcher = RotationWatcher() 26 27 private var isNaturalRotation: Boolean = false 28 29 fun init() { 30 try { 31 windowManagerInterface.watchRotation(rotationWatcher, context.display.displayId) 32 } catch (e: RemoteException) { 33 throw e.rethrowFromSystemServer() 34 } 35 36 onRotationChanged(context.display.rotation) 37 } 38 39 private fun onRotationChanged(rotation: Int) { 40 val isNewRotationNatural = rotation == Surface.ROTATION_0 || 41 rotation == Surface.ROTATION_180 42 43 if (isNaturalRotation != isNewRotationNatural) { 44 isNaturalRotation = isNewRotationNatural 45 scopedUnfoldTransitionProgressProvider.setReadyToHandleTransition(isNewRotationNatural) 46 } 47 } 48 49 override fun destroy() { 50 try { 51 windowManagerInterface.removeRotationWatcher(rotationWatcher) 52 } catch (e: RemoteException) { 53 e.rethrowFromSystemServer() 54 } 55 56 scopedUnfoldTransitionProgressProvider.destroy() 57 } 58 59 override fun addCallback(listener: TransitionProgressListener) { 60 scopedUnfoldTransitionProgressProvider.addCallback(listener) 61 } 62 63 override fun removeCallback(listener: TransitionProgressListener) { 64 scopedUnfoldTransitionProgressProvider.removeCallback(listener) 65 } 66 67 private inner class RotationWatcher : IRotationWatcher.Stub() { 68 override fun onRotationChanged(rotation: Int) { 69 this@NaturalRotationUnfoldProgressProvider.onRotationChanged(rotation) 70 } 71 } 72 } 73