Merge "Do NOT MERGE Fix magnification border includes taskbar" into sc-v2-dev

This commit is contained in:
Ryan Lin
2021-11-03 05:24:26 +00:00
committed by Android (Google) Code Review
4 changed files with 39 additions and 13 deletions

View File

@@ -2440,6 +2440,20 @@ public interface WindowManager extends ViewManager {
*/ */
public static final int PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY = 0x00100000; public static final int PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY = 0x00100000;
/**
* Flag to indicate that this window will be excluded while computing the magnifiable region
* on the un-scaled screen coordinate, which could avoid the cutout on the magnification
* border. It should be used for unmagnifiable overlays.
*
* </p><p>
* Note unlike {@link #PRIVATE_FLAG_NOT_MAGNIFIABLE}, this flag doesn't affect the ability
* of magnification. If you want to the window to be unmagnifiable and doesn't lead to the
* cutout, you need to combine both of them.
* </p><p>
* @hide
*/
public static final int PRIVATE_FLAG_EXCLUDE_FROM_SCREEN_MAGNIFICATION = 0x00200000;
/** /**
* Flag to prevent the window from being magnified by the accessibility magnifier. * Flag to prevent the window from being magnified by the accessibility magnifier.
* *
@@ -2551,6 +2565,7 @@ public interface WindowManager extends ViewManager {
PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE, PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE,
SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS, SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS,
PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY, PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY,
PRIVATE_FLAG_EXCLUDE_FROM_SCREEN_MAGNIFICATION,
PRIVATE_FLAG_NOT_MAGNIFIABLE, PRIVATE_FLAG_NOT_MAGNIFIABLE,
PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION, PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION,
PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC, PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC,
@@ -2631,6 +2646,10 @@ public interface WindowManager extends ViewManager {
mask = PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY, mask = PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY,
equals = PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY, equals = PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY,
name = "IS_ROUNDED_CORNERS_OVERLAY"), name = "IS_ROUNDED_CORNERS_OVERLAY"),
@ViewDebug.FlagToString(
mask = PRIVATE_FLAG_EXCLUDE_FROM_SCREEN_MAGNIFICATION,
equals = PRIVATE_FLAG_EXCLUDE_FROM_SCREEN_MAGNIFICATION,
name = "EXCLUDE_FROM_SCREEN_MAGNIFICATION"),
@ViewDebug.FlagToString( @ViewDebug.FlagToString(
mask = PRIVATE_FLAG_NOT_MAGNIFIABLE, mask = PRIVATE_FLAG_NOT_MAGNIFIABLE,
equals = PRIVATE_FLAG_NOT_MAGNIFIABLE, equals = PRIVATE_FLAG_NOT_MAGNIFIABLE,

View File

@@ -22,6 +22,7 @@ import static android.util.MathUtils.sq;
import static android.view.WindowInsets.Type.displayCutout; import static android.view.WindowInsets.Type.displayCutout;
import static android.view.WindowInsets.Type.ime; import static android.view.WindowInsets.Type.ime;
import static android.view.WindowInsets.Type.systemBars; import static android.view.WindowInsets.Type.systemBars;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_EXCLUDE_FROM_SCREEN_MAGNIFICATION;
import static java.util.Objects.requireNonNull; import static java.util.Objects.requireNonNull;
@@ -659,6 +660,7 @@ public class AccessibilityFloatingMenuView extends FrameLayout
| WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
PixelFormat.TRANSLUCENT); PixelFormat.TRANSLUCENT);
params.receiveInsetsIgnoringZOrder = true; params.receiveInsetsIgnoringZOrder = true;
params.privateFlags |= PRIVATE_FLAG_EXCLUDE_FROM_SCREEN_MAGNIFICATION;
params.windowAnimations = android.R.style.Animation_Translucent; params.windowAnimations = android.R.style.Animation_Translucent;
params.gravity = Gravity.START | Gravity.TOP; params.gravity = Gravity.START | Gravity.TOP;
params.x = (mAlignment == Alignment.RIGHT) ? getMaxWindowX() : getMinWindowX(); params.x = (mAlignment == Alignment.RIGHT) ? getMaxWindowX() : getMinWindowX();

View File

@@ -20,11 +20,11 @@ import static android.accessibilityservice.AccessibilityTrace.FLAGS_MAGNIFICATIO
import static android.accessibilityservice.AccessibilityTrace.FLAGS_WINDOWS_FOR_ACCESSIBILITY_CALLBACK; import static android.accessibilityservice.AccessibilityTrace.FLAGS_WINDOWS_FOR_ACCESSIBILITY_CALLBACK;
import static android.os.Build.IS_USER; import static android.os.Build.IS_USER;
import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_EXCLUDE_FROM_SCREEN_MAGNIFICATION;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER; import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
import static android.view.WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
import static com.android.server.accessibility.AccessibilityTraceFileProto.ENTRY; import static com.android.server.accessibility.AccessibilityTraceFileProto.ENTRY;
import static com.android.server.accessibility.AccessibilityTraceFileProto.MAGIC_NUMBER; import static com.android.server.accessibility.AccessibilityTraceFileProto.MAGIC_NUMBER;
@@ -1008,6 +1008,8 @@ final class AccessibilityController {
WindowState windowState = visibleWindows.valueAt(i); WindowState windowState = visibleWindows.valueAt(i);
final int windowType = windowState.mAttrs.type; final int windowType = windowState.mAttrs.type;
if (isExcludedWindowType(windowType) if (isExcludedWindowType(windowType)
|| ((windowState.mAttrs.privateFlags
& PRIVATE_FLAG_EXCLUDE_FROM_SCREEN_MAGNIFICATION) != 0)
|| ((windowState.mAttrs.privateFlags || ((windowState.mAttrs.privateFlags
& PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY) != 0)) { & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY) != 0)) {
continue; continue;
@@ -1073,7 +1075,6 @@ final class AccessibilityController {
} }
} }
} }
visibleWindows.clear(); visibleWindows.clear();
mMagnificationRegion.op(mDrawBorderInset, mDrawBorderInset, mMagnificationRegion.op(mDrawBorderInset, mDrawBorderInset,
@@ -1110,9 +1111,6 @@ final class AccessibilityController {
private boolean isExcludedWindowType(int windowType) { private boolean isExcludedWindowType(int windowType) {
return windowType == TYPE_MAGNIFICATION_OVERLAY return windowType == TYPE_MAGNIFICATION_OVERLAY
// Omit the touch region to avoid the cut out of the magnification
// bounds because nav bar panel is unmagnifiable.
|| windowType == TYPE_NAVIGATION_BAR_PANEL
// Omit the touch region of window magnification to avoid the cut out of the // Omit the touch region of window magnification to avoid the cut out of the
// magnification and the magnified center of window magnification could be // magnification and the magnified center of window magnification could be
// in the bounds // in the bounds

View File

@@ -40,7 +40,6 @@ import android.graphics.drawable.Icon;
import android.os.IBinder; import android.os.IBinder;
import android.os.UserHandle; import android.os.UserHandle;
import android.provider.Settings; import android.provider.Settings;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest; import android.test.suitebuilder.annotation.SmallTest;
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction; import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
@@ -54,13 +53,16 @@ import com.android.server.accessibility.test.MessageCapturingHandler;
import com.android.server.wm.ActivityTaskManagerInternal; import com.android.server.wm.ActivityTaskManagerInternal;
import com.android.server.wm.WindowManagerInternal; import com.android.server.wm.WindowManagerInternal;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
/** /**
* APCT tests for {@link AccessibilityManagerService}. * APCT tests for {@link AccessibilityManagerService}.
*/ */
public class AccessibilityManagerServiceTest extends AndroidTestCase { public class AccessibilityManagerServiceTest {
private static final String TAG = "A11Y_MANAGER_SERVICE_TEST"; private static final String TAG = "A11Y_MANAGER_SERVICE_TEST";
private static final int ACTION_ID = 20; private static final int ACTION_ID = 20;
private static final String LABEL = "label"; private static final String LABEL = "label";
@@ -104,8 +106,8 @@ public class AccessibilityManagerServiceTest extends AndroidTestCase {
private AccessibilityServiceConnection mAccessibilityServiceConnection; private AccessibilityServiceConnection mAccessibilityServiceConnection;
private AccessibilityManagerService mA11yms; private AccessibilityManagerService mA11yms;
@Override @Before
protected void setUp() throws Exception { public void setUp() throws Exception {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
LocalServices.removeServiceForTest(WindowManagerInternal.class); LocalServices.removeServiceForTest(WindowManagerInternal.class);
LocalServices.removeServiceForTest(ActivityTaskManagerInternal.class); LocalServices.removeServiceForTest(ActivityTaskManagerInternal.class);
@@ -167,44 +169,48 @@ public class AccessibilityManagerServiceTest extends AndroidTestCase {
} }
@SmallTest @SmallTest
@Test
public void testRegisterSystemActionWithoutPermission() throws Exception { public void testRegisterSystemActionWithoutPermission() throws Exception {
doThrow(SecurityException.class).when(mMockSecurityPolicy) doThrow(SecurityException.class).when(mMockSecurityPolicy)
.enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ACCESSIBILITY); .enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ACCESSIBILITY);
try { try {
mA11yms.registerSystemAction(TEST_ACTION, ACTION_ID); mA11yms.registerSystemAction(TEST_ACTION, ACTION_ID);
fail(); Assert.fail();
} catch (SecurityException expected) { } catch (SecurityException expected) {
} }
verify(mMockSystemActionPerformer, never()).registerSystemAction(ACTION_ID, TEST_ACTION); verify(mMockSystemActionPerformer, never()).registerSystemAction(ACTION_ID, TEST_ACTION);
} }
@SmallTest @SmallTest
@Test
public void testRegisterSystemAction() throws Exception { public void testRegisterSystemAction() throws Exception {
mA11yms.registerSystemAction(TEST_ACTION, ACTION_ID); mA11yms.registerSystemAction(TEST_ACTION, ACTION_ID);
verify(mMockSystemActionPerformer).registerSystemAction(ACTION_ID, TEST_ACTION); verify(mMockSystemActionPerformer).registerSystemAction(ACTION_ID, TEST_ACTION);
} }
@SmallTest @Test
public void testUnregisterSystemActionWithoutPermission() throws Exception { public void testUnregisterSystemActionWithoutPermission() throws Exception {
doThrow(SecurityException.class).when(mMockSecurityPolicy) doThrow(SecurityException.class).when(mMockSecurityPolicy)
.enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ACCESSIBILITY); .enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ACCESSIBILITY);
try { try {
mA11yms.unregisterSystemAction(ACTION_ID); mA11yms.unregisterSystemAction(ACTION_ID);
fail(); Assert.fail();
} catch (SecurityException expected) { } catch (SecurityException expected) {
} }
verify(mMockSystemActionPerformer, never()).unregisterSystemAction(ACTION_ID); verify(mMockSystemActionPerformer, never()).unregisterSystemAction(ACTION_ID);
} }
@SmallTest @SmallTest
@Test
public void testUnregisterSystemAction() throws Exception { public void testUnregisterSystemAction() throws Exception {
mA11yms.unregisterSystemAction(ACTION_ID); mA11yms.unregisterSystemAction(ACTION_ID);
verify(mMockSystemActionPerformer).unregisterSystemAction(ACTION_ID); verify(mMockSystemActionPerformer).unregisterSystemAction(ACTION_ID);
} }
@SmallTest @SmallTest
@Test
public void testOnSystemActionsChanged() throws Exception { public void testOnSystemActionsChanged() throws Exception {
setupAccessibilityServiceConnection(); setupAccessibilityServiceConnection();
mA11yms.notifySystemActionsChangedLocked(mUserState); mA11yms.notifySystemActionsChangedLocked(mUserState);
@@ -213,6 +219,7 @@ public class AccessibilityManagerServiceTest extends AndroidTestCase {
} }
@SmallTest @SmallTest
@Test
public void testOnMagnificationTransitionFailed_capabilitiesIsAll_fallBackToPreviousMode() { public void testOnMagnificationTransitionFailed_capabilitiesIsAll_fallBackToPreviousMode() {
final AccessibilityUserState userState = mA11yms.mUserStates.get( final AccessibilityUserState userState = mA11yms.mUserStates.get(
mA11yms.getCurrentUserIdLocked()); mA11yms.getCurrentUserIdLocked());
@@ -223,7 +230,7 @@ public class AccessibilityManagerServiceTest extends AndroidTestCase {
mA11yms.onMagnificationTransitionEndedLocked(false); mA11yms.onMagnificationTransitionEndedLocked(false);
assertEquals(Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW, Assert.assertEquals(Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW,
userState.getMagnificationModeLocked()); userState.getMagnificationModeLocked());
} }
} }