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

Commit 4ac3a5d5 authored by Tyler Freeman's avatar Tyler Freeman Committed by Android (Google) Code Review
Browse files

Merge changes Ieeb523ce,If38609f5,I3d55c2c1

* changes:
  chore(magnification settings): add logging for zoom slider in settings panel
  feat(magnification settings): add logThrottled() so we only log one scale event when they start moving the slider
  chore(magnification settings): add logWithPosition() to log things like which magnification size was tapped.
parents 477cf00d 365612d9
Loading
Loading
Loading
Loading
+59 −5
Original line number Diff line number Diff line
@@ -16,8 +16,11 @@

package com.android.systemui.accessibility

import com.android.internal.annotations.GuardedBy
import com.android.internal.logging.UiEvent
import com.android.internal.logging.UiEventLogger
import com.android.internal.logging.UiEventLogger.UiEventEnum
import com.android.systemui.util.time.SystemClock
import javax.inject.Inject

/**
@@ -25,16 +28,60 @@ import javax.inject.Inject
 *
 * See go/uievent
 */
class AccessibilityLogger @Inject constructor(private val uiEventLogger: UiEventLogger) {
class AccessibilityLogger
@Inject
constructor(private val uiEventLogger: UiEventLogger, private val clock: SystemClock) {

    @GuardedBy("clock") private var lastTimeThrottledMs: Long = 0
    @GuardedBy("clock") private var lastEventThrottled: UiEventEnum? = null

    /**
     * Logs the event, but any additional calls within the given delay window are ignored. The
     * window resets every time a new event is received. i.e. it will only log one time until you
     * wait at least [delayBeforeLoggingMs] before sending the next event.
     *
     * <p>Additionally, if a different type of event is passed in, the delay window for the previous
     * one is forgotten. e.g. if you send two types of events interlaced all within the delay
     * window, e.g. A->B->A within 1000ms, all three will be logged.
     */
    @JvmOverloads fun logThrottled(event: UiEventEnum, delayBeforeLoggingMs: Int = 2000) {
        synchronized(clock) {
            val currentTimeMs = clock.elapsedRealtime()
            val shouldThrottle =
                event == lastEventThrottled &&
                    currentTimeMs - lastTimeThrottledMs < delayBeforeLoggingMs
            lastEventThrottled = event
            lastTimeThrottledMs = currentTimeMs
            if (shouldThrottle) {
                return
            }
        }
        log(event)
    }

    /** Logs the given event */
    fun log(event: UiEventLogger.UiEventEnum) {
    fun log(event: UiEventEnum) {
        uiEventLogger.log(event)
    }

    /**
     * Logs the given event with an integer rank/position value.
     *
     * @param event the event to log
     * @param position the rank or position value that the user interacted with in the UI
     */
    fun logWithPosition(event: UiEventEnum, position: Int) {
        uiEventLogger.logWithPosition(event, /* uid= */ 0, /* packageName= */ null, position)
    }

    /** Events regarding interaction with the magnifier settings panel */
    enum class MagnificationSettingsEvent constructor(private val id: Int) :
        UiEventLogger.UiEventEnum {
        @UiEvent(doc = "Magnification settings panel opened.")
        UiEventEnum {
        @UiEvent(
            doc =
                "Magnification settings panel opened. The selection rank is from which " +
                    "magnifier mode it was opened (fullscreen or window)"
        )
        MAGNIFICATION_SETTINGS_PANEL_OPENED(1381),

        @UiEvent(doc = "Magnification settings panel closed")
@@ -46,7 +93,14 @@ class AccessibilityLogger @Inject constructor(private val uiEventLogger: UiEvent
        @UiEvent(doc = "Magnification settings panel edit size save button clicked")
        MAGNIFICATION_SETTINGS_SIZE_EDITING_DEACTIVATED(1384),

        @UiEvent(doc = "Magnification settings panel window size selected")
        @UiEvent(doc = "Magnification settings panel zoom slider changed")
        MAGNIFICATION_SETTINGS_ZOOM_SLIDER_CHANGED(1385),

        @UiEvent(
            doc =
                "Magnification settings panel window size selected. The selection rank is " +
                    "which size was selected."
        )
        MAGNIFICATION_SETTINGS_WINDOW_SIZE_SELECTED(1386);

        override fun getId(): Int = this.id
+24 −6
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.systemui.accessibility;

import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW;
import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY;

@@ -346,7 +347,10 @@ public class WindowMagnification implements CoreStartable, CommandQueue.Callback
        @Override
        public void onSetMagnifierSize(int displayId, int index) {
            mHandler.post(() -> onSetMagnifierSizeInternal(displayId, index));
            mA11yLogger.log(MagnificationSettingsEvent.MAGNIFICATION_SETTINGS_WINDOW_SIZE_SELECTED);
            mA11yLogger.logWithPosition(
                    MagnificationSettingsEvent.MAGNIFICATION_SETTINGS_WINDOW_SIZE_SELECTED,
                    index
            );
        }

        @Override
@@ -367,6 +371,9 @@ public class WindowMagnification implements CoreStartable, CommandQueue.Callback
            if (mWindowMagnificationConnectionImpl != null) {
                mWindowMagnificationConnectionImpl.onPerformScaleAction(displayId, scale);
            }
            mA11yLogger.logThrottled(
                    MagnificationSettingsEvent.MAGNIFICATION_SETTINGS_ZOOM_SLIDER_CHANGED
            );
        }

        @Override
@@ -377,9 +384,6 @@ public class WindowMagnification implements CoreStartable, CommandQueue.Callback
        @Override
        public void onSettingsPanelVisibilityChanged(int displayId, boolean shown) {
            mHandler.post(() -> onSettingsPanelVisibilityChangedInternal(displayId, shown));
            mA11yLogger.log(shown
                    ? MagnificationSettingsEvent.MAGNIFICATION_SETTINGS_PANEL_OPENED
                    : MagnificationSettingsEvent.MAGNIFICATION_SETTINGS_PANEL_CLOSED);
        }
    };

@@ -433,9 +437,23 @@ public class WindowMagnification implements CoreStartable, CommandQueue.Callback
    private void onSettingsPanelVisibilityChangedInternal(int displayId, boolean shown) {
        final WindowMagnificationController windowMagnificationController =
                mMagnificationControllerSupplier.get(displayId);
        if (windowMagnificationController != null && windowMagnificationController.isActivated()) {
        if (windowMagnificationController != null) {
            boolean isWindowMagnifierActivated = windowMagnificationController.isActivated();
            if (isWindowMagnifierActivated) {
                windowMagnificationController.updateDragHandleResourcesIfNeeded(shown);
            }

            if (shown) {
                mA11yLogger.logWithPosition(
                        MagnificationSettingsEvent.MAGNIFICATION_SETTINGS_PANEL_OPENED,
                        isWindowMagnifierActivated
                                ? ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW
                                : ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN
                );
            } else {
                mA11yLogger.log(MagnificationSettingsEvent.MAGNIFICATION_SETTINGS_PANEL_CLOSED);
            }
        }
    }

    @Override
+80 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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
 *
 *      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.
 */

package com.android.systemui.accessibility

import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
import com.android.internal.logging.UiEventLogger
import com.android.systemui.SysuiTestCase
import com.android.systemui.accessibility.AccessibilityLogger.MagnificationSettingsEvent.MAGNIFICATION_SETTINGS_PANEL_CLOSED
import com.android.systemui.accessibility.AccessibilityLogger.MagnificationSettingsEvent.MAGNIFICATION_SETTINGS_PANEL_OPENED
import com.android.systemui.util.time.FakeSystemClock
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.eq
import org.mockito.Mock
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
import org.mockito.junit.MockitoJUnit

@SmallTest
@RunWith(AndroidTestingRunner::class)
class AccessibilityLoggerTest : SysuiTestCase() {
    @JvmField @Rule val mockito = MockitoJUnit.rule()

    private val fakeClock = FakeSystemClock()
    @Mock private lateinit var fakeLogger: UiEventLogger

    private lateinit var a11yLogger: AccessibilityLogger

    @Before
    fun setup() {
        a11yLogger = AccessibilityLogger(fakeLogger, fakeClock)
    }

    @Test
    fun logThrottled_onceWithinWindow() {
        a11yLogger.logThrottled(MAGNIFICATION_SETTINGS_PANEL_OPENED, 1000)
        a11yLogger.logThrottled(MAGNIFICATION_SETTINGS_PANEL_OPENED, 1000)
        a11yLogger.logThrottled(MAGNIFICATION_SETTINGS_PANEL_OPENED, 1000)
        fakeClock.advanceTime(100L)
        a11yLogger.logThrottled(MAGNIFICATION_SETTINGS_PANEL_OPENED, 1000)
        fakeClock.advanceTime(900L)
        a11yLogger.logThrottled(MAGNIFICATION_SETTINGS_PANEL_OPENED, 1000)
        fakeClock.advanceTime(1100L)
        a11yLogger.logThrottled(MAGNIFICATION_SETTINGS_PANEL_OPENED, 1000)

        verify(fakeLogger, times(2)).log(eq(MAGNIFICATION_SETTINGS_PANEL_OPENED))
    }

    @Test
    fun logThrottled_interlacedLogsAllWithinWindow() {
        a11yLogger.logThrottled(MAGNIFICATION_SETTINGS_PANEL_OPENED, 1000)
        a11yLogger.logThrottled(MAGNIFICATION_SETTINGS_PANEL_CLOSED, 1000)
        fakeClock.advanceTime(100L)
        a11yLogger.logThrottled(MAGNIFICATION_SETTINGS_PANEL_CLOSED, 1000)
        fakeClock.advanceTime(200L)
        a11yLogger.logThrottled(MAGNIFICATION_SETTINGS_PANEL_OPENED, 1000)
        fakeClock.advanceTime(1100L)
        a11yLogger.logThrottled(MAGNIFICATION_SETTINGS_PANEL_OPENED, 1000)

        verify(fakeLogger, times(3)).log(eq(MAGNIFICATION_SETTINGS_PANEL_OPENED))
        verify(fakeLogger).log(eq(MAGNIFICATION_SETTINGS_PANEL_CLOSED))
    }
}
+12 −4
Original line number Diff line number Diff line
@@ -117,6 +117,8 @@ public class WindowMagnificationTest extends SysuiTestCase {
            return null;
        }).when(mMagnificationSettingsController).closeMagnificationSettings();

        when(mWindowMagnificationController.isActivated()).thenReturn(true);

        mCommandQueue = new CommandQueue(getContext(), mDisplayTracker);
        mWindowMagnification = new WindowMagnification(getContext(),
                getContext().getMainThreadHandler(), mCommandQueue, mModeSwitchesController,
@@ -199,8 +201,10 @@ public class WindowMagnificationTest extends SysuiTestCase {
        waitForIdleSync();

        verify(mMagnificationSettingsController).toggleSettingsPanelVisibility();
        verify(mA11yLogger).log(
                eq(MagnificationSettingsEvent.MAGNIFICATION_SETTINGS_PANEL_OPENED));
        verify(mA11yLogger).logWithPosition(
                eq(MagnificationSettingsEvent.MAGNIFICATION_SETTINGS_PANEL_OPENED),
                eq(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW)
        );
    }

    @Test
@@ -211,8 +215,10 @@ public class WindowMagnificationTest extends SysuiTestCase {
        waitForIdleSync();

        verify(mWindowMagnificationController).changeMagnificationSize(eq(index));
        verify(mA11yLogger).log(
                eq(MagnificationSettingsEvent.MAGNIFICATION_SETTINGS_WINDOW_SIZE_SELECTED));
        verify(mA11yLogger).logWithPosition(
                eq(MagnificationSettingsEvent.MAGNIFICATION_SETTINGS_WINDOW_SIZE_SELECTED),
                eq(index)
        );
    }

    @Test
@@ -253,6 +259,8 @@ public class WindowMagnificationTest extends SysuiTestCase {
                TEST_DISPLAY, scale);

        verify(mConnectionCallback).onPerformScaleAction(eq(TEST_DISPLAY), eq(scale));
        verify(mA11yLogger).logThrottled(
                eq(MagnificationSettingsEvent.MAGNIFICATION_SETTINGS_ZOOM_SLIDER_CHANGED));
    }

    @Test