Logs the activated session duration for magnification. (2/2)

Uses the atom MagnificationFollowTypingFocusActivatedSessionReported in
westworld to log the activated session duration for the window magnifier
which its following typing focus is enabled.

The duration is accumulated by the time when the window magnifier and
the ime are all on. If one of them is off, we would pause the
accumulated timer. If a user moves the window magnifier to disables
this function, we would stop the accumulated timer and log the duration.

Bug: 216733714
Test: m statsd_testdrive & statsd_testdrive 453
      atest WindowMagnificationManagerTest
Change-Id: I994fc2a3ada8a90fde8b3a0b4f1cc8d7ec21638a
Merged-In: I994fc2a3ada8a90fde8b3a0b4f1cc8d7ec21638a
This commit is contained in:
Daniel Hsieh
2022-04-09 16:34:45 +00:00
parent 7902b95191
commit 22783d8314
3 changed files with 106 additions and 1 deletions

View File

@@ -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.

View File

@@ -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;
@@ -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}
@@ -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;
@@ -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) {
mIsImeVisibleArray.put(displayId, 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);
@@ -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;
@@ -1017,6 +1051,7 @@ public class WindowMagnificationManager implements
mEnabled = false;
mIdOfLastServiceToControl = INVALID_SERVICE_ID;
mTrackingTypingFocusEnabled = false;
pauseTrackingTypingFocusRecord();
return true;
}
return false;
@@ -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;
}
@@ -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;
}

View File

@@ -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;
@@ -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 {