diff options
9 files changed, 69 insertions, 94 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/AppOpsInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/AppOpsInfo.java index 9dcc187cb0ef..87612f15ed3d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/AppOpsInfo.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/AppOpsInfo.java @@ -52,7 +52,7 @@ public class AppOpsInfo extends LinearLayout implements NotificationGuts.GutsCon private NotificationGuts mGutsContainer; private OnClickListener mOnOk = v -> { - closeControls(v); + mGutsContainer.closeControls(v, false); }; public AppOpsInfo(Context context, AttributeSet attrs) { @@ -117,6 +117,7 @@ public class AppOpsInfo extends LinearLayout implements NotificationGuts.GutsCon }); TextView ok = findViewById(R.id.ok); ok.setOnClickListener(mOnOk); + ok.setAccessibilityDelegate(mGutsContainer.getAccessibilityDelegate()); } private String getPrompt() { @@ -160,19 +161,6 @@ public class AppOpsInfo extends LinearLayout implements NotificationGuts.GutsCon } } - private void closeControls(View v) { - mMetricsLogger.visibility(MetricsEvent.APP_OPS_GUTS, false); - int[] parentLoc = new int[2]; - int[] targetLoc = new int[2]; - mGutsContainer.getLocationOnScreen(parentLoc); - v.getLocationOnScreen(targetLoc); - final int centerX = v.getWidth() / 2; - final int centerY = v.getHeight() / 2; - final int x = targetLoc[0] - parentLoc[0] + centerX; - final int y = targetLoc[1] - parentLoc[1] + centerY; - mGutsContainer.closeControls(x, y, false, false); - } - @Override public void setGutsParent(NotificationGuts guts) { mGutsContainer = guts; @@ -200,6 +188,7 @@ public class AppOpsInfo extends LinearLayout implements NotificationGuts.GutsCon @Override public boolean handleCloseControls(boolean save, boolean force) { + mMetricsLogger.visibility(MetricsEvent.APP_OPS_GUTS, false); return false; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java index f7ad50edb2f6..94e12e82f850 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java @@ -1122,9 +1122,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView } public void setGutsView(MenuItem item) { - if (mGuts != null && item.getGutsView() instanceof NotificationGuts.GutsContent) { - ((NotificationGuts.GutsContent) item.getGutsView()).setGutsParent(mGuts); - mGuts.setGutsContent((NotificationGuts.GutsContent) item.getGutsView()); + if (getGuts() != null && item.getGutsView() instanceof NotificationGuts.GutsContent) { + getGuts().setGutsContent((NotificationGuts.GutsContent) item.getGutsView()); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java index 9befa313edd8..254c38b0513e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java @@ -137,13 +137,13 @@ public class NotificationConversationInfo extends LinearLayout implements mSelectedAction = ACTION_HOME; mShortcutManager.requestPinShortcut(mShortcutInfo, null); mShadeController.animateCollapsePanels(); - closeControls(v, true); + mGutsContainer.closeControls(v, true); }; private OnClickListener mOnSnoozeClick = v -> { mSelectedAction = ACTION_SNOOZE; mOnSnoozeClickListener.onClick(v, 1); - closeControls(v, true); + mGutsContainer.closeControls(v, true); }; */ @@ -164,7 +164,7 @@ public class NotificationConversationInfo extends LinearLayout implements private OnClickListener mOnDone = v -> { mPressedApply = true; - closeControls(v, true); + mGutsContainer.closeControls(v, true); }; public NotificationConversationInfo(Context context, AttributeSet attrs) { @@ -258,6 +258,7 @@ public class NotificationConversationInfo extends LinearLayout implements View done = findViewById(R.id.done); done.setOnClickListener(mOnDone); + done.setAccessibilityDelegate(mGutsContainer.getAccessibilityDelegate()); } private void bindActions() { @@ -546,25 +547,6 @@ public class NotificationConversationInfo extends LinearLayout implements controller.show(); } - /** - * Closes the controls and commits the updated importance values (indirectly). - * - * <p><b>Note,</b> this will only get called once the view is dismissing. This means that the - * user does not have the ability to undo the action anymore. - */ - @VisibleForTesting - void closeControls(View v, boolean save) { - int[] parentLoc = new int[2]; - int[] targetLoc = new int[2]; - mGutsContainer.getLocationOnScreen(parentLoc); - v.getLocationOnScreen(targetLoc); - final int centerX = v.getWidth() / 2; - final int centerY = v.getHeight() / 2; - final int x = targetLoc[0] - parentLoc[0] + centerX; - final int y = targetLoc[1] - parentLoc[1] + centerY; - mGutsContainer.closeControls(x, y, save, false /* force */); - } - @Override public void setGutsParent(NotificationGuts guts) { mGutsContainer = guts; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGuts.java index c762b73a1648..eeac46a60ac8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGuts.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGuts.java @@ -22,12 +22,14 @@ import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.drawable.Drawable; +import android.os.Bundle; import android.os.Handler; import android.util.AttributeSet; import android.util.Log; import android.view.View; import android.view.ViewAnimationUtils; import android.view.accessibility.AccessibilityEvent; +import android.view.accessibility.AccessibilityNodeInfo; import android.widget.FrameLayout; import androidx.annotation.Nullable; @@ -59,6 +61,31 @@ public class NotificationGuts extends FrameLayout { private GutsContent mGutsContent; + private View.AccessibilityDelegate mGutsContentAccessibilityDelegate = + new View.AccessibilityDelegate() { + @Override + public void onInitializeAccessibilityNodeInfo( + View host, AccessibilityNodeInfo info) { + super.onInitializeAccessibilityNodeInfo(host, info); + info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_LONG_CLICK); + } + + @Override + public boolean performAccessibilityAction(View host, int action, Bundle args) { + if (super.performAccessibilityAction(host, action, args)) { + return true; + } + + switch (action) { + case AccessibilityNodeInfo.ACTION_LONG_CLICK: + closeControls(host, false); + return true; + } + + return false; + } + }; + public interface GutsContent { public void setGutsParent(NotificationGuts listener); @@ -110,6 +137,11 @@ public class NotificationGuts extends FrameLayout { * view on the lockscreen */ boolean needsFalsingProtection(); + + /** + * Equivalent to {@link View#setAccessibilityDelegate(AccessibilityDelegate)} + */ + void setAccessibilityDelegate(AccessibilityDelegate gutsContentAccessibilityDelegate); } public interface OnGutsClosedListener { @@ -146,6 +178,8 @@ public class NotificationGuts extends FrameLayout { } public void setGutsContent(GutsContent content) { + content.setGutsParent(this); + content.setAccessibilityDelegate(mGutsContentAccessibilityDelegate); mGutsContent = content; removeAllViews(); addView(mGutsContent.getContentView()); @@ -237,13 +271,29 @@ public class NotificationGuts extends FrameLayout { /** * Closes any exposed guts/views. + */ + public void closeControls(View eventSource, boolean save) { + int[] parentLoc = new int[2]; + int[] targetLoc = new int[2]; + getLocationOnScreen(parentLoc); + eventSource.getLocationOnScreen(targetLoc); + final int centerX = eventSource.getWidth() / 2; + final int centerY = eventSource.getHeight() / 2; + final int x = targetLoc[0] - parentLoc[0] + centerX; + final int y = targetLoc[1] - parentLoc[1] + centerY; + + closeControls(x, y, save, false); + } + + /** + * Closes any exposed guts/views. * * @param x x coordinate to animate the close circular reveal with * @param y y coordinate to animate the close circular reveal with * @param save whether the state should be saved * @param force whether the guts should be force-closed regardless of state. */ - public void closeControls(int x, int y, boolean save, boolean force) { + private void closeControls(int x, int y, boolean save, boolean force) { // First try to dismiss any blocking helper. boolean wasBlockingHelperDismissed = Dependency.get(NotificationBlockingHelperManager.class) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java index 334599930b63..56dd3326c843 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java @@ -141,7 +141,7 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G // used by standard ui private OnClickListener mOnDismissSettings = v -> { mPressedApply = true; - closeControls(v, true); + mGutsContainer.closeControls(v, true); }; public NotificationInfo(Context context, AttributeSet attrs) { @@ -250,7 +250,7 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G View done = findViewById(R.id.done); done.setOnClickListener(mOnDismissSettings); - + done.setAccessibilityDelegate(mGutsContainer.getAccessibilityDelegate()); View silent = findViewById(R.id.silence); View alert = findViewById(R.id.alert); @@ -330,7 +330,7 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G mUniqueChannelsInRow, mPkgIcon, mOnSettingsClickListener); mChannelEditorDialogController.setOnFinishListener(() -> { mPresentingChannelEditorDialog = false; - closeControls(this, false); + mGutsContainer.closeControls(this, false); }); mChannelEditorDialogController.show(); } @@ -531,25 +531,6 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G return intent; } - /** - * Closes the controls and commits the updated importance values (indirectly). - * - * <p><b>Note,</b> this will only get called once the view is dismissing. This means that the - * user does not have the ability to undo the action anymore. - */ - @VisibleForTesting - void closeControls(View v, boolean save) { - int[] parentLoc = new int[2]; - int[] targetLoc = new int[2]; - mGutsContainer.getLocationOnScreen(parentLoc); - v.getLocationOnScreen(targetLoc); - final int centerX = v.getWidth() / 2; - final int centerY = v.getHeight() / 2; - final int x = targetLoc[0] - parentLoc[0] + centerX; - final int y = targetLoc[1] - parentLoc[1] + centerY; - mGutsContainer.closeControls(x, y, save, false /* force */); - } - @Override public void setGutsParent(NotificationGuts guts) { mGutsContainer = guts; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationSnooze.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationSnooze.java index cde3dfd66aaf..1ffb244b51c9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationSnooze.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationSnooze.java @@ -380,16 +380,8 @@ public class NotificationSnooze extends LinearLayout private void undoSnooze(View v) { mSelectedOption = null; - int[] parentLoc = new int[2]; - int[] targetLoc = new int[2]; - mGutsContainer.getLocationOnScreen(parentLoc); - v.getLocationOnScreen(targetLoc); - final int centerX = v.getWidth() / 2; - final int centerY = v.getHeight() / 2; - final int x = targetLoc[0] - parentLoc[0] + centerX; - final int y = targetLoc[1] - parentLoc[1] + centerY; showSnoozeOptions(false); - mGutsContainer.closeControls(x, y, false /* save */, false /* force */); + mGutsContainer.closeControls(v, false); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PartialConversationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PartialConversationInfo.java index ea059cbcf3e1..8a34220e9b65 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PartialConversationInfo.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PartialConversationInfo.java @@ -89,7 +89,7 @@ public class PartialConversationInfo extends LinearLayout implements private OnClickListener mOnDone = v -> { mPressedApply = true; - closeControls(v, true); + mGutsContainer.closeControls(v, true); }; public PartialConversationInfo(Context context, AttributeSet attrs) { @@ -132,6 +132,7 @@ public class PartialConversationInfo extends LinearLayout implements View done = findViewById(R.id.done); done.setOnClickListener(mOnDone); + done.setAccessibilityDelegate(mGutsContainer.getAccessibilityDelegate()); } private void bindActions() { @@ -172,7 +173,7 @@ public class PartialConversationInfo extends LinearLayout implements mUniqueChannelsInRow, mPkgIcon, mOnSettingsClickListener); mChannelEditorDialogController.setOnFinishListener(() -> { mPresentingChannelEditorDialog = false; - closeControls(this, false); + mGutsContainer.closeControls(this, false); }); mChannelEditorDialogController.show(); } @@ -320,25 +321,6 @@ public class PartialConversationInfo extends LinearLayout implements } } - /** - * Closes the controls and commits the updated importance values (indirectly). - * - * <p><b>Note,</b> this will only get called once the view is dismissing. This means that the - * user does not have the ability to undo the action anymore. - */ - @VisibleForTesting - void closeControls(View v, boolean save) { - int[] parentLoc = new int[2]; - int[] targetLoc = new int[2]; - mGutsContainer.getLocationOnScreen(parentLoc); - v.getLocationOnScreen(targetLoc); - final int centerX = v.getWidth() / 2; - final int centerY = v.getHeight() / 2; - final int x = targetLoc[0] - parentLoc[0] + centerX; - final int y = targetLoc[1] - parentLoc[1] + centerY; - mGutsContainer.closeControls(x, y, save, false /* force */); - } - @Override public void setGutsParent(NotificationGuts guts) { mGutsContainer = guts; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/AppOpsInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/AppOpsInfoTest.java index dd5cb585d0aa..ec73a7571969 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/AppOpsInfoTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/AppOpsInfoTest.java @@ -144,7 +144,7 @@ public class AppOpsInfoTest extends SysuiTestCase { final View okButton = mAppOpsInfo.findViewById(R.id.ok); okButton.performClick(); assertEquals(1, latch.getCount()); - verify(mGutsParent, times(1)).closeControls(anyInt(), anyInt(), anyBoolean(), anyBoolean()); + verify(mGutsParent, times(1)).closeControls(eq(okButton), anyBoolean()); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java index 0272028e62fc..a815fad10a5c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java @@ -173,7 +173,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase { doAnswer((Answer<Object>) invocation -> { mNotificationInfo.handleCloseControls(true, false); return null; - }).when(mNotificationGuts).closeControls(anyInt(), anyInt(), eq(true), eq(false)); + }).when(mNotificationGuts).closeControls(any(View.class), eq(true)); // Our view is never attached to a window so the View#post methods in NotificationInfo never // get called. Setting this will skip the post and do the action immediately. mNotificationInfo.mSkipPost = true; |