[A11y] Notification Intelligence Feedback UI

1. Set adjustment status in content descriptions for different feedback indicators
2. Enlarge feedback icon size

Bug: 175657733
Bug: 175662413
Test: atest com.android.systemui.statusbar.notification, manually test
on device

Change-Id: I6ca0fbc625555d1849d1b4a2749d182434f9f3d2
This commit is contained in:
Chloris Kuo
2020-12-16 03:07:50 -08:00
parent 1ecd270dbe
commit 975d47e1bc
14 changed files with 69 additions and 36 deletions

View File

@@ -112,11 +112,12 @@
android:id="@+id/feedback"
android:layout_width="@dimen/notification_feedback_size"
android:layout_height="@dimen/notification_feedback_size"
android:layout_marginStart="4dp"
android:layout_marginEnd="4dp"
android:layout_marginStart="@dimen/notification_header_separating_margin"
android:layout_gravity="center"
android:scaleType="fitCenter"
android:src="@drawable/ic_feedback_indicator"
android:background="?android:selectableItemBackgroundBorderless"
android:paddingTop="2dp"
android:visibility="gone"
android:contentDescription="@string/notification_feedback_indicator"
/>

View File

@@ -480,7 +480,7 @@
<dimen name="notification_inbox_item_top_padding">5dp</dimen>
<!-- Size of the feedback indicator for notifications -->
<dimen name="notification_feedback_size">16dp</dimen>
<dimen name="notification_feedback_size">20dp</dimen>
<!-- Size of the profile badge for notifications -->
<dimen name="notification_badge_size">12dp</dimen>

View File

@@ -5366,6 +5366,14 @@
<!-- Feedback Indicator -->
<!-- Content description of the feedback icon in the notification. [CHAR LIMIT=NONE] -->
<string name="notification_feedback_indicator">Provide Feedback</string>
<!-- Content description of the alerted feedback icon in the notification. [CHAR LIMIT=NONE] -->
<string name="notification_feedback_indicator_alerted">This notification was promoted to Default. Tap to provide feedback.</string>
<!-- Content description of the silenced feedback icon in the notification. [CHAR LIMIT=NONE] -->
<string name="notification_feedback_indicator_silenced">This notification was demoted to Silent. Tap to provide feedback.</string>
<!-- Content description of the promoted feedback icon in the notification. [CHAR LIMIT=NONE] -->
<string name="notification_feedback_indicator_promoted">This notification was ranked higher. Tap to provide feedback.</string>
<!-- Content description of the demoted feedback icon in the notification. [CHAR LIMIT=NONE] -->
<string name="notification_feedback_indicator_demoted">This notification was ranked lower. Tap to provide feedback.</string>
<!-- Dynamic mode battery saver strings -->
<!-- The user visible name of the notification channel for the routine mode battery saver fyi notification [CHAR_LIMIT=80]-->

View File

@@ -2252,6 +2252,10 @@
<java-symbol type="string" name="ext_media_move_success_message" />
<java-symbol type="string" name="ext_media_move_failure_title" />
<java-symbol type="string" name="ext_media_move_failure_message" />
<java-symbol type="string" name="notification_feedback_indicator_alerted" />
<java-symbol type="string" name="notification_feedback_indicator_silenced" />
<java-symbol type="string" name="notification_feedback_indicator_promoted" />
<java-symbol type="string" name="notification_feedback_indicator_demoted" />
<java-symbol type="style" name="Animation.RecentApplications" />
<java-symbol type="integer" name="dock_enter_exit_duration" />
<java-symbol type="bool" name="config_battery_percentage_setting_available" />

View File

@@ -485,7 +485,7 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle
}
}
row.showFeedbackIcon(mAssistantFeedbackController.showFeedbackIndicator(entry),
mAssistantFeedbackController.getFeedbackImageResource(entry));
mAssistantFeedbackController.getFeedbackResources(entry));
row.setLastAudiblyAlertedMs(entry.getLastAudiblyAlertedMs());
}

View File

@@ -27,6 +27,7 @@ import android.os.Handler;
import android.os.Looper;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.Pair;
import androidx.annotation.Nullable;
@@ -129,24 +130,28 @@ public class AssistantFeedbackController extends ContentObserver {
}
/**
* Get the feedback indicator image resource according to assistant's changes on this
* notification's rank or importance.
* Get the feedback indicator image and content description resources according to assistant's
* changes on this notification's rank or importance.
*
* @param entry Notification Entry to show feedback for
*/
public int getFeedbackImageResource(NotificationEntry entry) {
public Pair<Integer, Integer> getFeedbackResources(NotificationEntry entry) {
int feedbackStatus = getFeedbackStatus(entry);
switch (feedbackStatus) {
case STATUS_ALERTED:
return R.drawable.ic_feedback_alerted;
return new Pair(R.drawable.ic_feedback_alerted,
R.string.notification_feedback_indicator_alerted);
case STATUS_SILENCED:
return R.drawable.ic_feedback_silenced;
return new Pair(R.drawable.ic_feedback_silenced,
R.string.notification_feedback_indicator_silenced);
case STATUS_PROMOTED:
return R.drawable.ic_feedback_uprank;
return new Pair(R.drawable.ic_feedback_uprank,
R.string.notification_feedback_indicator_promoted);
case STATUS_DEMOTED:
return R.drawable.ic_feedback_downrank;
return new Pair(R.drawable.ic_feedback_downrank,
R.string.notification_feedback_indicator_demoted);
default:
return 0;
return new Pair(0, 0);
}
}

View File

@@ -49,6 +49,7 @@ import android.util.AttributeSet;
import android.util.FloatProperty;
import android.util.Log;
import android.util.MathUtils;
import android.util.Pair;
import android.util.Property;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@@ -1672,12 +1673,12 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
requestLayout();
}
public void showFeedbackIcon(boolean show, int resId) {
public void showFeedbackIcon(boolean show, Pair<Integer, Integer> resIds) {
if (mIsSummaryWithChildren) {
mChildrenContainer.showFeedbackIcon(show, resId);
mChildrenContainer.showFeedbackIcon(show, resIds);
}
mPrivateLayout.showFeedbackIcon(show, resId);
mPublicLayout.showFeedbackIcon(show, resId);
mPrivateLayout.showFeedbackIcon(show, resIds);
mPublicLayout.showFeedbackIcon(show, resIds);
}
/** Sets the last time the notification being displayed audibly alerted the user. */

View File

@@ -33,6 +33,7 @@ import android.provider.Settings;
import android.util.ArrayMap;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Pair;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.NotificationHeaderView;
@@ -1586,15 +1587,15 @@ public class NotificationContentView extends FrameLayout {
return null;
}
public void showFeedbackIcon(boolean show, int resId) {
public void showFeedbackIcon(boolean show, Pair<Integer, Integer> resIds) {
if (mContractedChild != null) {
mContractedWrapper.showFeedbackIcon(show, resId);
mContractedWrapper.showFeedbackIcon(show, resIds);
}
if (mExpandedChild != null) {
mExpandedWrapper.showFeedbackIcon(show, resId);
mExpandedWrapper.showFeedbackIcon(show, resIds);
}
if (mHeadsUpChild != null) {
mHeadsUpWrapper.showFeedbackIcon(show, resId);
mHeadsUpWrapper.showFeedbackIcon(show, resIds);
}
}

View File

@@ -22,6 +22,7 @@ import android.app.Notification;
import android.content.Context;
import android.content.res.ColorStateList;
import android.util.ArraySet;
import android.util.Pair;
import android.view.NotificationHeaderView;
import android.view.NotificationTopLineView;
import android.view.View;
@@ -132,10 +133,13 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper {
/** Shows or hides feedback indicator */
@Override
public void showFeedbackIcon(boolean show, int resId) {
public void showFeedbackIcon(boolean show, Pair<Integer, Integer> resIds) {
mFeedbackIcon.setVisibility(show ? View.VISIBLE : View.GONE);
if (show && mFeedbackIcon instanceof ImageButton) {
((ImageButton) mFeedbackIcon).setImageResource(resId);
if (show) {
if (mFeedbackIcon instanceof ImageButton) {
((ImageButton) mFeedbackIcon).setImageResource(resIds.first);
}
mFeedbackIcon.setContentDescription(mView.getContext().getString(resIds.second));
}
}

View File

@@ -29,6 +29,7 @@ import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.util.Pair;
import android.view.ContextThemeWrapper;
import android.view.NotificationHeaderView;
import android.view.View;
@@ -103,7 +104,7 @@ public abstract class NotificationViewWrapper implements TransformableView {
/**
* Shows or hides feedback icon.
*/
public void showFeedbackIcon(boolean show, int resId) {
public void showFeedbackIcon(boolean show, Pair<Integer, Integer> resIds) {
}
public void onReinflated() {

View File

@@ -23,6 +23,7 @@ import android.content.res.Resources;
import android.graphics.drawable.ColorDrawable;
import android.service.notification.StatusBarNotification;
import android.util.AttributeSet;
import android.util.Pair;
import android.view.LayoutInflater;
import android.view.NotificationHeaderView;
import android.view.View;
@@ -1300,12 +1301,12 @@ public class NotificationChildrenContainer extends ViewGroup {
/**
* Shows or hides feedback icon.
*/
public void showFeedbackIcon(boolean show, int resId) {
public void showFeedbackIcon(boolean show, Pair<Integer, Integer> resIds) {
if (mNotificationHeaderWrapper != null) {
mNotificationHeaderWrapper.showFeedbackIcon(show, resId);
mNotificationHeaderWrapper.showFeedbackIcon(show, resIds);
}
if (mNotificationHeaderWrapperLowPriority != null) {
mNotificationHeaderWrapperLowPriority.showFeedbackIcon(show, resId);
mNotificationHeaderWrapperLowPriority.showFeedbackIcon(show, resIds);
}
}

View File

@@ -41,6 +41,7 @@ import android.provider.Settings;
import android.service.notification.StatusBarNotification;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.util.Pair;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -120,9 +121,9 @@ public class AssistantFeedbackControllerTest extends SysuiTestCase {
}
@Test
public void testGetFeedbackImageResource_settingDisabled() {
public void testGetFeedbackResources_settingDisabled() {
switchSetting(OFF);
Assert.assertEquals(0, mAssistantFeedbackController.getFeedbackImageResource(
Assert.assertEquals(new Pair(0, 0), mAssistantFeedbackController.getFeedbackResources(
getEntry(IMPORTANCE_DEFAULT, IMPORTANCE_DEFAULT, RANKING_UNCHANGED)));
}

View File

@@ -39,10 +39,12 @@ import android.app.NotificationChannel;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
import android.util.Pair;
import android.view.View;
import androidx.test.filters.SmallTest;
import com.android.internal.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -210,7 +212,7 @@ public class ExpandableNotificationRowTest extends SysuiTestCase {
// public notification is custom layout - no header
mGroupRow.setSensitive(true, true);
mGroupRow.setOnFeedbackClickListener(null);
mGroupRow.showFeedbackIcon(false, 0);
mGroupRow.showFeedbackIcon(false, null);
}
@Test
@@ -224,12 +226,13 @@ public class ExpandableNotificationRowTest extends SysuiTestCase {
mGroupRow.setChildrenContainer(mockContainer);
final boolean show = true;
final int resId = 1;
mGroupRow.showFeedbackIcon(show, resId);
final Pair<Integer, Integer> resIds = new Pair(R.drawable.ic_feedback_alerted,
R.string.notification_feedback_indicator_alerted);
mGroupRow.showFeedbackIcon(show, resIds);
verify(mockContainer, times(1)).showFeedbackIcon(show, resId);
verify(privateLayout, times(1)).showFeedbackIcon(show, resId);
verify(publicLayout, times(1)).showFeedbackIcon(show, resId);
verify(mockContainer, times(1)).showFeedbackIcon(show, resIds);
verify(privateLayout, times(1)).showFeedbackIcon(show, resIds);
verify(publicLayout, times(1)).showFeedbackIcon(show, resIds);
}
@Test

View File

@@ -25,6 +25,7 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.util.Pair;
import android.view.NotificationHeaderView;
import android.view.View;
import android.view.ViewPropertyAnimator;
@@ -33,6 +34,7 @@ import androidx.test.annotation.UiThreadTest;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.internal.R;
import com.android.internal.widget.NotificationExpandButton;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.media.dialog.MediaOutputDialogFactory;
@@ -95,7 +97,8 @@ public class NotificationContentViewTest extends SysuiTestCase {
mView.setExpandedChild(mockExpanded);
mView.setHeadsUpChild(mockHeadsUp);
mView.showFeedbackIcon(true, 1);
mView.showFeedbackIcon(true, new Pair(R.drawable.ic_feedback_alerted,
R.string.notification_feedback_indicator_alerted));
verify(mockContracted, times(1)).setVisibility(View.VISIBLE);
verify(mockExpanded, times(1)).setVisibility(View.VISIBLE);