Merge "Defines flag to disable touch feedback on display" into tm-dev

This commit is contained in:
TreeHugger Robot
2022-05-19 11:51:29 +00:00
committed by Android (Google) Code Review
8 changed files with 98 additions and 1 deletions

View File

@@ -122,7 +122,8 @@ public final class DisplayManager {
VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS, VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS,
VIRTUAL_DISPLAY_FLAG_TRUSTED, VIRTUAL_DISPLAY_FLAG_TRUSTED,
VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP, VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP,
VIRTUAL_DISPLAY_FLAG_ALWAYS_UNLOCKED VIRTUAL_DISPLAY_FLAG_ALWAYS_UNLOCKED,
VIRTUAL_DISPLAY_FLAG_TOUCH_FEEDBACK_DISABLED
}) })
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
public @interface VirtualDisplayFlag {} public @interface VirtualDisplayFlag {}
@@ -379,6 +380,15 @@ public final class DisplayManager {
*/ */
public static final int VIRTUAL_DISPLAY_FLAG_ALWAYS_UNLOCKED = 1 << 12; public static final int VIRTUAL_DISPLAY_FLAG_ALWAYS_UNLOCKED = 1 << 12;
/**
* Virtual display flags: Indicates that the display should not play sound effects or perform
* haptic feedback when the user touches the screen.
*
* @see #createVirtualDisplay
* @hide
*/
public static final int VIRTUAL_DISPLAY_FLAG_TOUCH_FEEDBACK_DISABLED = 1 << 13;
/** @hide */ /** @hide */
@IntDef(prefix = {"MATCH_CONTENT_FRAMERATE_"}, value = { @IntDef(prefix = {"MATCH_CONTENT_FRAMERATE_"}, value = {
MATCH_CONTENT_FRAMERATE_UNKNOWN, MATCH_CONTENT_FRAMERATE_UNKNOWN,

View File

@@ -308,6 +308,15 @@ public final class Display {
*/ */
public static final int FLAG_ALWAYS_UNLOCKED = 1 << 9; public static final int FLAG_ALWAYS_UNLOCKED = 1 << 9;
/**
* Flag: Indicates that the display should not play sound effects or perform haptic feedback
* when the user touches the screen.
*
* @hide
* @see #getFlags()
*/
public static final int FLAG_TOUCH_FEEDBACK_DISABLED = 1 << 10;
/** /**
* Display flag: Indicates that the contents of the display should not be scaled * Display flag: Indicates that the contents of the display should not be scaled
* to fit the physical screen dimensions. Used for development only to emulate * to fit the physical screen dimensions. Used for development only to emulate

View File

@@ -865,6 +865,9 @@ public final class DisplayInfo implements Parcelable {
if ((flags & Display.FLAG_ALWAYS_UNLOCKED) != 0) { if ((flags & Display.FLAG_ALWAYS_UNLOCKED) != 0) {
result.append(", FLAG_ALWAYS_UNLOCKED"); result.append(", FLAG_ALWAYS_UNLOCKED");
} }
if ((flags & Display.FLAG_TOUCH_FEEDBACK_DISABLED) != 0) {
result.append(", FLAG_TOUCH_FEEDBACK_DISABLED");
}
return result.toString(); return result.toString();
} }
} }

View File

@@ -8200,6 +8200,10 @@ public final class ViewRootImpl implements ViewParent,
*/ */
@Override @Override
public void playSoundEffect(@SoundEffectConstants.SoundEffect int effectId) { public void playSoundEffect(@SoundEffectConstants.SoundEffect int effectId) {
if ((mDisplay.getFlags() & Display.FLAG_TOUCH_FEEDBACK_DISABLED) != 0) {
return;
}
checkThread(); checkThread();
try { try {
@@ -8248,6 +8252,10 @@ public final class ViewRootImpl implements ViewParent,
*/ */
@Override @Override
public boolean performHapticFeedback(int effectId, boolean always) { public boolean performHapticFeedback(int effectId, boolean always) {
if ((mDisplay.getFlags() & Display.FLAG_TOUCH_FEEDBACK_DISABLED) != 0) {
return false;
}
try { try {
return mWindowSession.performHapticFeedback(effectId, always); return mWindowSession.performHapticFeedback(effectId, always);
} catch (RemoteException e) { } catch (RemoteException e) {

View File

@@ -35,16 +35,19 @@ import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage; import static com.google.common.truth.Truth.assertWithMessage;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import android.app.Instrumentation; import android.app.Instrumentation;
import android.content.Context; import android.content.Context;
import android.hardware.display.DisplayManagerGlobal;
import android.os.Binder; import android.os.Binder;
import android.platform.test.annotations.Presubmit; import android.platform.test.annotations.Presubmit;
import android.view.WindowInsets.Side; import android.view.WindowInsets.Side;
import android.view.WindowInsets.Type; import android.view.WindowInsets.Type;
import androidx.test.annotation.UiThreadTest;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest;
import androidx.test.platform.app.InstrumentationRegistry; import androidx.test.platform.app.InstrumentationRegistry;
@@ -334,6 +337,55 @@ public class ViewRootImplTest {
}, false /*shouldReceiveKey*/); }, false /*shouldReceiveKey*/);
} }
@UiThreadTest
@Test
public void playSoundEffect_wrongEffectId_throwException() {
ViewRootImpl viewRootImpl = new ViewRootImpl(sContext,
sContext.getDisplayNoVerify());
View view = new View(sContext);
WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(
TYPE_APPLICATION_OVERLAY);
layoutParams.token = new Binder();
view.setLayoutParams(layoutParams);
viewRootImpl.setView(view, layoutParams, /* panelParentView= */ null);
assertThrows(IllegalArgumentException.class,
() -> viewRootImpl.playSoundEffect(/* effectId= */ -1));
}
@UiThreadTest
@Test
public void playSoundEffect_wrongEffectId_touchFeedbackDisabled_doNothing() {
DisplayInfo displayInfo = new DisplayInfo();
displayInfo.flags = Display.FLAG_TOUCH_FEEDBACK_DISABLED;
Display display = new Display(DisplayManagerGlobal.getInstance(), /* displayId= */
0, displayInfo, new DisplayAdjustments());
ViewRootImpl viewRootImpl = new ViewRootImpl(sContext, display);
View view = new View(sContext);
WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(
TYPE_APPLICATION_OVERLAY);
layoutParams.token = new Binder();
view.setLayoutParams(layoutParams);
viewRootImpl.setView(view, layoutParams, /* panelParentView= */ null);
viewRootImpl.playSoundEffect(/* effectId= */ -1);
}
@UiThreadTest
@Test
public void performHapticFeedback_touchFeedbackDisabled_doNothing() {
DisplayInfo displayInfo = new DisplayInfo();
displayInfo.flags = Display.FLAG_TOUCH_FEEDBACK_DISABLED;
Display display = new Display(DisplayManagerGlobal.getInstance(), /* displayId= */
0, displayInfo, new DisplayAdjustments());
ViewRootImpl viewRootImpl = new ViewRootImpl(sContext, display);
boolean result = viewRootImpl.performHapticFeedback(
HapticFeedbackConstants.CONTEXT_CLICK, true);
assertThat(result).isFalse();
}
class KeyView extends View { class KeyView extends View {
KeyView(Context context) { KeyView(Context context) {
super(context); super(context);

View File

@@ -149,6 +149,13 @@ final class DisplayDeviceInfo {
*/ */
public static final int FLAG_ALWAYS_UNLOCKED = 1 << 15; public static final int FLAG_ALWAYS_UNLOCKED = 1 << 15;
/**
* Flag: Indicates that the display should not play sound effects or perform haptic feedback
* when the user touches the screen.
*
* @hide
*/
public static final int FLAG_TOUCH_FEEDBACK_DISABLED = 1 << 16;
/** /**
* Touch attachment: Display does not receive touch. * Touch attachment: Display does not receive touch.

View File

@@ -381,6 +381,9 @@ final class LogicalDisplay {
if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_ALWAYS_UNLOCKED) != 0) { if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_ALWAYS_UNLOCKED) != 0) {
mBaseDisplayInfo.flags |= Display.FLAG_ALWAYS_UNLOCKED; mBaseDisplayInfo.flags |= Display.FLAG_ALWAYS_UNLOCKED;
} }
if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_TOUCH_FEEDBACK_DISABLED) != 0) {
mBaseDisplayInfo.flags |= Display.FLAG_TOUCH_FEEDBACK_DISABLED;
}
Rect maskingInsets = getMaskingInsets(deviceInfo); Rect maskingInsets = getMaskingInsets(deviceInfo);
int maskedWidth = deviceInfo.width - maskingInsets.left - maskingInsets.right; int maskedWidth = deviceInfo.width - maskingInsets.left - maskingInsets.right;
int maskedHeight = deviceInfo.height - maskingInsets.top - maskingInsets.bottom; int maskedHeight = deviceInfo.height - maskingInsets.top - maskingInsets.bottom;

View File

@@ -27,10 +27,12 @@ import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_ROTAT
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE; import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS; import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH; import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_TOUCH_FEEDBACK_DISABLED;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_TRUSTED; import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_TRUSTED;
import static com.android.server.display.DisplayDeviceInfo.FLAG_ALWAYS_UNLOCKED; import static com.android.server.display.DisplayDeviceInfo.FLAG_ALWAYS_UNLOCKED;
import static com.android.server.display.DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP; import static com.android.server.display.DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP;
import static com.android.server.display.DisplayDeviceInfo.FLAG_TOUCH_FEEDBACK_DISABLED;
import static com.android.server.display.DisplayDeviceInfo.FLAG_TRUSTED; import static com.android.server.display.DisplayDeviceInfo.FLAG_TRUSTED;
import android.content.Context; import android.content.Context;
@@ -457,6 +459,9 @@ public class VirtualDisplayAdapter extends DisplayAdapter {
&& (mInfo.flags & DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP) != 0) { && (mInfo.flags & DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP) != 0) {
mInfo.flags |= FLAG_ALWAYS_UNLOCKED; mInfo.flags |= FLAG_ALWAYS_UNLOCKED;
} }
if ((mFlags & VIRTUAL_DISPLAY_FLAG_TOUCH_FEEDBACK_DISABLED) != 0) {
mInfo.flags |= FLAG_TOUCH_FEEDBACK_DISABLED;
}
mInfo.type = Display.TYPE_VIRTUAL; mInfo.type = Display.TYPE_VIRTUAL;
mInfo.touch = ((mFlags & VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH) == 0) ? mInfo.touch = ((mFlags & VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH) == 0) ?