Merge "LockscreenShadeTransitionController: extract logic of keyguard and scrims" into tm-dev am: 941937ea1c am: 6fed0856e6

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/17523088

Change-Id: I95319ce79369874c305517aca6250d5ab66c8330
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/AbstractLockscreenShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/AbstractLockscreenShadeTransitionController.kt
new file mode 100644
index 0000000..189f384
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/AbstractLockscreenShadeTransitionController.kt
@@ -0,0 +1,61 @@
+package com.android.systemui.statusbar
+
+import android.content.Context
+import android.content.res.Configuration
+import android.util.IndentingPrintWriter
+import com.android.systemui.Dumpable
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.statusbar.policy.ConfigurationController
+import com.android.systemui.util.LargeScreenUtils
+import java.io.FileDescriptor
+import java.io.PrintWriter
+
+/** An abstract implementation of a class that controls the lockscreen to shade transition. */
+abstract class AbstractLockscreenShadeTransitionController(
+    protected val context: Context,
+    configurationController: ConfigurationController,
+    dumpManager: DumpManager
+) : Dumpable {
+
+    protected var useSplitShade = false
+
+    /**
+     * The amount of pixels that the user has dragged down during the shade transition on
+     * lockscreen.
+     */
+    var dragDownAmount = 0f
+        set(value) {
+            if (value == field) {
+                return
+            }
+            field = value
+            onDragDownAmountChanged(value)
+        }
+
+    init {
+        updateResourcesInternal()
+        configurationController.addCallback(
+            object : ConfigurationController.ConfigurationListener {
+                override fun onConfigChanged(newConfig: Configuration?) {
+                    updateResourcesInternal()
+                }
+            })
+        @Suppress("LeakingThis")
+        dumpManager.registerDumpable(this)
+    }
+
+    private fun updateResourcesInternal() {
+        useSplitShade = LargeScreenUtils.shouldUseSplitNotificationShade(context.resources)
+        updateResources()
+    }
+
+    protected abstract fun updateResources()
+
+    protected abstract fun onDragDownAmountChanged(dragDownAmount: Float)
+
+    override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<out String>) {
+        dump(IndentingPrintWriter(pw, /* singleIndent= */ "  "))
+    }
+
+    abstract fun dump(pw: IndentingPrintWriter)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeKeyguardTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeKeyguardTransitionController.kt
new file mode 100644
index 0000000..01eb444
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeKeyguardTransitionController.kt
@@ -0,0 +1,120 @@
+package com.android.systemui.statusbar
+
+import android.content.Context
+import android.util.IndentingPrintWriter
+import android.util.MathUtils
+import com.android.systemui.R
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.media.MediaHierarchyManager
+import com.android.systemui.statusbar.phone.NotificationPanelViewController
+import com.android.systemui.statusbar.policy.ConfigurationController
+import dagger.assisted.Assisted
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+
+/** Controls the lockscreen to shade transition for the keyguard elements. */
+class LockscreenShadeKeyguardTransitionController
+@AssistedInject
+constructor(
+    private val mediaHierarchyManager: MediaHierarchyManager,
+    @Assisted private val notificationPanelController: NotificationPanelViewController,
+    context: Context,
+    configurationController: ConfigurationController,
+    dumpManager: DumpManager
+) : AbstractLockscreenShadeTransitionController(context, configurationController, dumpManager) {
+
+    /**
+     * Distance that the full shade transition takes in order for the keyguard content on
+     * NotificationPanelViewController to fully fade (e.g. Clock & Smartspace).
+     */
+    private var alphaTransitionDistance = 0
+
+    /**
+     * Distance that the full shade transition takes in order for the keyguard elements to fully
+     * translate into their final position
+     */
+    private var keyguardTransitionDistance = 0
+
+    /** The amount of vertical offset for the keyguard during the full shade transition. */
+    private var keyguardTransitionOffset = 0
+
+    /** The amount of alpha that was last set on the keyguard elements. */
+    private var alpha = 0f
+
+    /** The latest progress [0,1] of the alpha transition. */
+    private var alphaProgress = 0f
+
+    /** The amount of alpha that was last set on the keyguard status bar. */
+    private var statusBarAlpha = 0f
+
+    /** The amount of translationY that was last set on the keyguard elements. */
+    private var translationY = 0
+
+    /** The latest progress [0,1] of the translationY progress. */
+    private var translationYProgress = 0f
+
+    override fun updateResources() {
+        alphaTransitionDistance =
+            context.resources.getDimensionPixelSize(
+                R.dimen.lockscreen_shade_npvc_keyguard_content_alpha_transition_distance)
+        keyguardTransitionDistance =
+            context.resources.getDimensionPixelSize(
+                R.dimen.lockscreen_shade_keyguard_transition_distance)
+        keyguardTransitionOffset =
+            context.resources.getDimensionPixelSize(
+                R.dimen.lockscreen_shade_keyguard_transition_vertical_offset)
+    }
+
+    override fun onDragDownAmountChanged(dragDownAmount: Float) {
+        alphaProgress = MathUtils.saturate(dragDownAmount / alphaTransitionDistance)
+        alpha = 1f - alphaProgress
+        translationY = calculateKeyguardTranslationY(dragDownAmount)
+        notificationPanelController.setKeyguardTransitionProgress(alpha, translationY)
+
+        statusBarAlpha = if (useSplitShade) alpha else -1f
+        notificationPanelController.setKeyguardStatusBarAlpha(statusBarAlpha)
+    }
+
+    private fun calculateKeyguardTranslationY(dragDownAmount: Float): Int {
+        if (!useSplitShade) {
+            return 0
+        }
+        // On split-shade, the translationY of the keyguard should stay in sync with the
+        // translation of media.
+        if (mediaHierarchyManager.isCurrentlyInGuidedTransformation()) {
+            return mediaHierarchyManager.getGuidedTransformationTranslationY()
+        }
+        // When media is not showing, apply the default distance
+        translationYProgress = MathUtils.saturate(dragDownAmount / keyguardTransitionDistance)
+        val translationY = translationYProgress * keyguardTransitionOffset
+        return translationY.toInt()
+    }
+
+    override fun dump(indentingPrintWriter: IndentingPrintWriter) {
+        indentingPrintWriter.let {
+            it.println("LockscreenShadeKeyguardTransitionController:")
+            it.increaseIndent()
+            it.println("Resources:")
+            it.increaseIndent()
+            it.println("alphaTransitionDistance: $alphaTransitionDistance")
+            it.println("keyguardTransitionDistance: $keyguardTransitionDistance")
+            it.println("keyguardTransitionOffset: $keyguardTransitionOffset")
+            it.decreaseIndent()
+            it.println("State:")
+            it.increaseIndent()
+            it.println("dragDownAmount: $dragDownAmount")
+            it.println("alpha: $alpha")
+            it.println("alphaProgress: $alphaProgress")
+            it.println("statusBarAlpha: $statusBarAlpha")
+            it.println("translationProgress: $translationYProgress")
+            it.println("translationY: $translationY")
+        }
+    }
+
+    @AssistedFactory
+    fun interface Factory {
+        fun create(
+            notificationPanelController: NotificationPanelViewController
+        ): LockscreenShadeKeyguardTransitionController
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeScrimTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeScrimTransitionController.kt
new file mode 100644
index 0000000..00d3701
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeScrimTransitionController.kt
@@ -0,0 +1,86 @@
+package com.android.systemui.statusbar
+
+import android.content.Context
+import android.util.IndentingPrintWriter
+import android.util.MathUtils
+import com.android.systemui.R
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.statusbar.phone.ScrimController
+import com.android.systemui.statusbar.policy.ConfigurationController
+import javax.inject.Inject
+
+/** Controls the lockscreen to shade transition for scrims. */
+class LockscreenShadeScrimTransitionController
+@Inject
+constructor(
+    private val scrimController: ScrimController,
+    context: Context,
+    configurationController: ConfigurationController,
+    dumpManager: DumpManager
+) : AbstractLockscreenShadeTransitionController(context, configurationController, dumpManager) {
+
+    /**
+     * Distance that the full shade transition takes in order for scrim to fully transition to the
+     * shade (in alpha)
+     */
+    private var scrimTransitionDistance = 0
+
+    /** Distance it takes in order for the notifications scrim fade in to start. */
+    private var notificationsScrimTransitionDelay = 0
+
+    /** Distance it takes for the notifications scrim to fully fade if after it started. */
+    private var notificationsScrimTransitionDistance = 0
+
+    /** The latest progress [0,1] the scrims transition. */
+    var scrimProgress = 0f
+
+    /** The latest progress [0,1] specifically of the notifications scrim transition. */
+    var notificationsScrimProgress = 0f
+
+    /**
+     * The last drag amount specifically for the notifications scrim. It is different to the normal
+     * [dragDownAmount] as the notifications scrim transition starts relative to the other scrims'
+     * progress.
+     */
+    var notificationsScrimDragAmount = 0f
+
+    override fun updateResources() {
+        scrimTransitionDistance =
+            context.resources.getDimensionPixelSize(
+                R.dimen.lockscreen_shade_scrim_transition_distance)
+        notificationsScrimTransitionDelay =
+            context.resources.getDimensionPixelSize(
+                R.dimen.lockscreen_shade_notifications_scrim_transition_delay)
+        notificationsScrimTransitionDistance =
+            context.resources.getDimensionPixelSize(
+                R.dimen.lockscreen_shade_notifications_scrim_transition_distance)
+    }
+
+    override fun onDragDownAmountChanged(dragDownAmount: Float) {
+        scrimProgress = MathUtils.saturate(dragDownAmount / scrimTransitionDistance)
+        notificationsScrimDragAmount = dragDownAmount - notificationsScrimTransitionDelay
+        notificationsScrimProgress =
+            MathUtils.saturate(notificationsScrimDragAmount / notificationsScrimTransitionDistance)
+        scrimController.setTransitionToFullShadeProgress(scrimProgress, notificationsScrimProgress)
+    }
+
+    override fun dump(indentingPrintWriter: IndentingPrintWriter) {
+        indentingPrintWriter.let {
+            it.println("LockscreenShadeScrimTransitionController:")
+            it.increaseIndent()
+            it.println("Resources:")
+            it.increaseIndent()
+            it.println("scrimTransitionDistance: $scrimTransitionDistance")
+            it.println("notificationsScrimTransitionDelay: $notificationsScrimTransitionDelay")
+            it.println(
+                "notificationsScrimTransitionDistance: $notificationsScrimTransitionDistance")
+            it.decreaseIndent()
+            it.println("State")
+            it.increaseIndent()
+            it.println("dragDownAmount: $dragDownAmount")
+            it.println("scrimProgress: $scrimProgress")
+            it.println("notificationsScrimProgress: $notificationsScrimProgress")
+            it.println("notificationsScrimDragAmount: $notificationsScrimDragAmount")
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
index 63ab3de..b7d82c3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
@@ -38,7 +38,6 @@
 import com.android.systemui.statusbar.phone.KeyguardBypassController
 import com.android.systemui.statusbar.phone.LSShadeTransitionLogger
 import com.android.systemui.statusbar.phone.NotificationPanelViewController
-import com.android.systemui.statusbar.phone.ScrimController
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.util.LargeScreenUtils
 import java.io.FileDescriptor
@@ -61,7 +60,9 @@
     private val falsingCollector: FalsingCollector,
     private val ambientState: AmbientState,
     private val mediaHierarchyManager: MediaHierarchyManager,
-    private val scrimController: ScrimController,
+    private val scrimTransitionController: LockscreenShadeScrimTransitionController,
+    private val keyguardTransitionControllerFactory:
+        LockscreenShadeKeyguardTransitionController.Factory,
     private val depthController: NotificationShadeDepthController,
     private val context: Context,
     private val splitShadeOverScrollerFactory: SplitShadeLockScreenOverScroller.Factory,
@@ -112,22 +113,6 @@
     private var fullTransitionDistanceByTap = 0
 
     /**
-     * Distance that the full shade transition takes in order for scrim to fully transition to the
-     * shade (in alpha)
-     */
-    private var scrimTransitionDistance = 0
-
-    /**
-     * Distance that it takes in order for the notifications scrim fade in to start.
-     */
-    private var notificationsScrimTransitionDelay = 0
-
-    /**
-     * Distance that it takes for the notifications scrim to fully fade if after it started.
-     */
-    private var notificationsScrimTransitionDistance = 0
-
-    /**
      * Distance that the full shade transition takes in order for the notification shelf to fully
      * expand.
      */
@@ -140,12 +125,6 @@
     private var qsTransitionDistance = 0
 
     /**
-     * Distance that the full shade transition takes in order for the keyguard content on
-     * NotificationPanelViewController to fully fade (e.g. Clock & Smartspace).
-     */
-    private var npvcKeyguardContentAlphaTransitionDistance = 0
-
-    /**
      * Distance that the full shade transition takes in order for depth of the wallpaper to fully
      * change.
      */
@@ -164,17 +143,6 @@
     private var statusBarTransitionDistance = 0
 
     /**
-     * Distance that the full shade transition takes in order for the keyguard elements to fully
-     * translate into their final position
-     */
-    private var keyguardTransitionDistance = 0
-
-    /**
-     * The amount of vertical offset for the keyguard during the full shade transition.
-     */
-    private var keyguardTransitionOffset = 0
-
-    /**
      * Flag to make sure that the dragDownAmount is applied to the listeners even when in the
      * locked down shade.
      */
@@ -215,6 +183,10 @@
         singleShadeOverScrollerFactory.create(nsslController)
     }
 
+    private val keyguardTransitionController by lazy {
+        keyguardTransitionControllerFactory.create(notificationPanelController)
+    }
+
     /**
      * [LockScreenShadeOverScroller] property that delegates to either
      * [SingleShadeLockScreenOverScroller] or [SplitShadeLockScreenOverScroller].
@@ -267,18 +239,10 @@
                 R.dimen.lockscreen_shade_full_transition_distance)
         fullTransitionDistanceByTap = context.resources.getDimensionPixelSize(
             R.dimen.lockscreen_shade_transition_by_tap_distance)
-        scrimTransitionDistance = context.resources.getDimensionPixelSize(
-                R.dimen.lockscreen_shade_scrim_transition_distance)
-        notificationsScrimTransitionDelay = context.resources.getDimensionPixelSize(
-                R.dimen.lockscreen_shade_notifications_scrim_transition_delay)
-        notificationsScrimTransitionDistance = context.resources.getDimensionPixelSize(
-                R.dimen.lockscreen_shade_notifications_scrim_transition_distance)
         notificationShelfTransitionDistance = context.resources.getDimensionPixelSize(
                 R.dimen.lockscreen_shade_notif_shelf_transition_distance)
         qsTransitionDistance = context.resources.getDimensionPixelSize(
                 R.dimen.lockscreen_shade_qs_transition_distance)
-        npvcKeyguardContentAlphaTransitionDistance = context.resources.getDimensionPixelSize(
-                R.dimen.lockscreen_shade_npvc_keyguard_content_alpha_transition_distance)
         depthControllerTransitionDistance = context.resources.getDimensionPixelSize(
                 R.dimen.lockscreen_shade_depth_controller_transition_distance)
         udfpsTransitionDistance = context.resources.getDimensionPixelSize(
@@ -286,10 +250,6 @@
         statusBarTransitionDistance = context.resources.getDimensionPixelSize(
                 R.dimen.lockscreen_shade_status_bar_transition_distance)
         useSplitShade = LargeScreenUtils.shouldUseSplitNotificationShade(context.resources)
-        keyguardTransitionDistance = context.resources.getDimensionPixelSize(
-            R.dimen.lockscreen_shade_keyguard_transition_distance)
-        keyguardTransitionOffset = context.resources.getDimensionPixelSize(
-            R.dimen.lockscreen_shade_keyguard_transition_vertical_offset)
     }
 
     fun setStackScroller(nsslController: NotificationStackScrollLayoutController) {
@@ -457,9 +417,9 @@
                             false /* animate */, 0 /* delay */)
 
                     mediaHierarchyManager.setTransitionToFullShadeAmount(field)
-                    transitionToShadeAmountScrim(field)
+                    scrimTransitionController.dragDownAmount = value
                     transitionToShadeAmountCommon(field)
-                    transitionToShadeAmountKeyguard(field)
+                    keyguardTransitionController.dragDownAmount = value
                     shadeOverScroller.expansionDragDownAmount = dragDownAmount
                 }
             }
@@ -471,14 +431,6 @@
     var qSDragProgress = 0f
         private set
 
-    private fun transitionToShadeAmountScrim(dragDownAmount: Float) {
-        val scrimProgress = MathUtils.saturate(dragDownAmount / scrimTransitionDistance)
-        val notificationsScrimDragAmount = dragDownAmount - notificationsScrimTransitionDelay
-        val notificationsScrimProgress = MathUtils.saturate(
-                notificationsScrimDragAmount / notificationsScrimTransitionDistance)
-        scrimController.setTransitionToFullShadeProgress(scrimProgress, notificationsScrimProgress)
-    }
-
     private fun transitionToShadeAmountCommon(dragDownAmount: Float) {
         if (depthControllerTransitionDistance == 0) { // split shade
             depthController.transitionToFullShadeProgress = 0f
@@ -495,34 +447,6 @@
         centralSurfaces.setTransitionToFullShadeProgress(statusBarProgress)
     }
 
-    private fun transitionToShadeAmountKeyguard(dragDownAmount: Float) {
-        // Fade out all content only visible on the lockscreen
-        val keyguardAlphaProgress =
-            MathUtils.saturate(dragDownAmount / npvcKeyguardContentAlphaTransitionDistance)
-        val keyguardAlpha = 1f - keyguardAlphaProgress
-        val keyguardTranslationY = calculateKeyguardTranslationY(dragDownAmount)
-        notificationPanelController
-            .setKeyguardTransitionProgress(keyguardAlpha, keyguardTranslationY)
-
-        val statusBarAlpha = if (useSplitShade) keyguardAlpha else -1f
-        notificationPanelController.setKeyguardStatusBarAlpha(statusBarAlpha)
-    }
-
-    private fun calculateKeyguardTranslationY(dragDownAmount: Float): Int {
-        if (!useSplitShade) {
-            return 0
-        }
-        // On split-shade, the translationY of the keyguard should stay in sync with the
-        // translation of media.
-        if (mediaHierarchyManager.isCurrentlyInGuidedTransformation()) {
-            return mediaHierarchyManager.getGuidedTransformationTranslationY()
-        }
-        // When media is not showing, apply the default distance
-        val translationProgress = MathUtils.saturate(dragDownAmount / keyguardTransitionDistance)
-        val translationY = translationProgress * keyguardTransitionOffset
-        return translationY.toInt()
-    }
-
     private fun setDragDownAmountAnimated(
         target: Float,
         delay: Long = 0,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
index e2d6ae0..562c970 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
@@ -93,24 +93,34 @@
                 .addOverride(R.bool.config_use_split_notification_shade, false)
         context.getOrCreateTestableResources()
             .addOverride(R.dimen.lockscreen_shade_depth_controller_transition_distance, 100)
-        transitionController = LockscreenShadeTransitionController(
-            statusBarStateController = statusbarStateController,
-            logger = logger,
-            keyguardBypassController = keyguardBypassController,
-            lockScreenUserManager = lockScreenUserManager,
-            falsingCollector = falsingCollector,
-            ambientState = ambientState,
-            mediaHierarchyManager = mediaHierarchyManager,
-            scrimController = scrimController,
-            depthController = depthController,
-            wakefulnessLifecycle = wakefulnessLifecycle,
-            context = context,
-            configurationController = configurationController,
-            falsingManager = falsingManager,
-            dumpManager = dumpManager,
-            splitShadeOverScrollerFactory = { _, _ -> splitShadeOverScroller },
-            singleShadeOverScrollerFactory = { singleShadeOverScroller }
-        )
+        transitionController =
+            LockscreenShadeTransitionController(
+                statusBarStateController = statusbarStateController,
+                logger = logger,
+                keyguardBypassController = keyguardBypassController,
+                lockScreenUserManager = lockScreenUserManager,
+                falsingCollector = falsingCollector,
+                ambientState = ambientState,
+                mediaHierarchyManager = mediaHierarchyManager,
+                depthController = depthController,
+                wakefulnessLifecycle = wakefulnessLifecycle,
+                context = context,
+                configurationController = configurationController,
+                falsingManager = falsingManager,
+                dumpManager = dumpManager,
+                splitShadeOverScrollerFactory = { _, _ -> splitShadeOverScroller },
+                singleShadeOverScrollerFactory = { singleShadeOverScroller },
+                scrimTransitionController =
+                LockscreenShadeScrimTransitionController(
+                    scrimController, context, configurationController, dumpManager),
+                keyguardTransitionControllerFactory = { notificationPanelController ->
+                    LockscreenShadeKeyguardTransitionController(
+                        mediaHierarchyManager,
+                        notificationPanelController,
+                        context,
+                        configurationController,
+                        dumpManager)
+                })
         whenever(nsslController.view).thenReturn(stackscroller)
         whenever(nsslController.expandHelperCallback).thenReturn(expandHelperCallback)
         transitionController.notificationPanelController = notificationPanelController
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/FakeConfigurationController.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/FakeConfigurationController.kt
index 3a5d9ee..146b56e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/FakeConfigurationController.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/FakeConfigurationController.kt
@@ -5,22 +5,22 @@
 /** Fake implementation of [ConfigurationController] for tests. */
 class FakeConfigurationController : ConfigurationController {
 
-    private var listener: ConfigurationController.ConfigurationListener? = null
+    private var listeners = mutableListOf<ConfigurationController.ConfigurationListener>()
 
     override fun addCallback(listener: ConfigurationController.ConfigurationListener) {
-        this.listener = listener
+        listeners += listener
     }
 
     override fun removeCallback(listener: ConfigurationController.ConfigurationListener) {
-        this.listener = null
+        listeners -= listener
     }
 
     override fun onConfigurationChanged(newConfiguration: Configuration?) {
-        listener?.onConfigChanged(newConfiguration)
+        listeners.forEach { it.onConfigChanged(newConfiguration) }
     }
 
     override fun notifyThemeChanged() {
-        listener?.onThemeChanged()
+        listeners.forEach { it.onThemeChanged() }
     }
 
     fun notifyConfigurationChanged() {