Loading core/java/com/android/internal/accessibility/util/AccessibilityStatsLogUtils.java +11 −0 Original line number Diff line number Diff line Loading @@ -167,6 +167,17 @@ public final class AccessibilityStatsLogUtils { convertToLoggingMagnificationMode(mode)); } /** * Logs the duration for the window magnifier's following typing focus session. * * @param duration The duration of a triple-tap-and-hold activation session. */ public static void logMagnificationFollowTypingFocusSession(long duration) { FrameworkStatsLog.write( FrameworkStatsLog.MAGNIFICATION_FOLLOW_TYPING_FOCUS_ACTIVATED_SESSION_REPORTED, duration); } /** * Logs the duration for the magnification session which is activated by the triple tap and * hold gesture. Loading services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java +82 −1 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ import android.view.accessibility.IWindowMagnificationConnection; import android.view.accessibility.IWindowMagnificationConnectionCallback; import android.view.accessibility.MagnificationAnimationCallback; import com.android.internal.accessibility.util.AccessibilityStatsLogUtils; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.server.LocalServices; Loading @@ -54,6 +55,7 @@ import com.android.server.wm.WindowManagerInternal; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.concurrent.atomic.AtomicLongFieldUpdater; /** * A class to manipulate window magnification through {@link WindowMagnificationConnectionWrapper} Loading Loading @@ -136,6 +138,7 @@ public class WindowMagnificationManager implements private SparseArray<WindowMagnifier> mWindowMagnifiers = new SparseArray<>(); // Whether the following typing focus feature for magnification is enabled. private boolean mMagnificationFollowTypingEnabled = true; @GuardedBy("mLock") private final SparseBooleanArray mIsImeVisibleArray = new SparseBooleanArray(); private boolean mReceiverRegistered = false; Loading Loading @@ -465,18 +468,43 @@ public class WindowMagnificationManager implements } } private void pauseTrackingTypingFocusRecord(int displayId) { WindowMagnifier magnifier; synchronized (mLock) { magnifier = mWindowMagnifiers.get(displayId); if (magnifier == null) { return; } } magnifier.pauseTrackingTypingFocusRecord(); } /** * Called when the IME window visibility changed. * * @param shown {@code true} means the IME window shows on the screen. Otherwise, it's hidden. */ void onImeWindowVisibilityChanged(int displayId, boolean shown) { synchronized (mLock) { mIsImeVisibleArray.put(displayId, shown); } if (shown) { enableAllTrackingTypingFocus(); } else { pauseTrackingTypingFocusRecord(displayId); } } boolean isImeVisible(int displayId) { synchronized (mLock) { return mIsImeVisibleArray.get(displayId); } } void logTrackingTypingFocus(long duration) { AccessibilityStatsLogUtils.logMagnificationFollowTypingFocusSession(duration); } @Override public boolean processScroll(int displayId, float distanceX, float distanceY) { moveWindowMagnification(displayId, -distanceX, -distanceY); Loading Loading @@ -969,6 +997,12 @@ public class WindowMagnificationManager implements private boolean mTrackingTypingFocusEnabled = true; private volatile long mTrackingTypingFocusStartTime = 0; private static final AtomicLongFieldUpdater<WindowMagnifier> SUM_TIME_UPDATER = AtomicLongFieldUpdater.newUpdater(WindowMagnifier.class, "mTrackingTypingFocusSumTime"); private volatile long mTrackingTypingFocusSumTime = 0; WindowMagnifier(int displayId, WindowMagnificationManager windowMagnificationManager) { mDisplayId = displayId; mWindowMagnificationManager = windowMagnificationManager; Loading Loading @@ -1017,6 +1051,7 @@ public class WindowMagnificationManager implements mEnabled = false; mIdOfLastServiceToControl = INVALID_SERVICE_ID; mTrackingTypingFocusEnabled = false; pauseTrackingTypingFocusRecord(); return true; } return false; Loading Loading @@ -1069,6 +1104,14 @@ public class WindowMagnificationManager implements } void setTrackingTypingFocusEnabled(boolean trackingTypingFocusEnabled) { if (mWindowMagnificationManager.isWindowMagnifierEnabled(mDisplayId) && mWindowMagnificationManager.isImeVisible(mDisplayId) && trackingTypingFocusEnabled) { startTrackingTypingFocusRecord(); } if (mTrackingTypingFocusEnabled && !trackingTypingFocusEnabled) { stopAndLogTrackingTypingFocusRecordIfNeeded(); } mTrackingTypingFocusEnabled = trackingTypingFocusEnabled; } Loading @@ -1076,6 +1119,44 @@ public class WindowMagnificationManager implements return mTrackingTypingFocusEnabled; } void startTrackingTypingFocusRecord() { if (mTrackingTypingFocusStartTime == 0) { mTrackingTypingFocusStartTime = SystemClock.uptimeMillis(); if (DBG) { Slog.d(TAG, "start: mTrackingTypingFocusStartTime = " + mTrackingTypingFocusStartTime); } } } void pauseTrackingTypingFocusRecord() { if (mTrackingTypingFocusStartTime != 0) { final long elapsed = (SystemClock.uptimeMillis() - mTrackingTypingFocusStartTime); // update mTrackingTypingFocusSumTime value in an atomic operation SUM_TIME_UPDATER.addAndGet(this, elapsed); mTrackingTypingFocusStartTime = 0; if (DBG) { Slog.d(TAG, "pause: mTrackingTypingFocusSumTime = " + mTrackingTypingFocusSumTime + ", elapsed = " + elapsed); } } } void stopAndLogTrackingTypingFocusRecordIfNeeded() { if (mTrackingTypingFocusStartTime != 0 || mTrackingTypingFocusSumTime != 0) { final long elapsed = mTrackingTypingFocusStartTime != 0 ? (SystemClock.uptimeMillis() - mTrackingTypingFocusStartTime) : 0; final long duration = mTrackingTypingFocusSumTime + elapsed; if (DBG) { Slog.d(TAG, "stop and log: session duration = " + duration + ", elapsed = " + elapsed); } mWindowMagnificationManager.logTrackingTypingFocus(duration); mTrackingTypingFocusStartTime = 0; mTrackingTypingFocusSumTime = 0; } } boolean isEnabled() { return mEnabled; } Loading services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java +13 −0 Original line number Diff line number Diff line Loading @@ -23,10 +23,12 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyFloat; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.notNull; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.testng.Assert.assertEquals; Loading Loading @@ -292,6 +294,17 @@ public class WindowMagnificationManagerTest { MagnificationScaleProvider.MAX_SCALE); } @Test public void logTrackingTypingFocus_processScroll_logDuration() { WindowMagnificationManager spyWindowMagnificationManager = spy(mWindowMagnificationManager); spyWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f); spyWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, /* shown */ true); spyWindowMagnificationManager.processScroll(TEST_DISPLAY, 10f, 10f); verify(spyWindowMagnificationManager).logTrackingTypingFocus(anyLong()); } @Test public void onRectangleOnScreenRequested_trackingDisabledByOnDrag_withoutMovingMagnifier() throws RemoteException { Loading Loading
core/java/com/android/internal/accessibility/util/AccessibilityStatsLogUtils.java +11 −0 Original line number Diff line number Diff line Loading @@ -167,6 +167,17 @@ public final class AccessibilityStatsLogUtils { convertToLoggingMagnificationMode(mode)); } /** * Logs the duration for the window magnifier's following typing focus session. * * @param duration The duration of a triple-tap-and-hold activation session. */ public static void logMagnificationFollowTypingFocusSession(long duration) { FrameworkStatsLog.write( FrameworkStatsLog.MAGNIFICATION_FOLLOW_TYPING_FOCUS_ACTIVATED_SESSION_REPORTED, duration); } /** * Logs the duration for the magnification session which is activated by the triple tap and * hold gesture. Loading
services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java +82 −1 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ import android.view.accessibility.IWindowMagnificationConnection; import android.view.accessibility.IWindowMagnificationConnectionCallback; import android.view.accessibility.MagnificationAnimationCallback; import com.android.internal.accessibility.util.AccessibilityStatsLogUtils; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.server.LocalServices; Loading @@ -54,6 +55,7 @@ import com.android.server.wm.WindowManagerInternal; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.concurrent.atomic.AtomicLongFieldUpdater; /** * A class to manipulate window magnification through {@link WindowMagnificationConnectionWrapper} Loading Loading @@ -136,6 +138,7 @@ public class WindowMagnificationManager implements private SparseArray<WindowMagnifier> mWindowMagnifiers = new SparseArray<>(); // Whether the following typing focus feature for magnification is enabled. private boolean mMagnificationFollowTypingEnabled = true; @GuardedBy("mLock") private final SparseBooleanArray mIsImeVisibleArray = new SparseBooleanArray(); private boolean mReceiverRegistered = false; Loading Loading @@ -465,18 +468,43 @@ public class WindowMagnificationManager implements } } private void pauseTrackingTypingFocusRecord(int displayId) { WindowMagnifier magnifier; synchronized (mLock) { magnifier = mWindowMagnifiers.get(displayId); if (magnifier == null) { return; } } magnifier.pauseTrackingTypingFocusRecord(); } /** * Called when the IME window visibility changed. * * @param shown {@code true} means the IME window shows on the screen. Otherwise, it's hidden. */ void onImeWindowVisibilityChanged(int displayId, boolean shown) { synchronized (mLock) { mIsImeVisibleArray.put(displayId, shown); } if (shown) { enableAllTrackingTypingFocus(); } else { pauseTrackingTypingFocusRecord(displayId); } } boolean isImeVisible(int displayId) { synchronized (mLock) { return mIsImeVisibleArray.get(displayId); } } void logTrackingTypingFocus(long duration) { AccessibilityStatsLogUtils.logMagnificationFollowTypingFocusSession(duration); } @Override public boolean processScroll(int displayId, float distanceX, float distanceY) { moveWindowMagnification(displayId, -distanceX, -distanceY); Loading Loading @@ -969,6 +997,12 @@ public class WindowMagnificationManager implements private boolean mTrackingTypingFocusEnabled = true; private volatile long mTrackingTypingFocusStartTime = 0; private static final AtomicLongFieldUpdater<WindowMagnifier> SUM_TIME_UPDATER = AtomicLongFieldUpdater.newUpdater(WindowMagnifier.class, "mTrackingTypingFocusSumTime"); private volatile long mTrackingTypingFocusSumTime = 0; WindowMagnifier(int displayId, WindowMagnificationManager windowMagnificationManager) { mDisplayId = displayId; mWindowMagnificationManager = windowMagnificationManager; Loading Loading @@ -1017,6 +1051,7 @@ public class WindowMagnificationManager implements mEnabled = false; mIdOfLastServiceToControl = INVALID_SERVICE_ID; mTrackingTypingFocusEnabled = false; pauseTrackingTypingFocusRecord(); return true; } return false; Loading Loading @@ -1069,6 +1104,14 @@ public class WindowMagnificationManager implements } void setTrackingTypingFocusEnabled(boolean trackingTypingFocusEnabled) { if (mWindowMagnificationManager.isWindowMagnifierEnabled(mDisplayId) && mWindowMagnificationManager.isImeVisible(mDisplayId) && trackingTypingFocusEnabled) { startTrackingTypingFocusRecord(); } if (mTrackingTypingFocusEnabled && !trackingTypingFocusEnabled) { stopAndLogTrackingTypingFocusRecordIfNeeded(); } mTrackingTypingFocusEnabled = trackingTypingFocusEnabled; } Loading @@ -1076,6 +1119,44 @@ public class WindowMagnificationManager implements return mTrackingTypingFocusEnabled; } void startTrackingTypingFocusRecord() { if (mTrackingTypingFocusStartTime == 0) { mTrackingTypingFocusStartTime = SystemClock.uptimeMillis(); if (DBG) { Slog.d(TAG, "start: mTrackingTypingFocusStartTime = " + mTrackingTypingFocusStartTime); } } } void pauseTrackingTypingFocusRecord() { if (mTrackingTypingFocusStartTime != 0) { final long elapsed = (SystemClock.uptimeMillis() - mTrackingTypingFocusStartTime); // update mTrackingTypingFocusSumTime value in an atomic operation SUM_TIME_UPDATER.addAndGet(this, elapsed); mTrackingTypingFocusStartTime = 0; if (DBG) { Slog.d(TAG, "pause: mTrackingTypingFocusSumTime = " + mTrackingTypingFocusSumTime + ", elapsed = " + elapsed); } } } void stopAndLogTrackingTypingFocusRecordIfNeeded() { if (mTrackingTypingFocusStartTime != 0 || mTrackingTypingFocusSumTime != 0) { final long elapsed = mTrackingTypingFocusStartTime != 0 ? (SystemClock.uptimeMillis() - mTrackingTypingFocusStartTime) : 0; final long duration = mTrackingTypingFocusSumTime + elapsed; if (DBG) { Slog.d(TAG, "stop and log: session duration = " + duration + ", elapsed = " + elapsed); } mWindowMagnificationManager.logTrackingTypingFocus(duration); mTrackingTypingFocusStartTime = 0; mTrackingTypingFocusSumTime = 0; } } boolean isEnabled() { return mEnabled; } Loading
services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java +13 −0 Original line number Diff line number Diff line Loading @@ -23,10 +23,12 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyFloat; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.notNull; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.testng.Assert.assertEquals; Loading Loading @@ -292,6 +294,17 @@ public class WindowMagnificationManagerTest { MagnificationScaleProvider.MAX_SCALE); } @Test public void logTrackingTypingFocus_processScroll_logDuration() { WindowMagnificationManager spyWindowMagnificationManager = spy(mWindowMagnificationManager); spyWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f); spyWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, /* shown */ true); spyWindowMagnificationManager.processScroll(TEST_DISPLAY, 10f, 10f); verify(spyWindowMagnificationManager).logTrackingTypingFocus(anyLong()); } @Test public void onRectangleOnScreenRequested_trackingDisabledByOnDrag_withoutMovingMagnifier() throws RemoteException { Loading