Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 970fb0ff authored by Yein Jo's avatar Yein Jo Committed by Android (Google) Code Review
Browse files

Merge "Replace RotationUtils#Rotation with Surface#Rotation for wired charging...

Merge "Replace RotationUtils#Rotation with Surface#Rotation for wired charging animation." into tm-qpr-dev
parents 3dcd9ed2 b9f622bc
Loading
Loading
Loading
Loading
+12 −15
Original line number Diff line number Diff line
@@ -20,7 +20,7 @@ import android.content.Context
import android.content.res.Configuration
import android.graphics.PixelFormat
import android.os.SystemProperties
import android.util.DisplayMetrics
import android.view.Surface
import android.view.View
import android.view.WindowManager
import com.android.internal.annotations.VisibleForTesting
@@ -36,7 +36,6 @@ import com.android.systemui.statusbar.commandline.Command
import com.android.systemui.statusbar.commandline.CommandRegistry
import com.android.systemui.statusbar.policy.BatteryController
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.util.leak.RotationUtils
import com.android.systemui.util.time.SystemClock
import java.io.PrintWriter
import javax.inject.Inject
@@ -172,30 +171,28 @@ class WiredChargingRippleController @Inject constructor(
    }

    private fun layoutRipple() {
        val displayMetrics = DisplayMetrics()
        context.display.getRealMetrics(displayMetrics)
        val width = displayMetrics.widthPixels
        val height = displayMetrics.heightPixels
        val bounds = windowManager.currentWindowMetrics.bounds
        val width = bounds.width()
        val height = bounds.height()
        val maxDiameter = Integer.max(width, height) * 2f
        rippleView.setMaxSize(maxDiameter, maxDiameter)
        when (RotationUtils.getExactRotation(context)) {
            RotationUtils.ROTATION_LANDSCAPE -> {
        when (context.display.rotation) {
            Surface.ROTATION_0 -> {
                rippleView.setCenter(
                        width * normalizedPortPosX, height * normalizedPortPosY)
            }
            Surface.ROTATION_90 -> {
                rippleView.setCenter(
                        width * normalizedPortPosY, height * (1 - normalizedPortPosX))
            }
            RotationUtils.ROTATION_UPSIDE_DOWN -> {
            Surface.ROTATION_180 -> {
                rippleView.setCenter(
                        width * (1 - normalizedPortPosX), height * (1 - normalizedPortPosY))
            }
            RotationUtils.ROTATION_SEASCAPE -> {
            Surface.ROTATION_270 -> {
                rippleView.setCenter(
                        width * (1 - normalizedPortPosY), height * normalizedPortPosX)
            }
            else -> {
                // ROTATION_NONE
                rippleView.setCenter(
                        width * normalizedPortPosX, height * normalizedPortPosY)
            }
        }
    }

+29 −7
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
 * except in compliance with the License. You may obtain a copy of the License at
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the
 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.util.leak;
@@ -26,7 +28,27 @@ import android.view.Surface;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

public class RotationUtils {
/**
 * Utility class that provides device orientation.
 *
 * <p>Consider using {@link Surface.Rotation} or add a function that respects device aspect ratio
 * and {@code android.internal.R.bool.config_reverseDefaultRotation}.
 *
 * <p>If you only care about the rotation, use {@link Surface.Rotation}, as it always gives the
 * counter clock-wise rotation. (e.g. If you have a device that has a charging port at the bottom,
 * rotating three times in counter clock direction will give you {@link Surface#ROTATION_270} while
 * having the charging port on the left side of the device.)
 *
 * <p>If you need whether the device is in portrait or landscape (or their opposites), please add a
 * function here that respects the device aspect ratio and
 * {@code android.internal.R.bool.config_reverseDefaultRotation} together.
 *
 * <p>Note that {@code android.internal.R.bool.config_reverseDefaultRotation} does not change the
 * winding order. In other words, the rotation order (counter clock-wise) will remain the same. It
 * only flips the device orientation, such that portrait becomes upside down, landscape becomes
 * seascape.
 */
public final class RotationUtils {

    public static final int ROTATION_NONE = 0;
    public static final int ROTATION_LANDSCAPE = 1;
+70 −2
Original line number Diff line number Diff line
@@ -16,18 +16,23 @@

package com.android.systemui.charging

import android.graphics.Rect
import android.testing.AndroidTestingRunner
import android.view.Surface
import android.view.View
import android.view.WindowManager
import android.view.WindowMetrics
import androidx.test.filters.SmallTest
import com.android.internal.logging.UiEventLogger
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
import com.android.systemui.surfaceeffects.ripple.RippleView
import com.android.systemui.statusbar.commandline.CommandRegistry
import com.android.systemui.statusbar.policy.BatteryController
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.surfaceeffects.ripple.RippleView
import com.android.systemui.util.mockito.whenever
import com.android.systemui.util.time.FakeSystemClock
import org.junit.Before
import org.junit.Test
@@ -35,12 +40,12 @@ import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
import org.mockito.ArgumentMatchers
import org.mockito.Mock
import org.mockito.Mockito.`when`
import org.mockito.Mockito.any
import org.mockito.Mockito.eq
import org.mockito.Mockito.never
import org.mockito.Mockito.reset
import org.mockito.Mockito.verify
import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations

@SmallTest
@@ -54,6 +59,7 @@ class WiredChargingRippleControllerTest : SysuiTestCase() {
    @Mock private lateinit var rippleView: RippleView
    @Mock private lateinit var windowManager: WindowManager
    @Mock private lateinit var uiEventLogger: UiEventLogger
    @Mock private lateinit var windowMetrics: WindowMetrics
    private val systemClock = FakeSystemClock()

    @Before
@@ -66,6 +72,9 @@ class WiredChargingRippleControllerTest : SysuiTestCase() {
        rippleView.setupShader()
        controller.rippleView = rippleView // Replace the real ripple view with a mock instance
        controller.registerCallbacks()

        `when`(windowMetrics.bounds).thenReturn(Rect(0, 0, 100, 100))
        `when`(windowManager.currentWindowMetrics).thenReturn(windowMetrics)
    }

    @Test
@@ -164,4 +173,63 @@ class WiredChargingRippleControllerTest : SysuiTestCase() {
        verify(rippleView, never()).addOnAttachStateChangeListener(attachListenerCaptor.capture())
        verify(windowManager, never()).addView(eq(rippleView), any<WindowManager.LayoutParams>())
    }

    @Test
    fun testRipple_layoutsCorrectly() {
        // Sets the correct ripple size.
        val width = 100
        val height = 200
        whenever(windowMetrics.bounds).thenReturn(Rect(0, 0, width, height))

        // Trigger ripple.
        val captor = ArgumentCaptor
                .forClass(BatteryController.BatteryStateChangeCallback::class.java)
        verify(batteryController).addCallback(captor.capture())

        captor.value.onBatteryLevelChanged(
                /* unusedBatteryLevel= */ 0,
                /* plugged in= */ true,
                /* charging= */ false)

        val attachListenerCaptor =
                ArgumentCaptor.forClass(View.OnAttachStateChangeListener::class.java)
        verify(rippleView).addOnAttachStateChangeListener(attachListenerCaptor.capture())
        verify(windowManager).addView(eq(rippleView), any<WindowManager.LayoutParams>())

        val runnableCaptor =
                ArgumentCaptor.forClass(Runnable::class.java)
        attachListenerCaptor.value.onViewAttachedToWindow(rippleView)
        verify(rippleView).startRipple(runnableCaptor.capture())

        // Verify size and center position.
        val maxSize = 400f // Double the max value between width and height.
        verify(rippleView).setMaxSize(maxWidth = maxSize, maxHeight = maxSize)

        val normalizedPortPosX =
                context.resources.getFloat(R.dimen.physical_charger_port_location_normalized_x)
        val normalizedPortPosY =
                context.resources.getFloat(R.dimen.physical_charger_port_location_normalized_y)
        val expectedCenterX: Float
        val expectedCenterY: Float
        when (context.display.rotation) {
            Surface.ROTATION_90 -> {
                expectedCenterX = width * normalizedPortPosY
                expectedCenterY = height * (1 - normalizedPortPosX)
            }
            Surface.ROTATION_180 -> {
                expectedCenterX = width * (1 - normalizedPortPosX)
                expectedCenterY = height * (1 - normalizedPortPosY)
            }
            Surface.ROTATION_270 -> {
                expectedCenterX = width * (1 - normalizedPortPosY)
                expectedCenterY = height * normalizedPortPosX
            }
            else -> { // Surface.ROTATION_0
                expectedCenterX = width * normalizedPortPosX
                expectedCenterY = height * normalizedPortPosY
            }
        }

        verify(rippleView).setCenter(expectedCenterX, expectedCenterY)
    }
}