summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Jacqueline Bronger <bronger@google.com> 2021-07-19 08:34:41 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2021-07-19 08:34:41 +0000
commit9028f4992c7d1a0b41b92dbce7781fa8c1d34da8 (patch)
tree585e0892df3634d8a2d6674b05fbe2060a42428a
parente8ad8b7ff455ef77e36018de4e59f53483b336c3 (diff)
parentba527220f1a73e1490e7b9c147cbd36b6cdfeed1 (diff)
Merge "Add accessibility messages to privacy chip on tv." into sc-dev
-rw-r--r--packages/SystemUI/res/values/strings_tv.xml8
-rw-r--r--packages/SystemUI/src/com/android/systemui/privacy/television/TvOngoingPrivacyChip.java87
2 files changed, 95 insertions, 0 deletions
diff --git a/packages/SystemUI/res/values/strings_tv.xml b/packages/SystemUI/res/values/strings_tv.xml
index b51cb5619f0c..649e80ecc396 100644
--- a/packages/SystemUI/res/values/strings_tv.xml
+++ b/packages/SystemUI/res/values/strings_tv.xml
@@ -28,4 +28,12 @@
<string name="tv_notification_panel_title">Notifications</string>
<string name="tv_notification_panel_no_notifications">No Notifications</string>
+
+ <string name="mic_recording_announcement">Microphone is recording</string>
+ <string name="camera_recording_announcement">Camera is recording</string>
+ <string name="mic_and_camera_recording_announcement">Camera and Microphone are recording</string>
+ <string name="mic_stopped_recording_announcement">Microphone stopped recording</string>
+ <string name="camera_stopped_recording_announcement">Camera stopped recording</string>
+ <string name="mic_camera_stopped_recording_announcement">Camera and Microphone stopped recording</string>
+
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/television/TvOngoingPrivacyChip.java b/packages/SystemUI/src/com/android/systemui/privacy/television/TvOngoingPrivacyChip.java
index e4f5cde37f1d..d94cd28c3bc6 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/television/TvOngoingPrivacyChip.java
+++ b/packages/SystemUI/src/com/android/systemui/privacy/television/TvOngoingPrivacyChip.java
@@ -53,6 +53,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.LinkedList;
import java.util.List;
import javax.inject.Inject;
@@ -88,6 +89,9 @@ public class TvOngoingPrivacyChip extends SystemUI implements PrivacyItemControl
private static final int STATE_COLLAPSED = 3;
private static final int STATE_DISAPPEARING = 4;
+ // Avoid multiple messages after rapid changes such as starting/stopping both camera and mic.
+ private static final int ACCESSIBILITY_ANNOUNCEMENT_DELAY_MS = 500;
+
private static final int EXPANDED_DURATION_MS = 4000;
public final int mAnimationDurationMs;
@@ -113,6 +117,9 @@ public class TvOngoingPrivacyChip extends SystemUI implements PrivacyItemControl
private final Handler mUiThreadHandler = new Handler(Looper.getMainLooper());
private final Runnable mCollapseRunnable = this::collapseChip;
+ private final Runnable mAccessibilityRunnable = this::makeAccessibilityAnnouncement;
+ private final List<PrivacyItem> mItemsBeforeLastAnnouncement = new LinkedList<>();
+
@State
private int mState = STATE_NOT_SHOWN;
@@ -169,6 +176,8 @@ public class TvOngoingPrivacyChip extends SystemUI implements PrivacyItemControl
}
mPrivacyItems = updatedPrivacyItems;
+
+ postAccessibilityAnnouncement();
updateChip();
}
@@ -301,6 +310,7 @@ public class TvOngoingPrivacyChip extends SystemUI implements PrivacyItemControl
mIndicatorView.getViewTreeObserver().removeOnGlobalLayoutListener(
this);
+ postAccessibilityAnnouncement();
animateIconAppearance();
mChipDrawable.startInitialFadeIn();
}
@@ -460,6 +470,83 @@ public class TvOngoingPrivacyChip extends SystemUI implements PrivacyItemControl
}
/**
+ * Schedules the accessibility announcement to be made after {@code
+ * ACCESSIBILITY_ANNOUNCEMENT_DELAY_MS} (if possible). This is so that only one announcement is
+ * made instead of two separate ones if both the camera and the mic are started/stopped.
+ */
+ private void postAccessibilityAnnouncement() {
+ mUiThreadHandler.removeCallbacks(mAccessibilityRunnable);
+
+ if (mPrivacyItems.size() == 0) {
+ // Announce immediately since announcement cannot be made once the chip is gone.
+ makeAccessibilityAnnouncement();
+ } else {
+ mUiThreadHandler.postDelayed(mAccessibilityRunnable,
+ ACCESSIBILITY_ANNOUNCEMENT_DELAY_MS);
+ }
+ }
+
+ private void makeAccessibilityAnnouncement() {
+ if (mIndicatorView == null) {
+ return;
+ }
+
+ boolean cameraWasRecording = listContainsPrivacyType(mItemsBeforeLastAnnouncement,
+ PrivacyType.TYPE_CAMERA);
+ boolean cameraIsRecording = listContainsPrivacyType(mPrivacyItems,
+ PrivacyType.TYPE_CAMERA);
+ boolean micWasRecording = listContainsPrivacyType(mItemsBeforeLastAnnouncement,
+ PrivacyType.TYPE_MICROPHONE);
+ boolean micIsRecording = listContainsPrivacyType(mPrivacyItems,
+ PrivacyType.TYPE_MICROPHONE);
+
+ int announcement = 0;
+ if (!cameraWasRecording && cameraIsRecording && !micWasRecording && micIsRecording) {
+ // Both started
+ announcement = R.string.mic_and_camera_recording_announcement;
+ } else if (cameraWasRecording && !cameraIsRecording && micWasRecording && !micIsRecording) {
+ // Both stopped
+ announcement = R.string.mic_camera_stopped_recording_announcement;
+ } else {
+ // Did the camera start or stop?
+ if (cameraWasRecording && !cameraIsRecording) {
+ announcement = R.string.camera_stopped_recording_announcement;
+ } else if (!cameraWasRecording && cameraIsRecording) {
+ announcement = R.string.camera_recording_announcement;
+ }
+
+ // Announce camera changes now since we might need a second announcement about the mic.
+ if (announcement != 0) {
+ mIndicatorView.announceForAccessibility(mContext.getString(announcement));
+ announcement = 0;
+ }
+
+ // Did the mic start or stop?
+ if (micWasRecording && !micIsRecording) {
+ announcement = R.string.mic_stopped_recording_announcement;
+ } else if (!micWasRecording && micIsRecording) {
+ announcement = R.string.mic_recording_announcement;
+ }
+ }
+
+ if (announcement != 0) {
+ mIndicatorView.announceForAccessibility(mContext.getString(announcement));
+ }
+
+ mItemsBeforeLastAnnouncement.clear();
+ mItemsBeforeLastAnnouncement.addAll(mPrivacyItems);
+ }
+
+ private boolean listContainsPrivacyType(List<PrivacyItem> list, PrivacyType privacyType) {
+ for (PrivacyItem item : list) {
+ if (item.getPrivacyType() == privacyType) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
* Used in debug logs.
*/
private String stateToString(@State int state) {