Merge "Integrate captions volume button with new CaptioningManager API" into tm-dev am: 8fbe5b0fdb
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/16988625 Change-Id: Ib9d93f0f0fe1b4e9536f23431d59457db9d9b701
This commit is contained in:
@@ -311,6 +311,9 @@
|
|||||||
<uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />
|
<uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />
|
||||||
<uses-permission android:name="android.permission.SUPPRESS_CLIPBOARD_ACCESS_NOTIFICATION" />
|
<uses-permission android:name="android.permission.SUPPRESS_CLIPBOARD_ACCESS_NOTIFICATION" />
|
||||||
|
|
||||||
|
<!-- To change system captions state -->
|
||||||
|
<uses-permission android:name="android.permission.SET_SYSTEM_AUDIO_CAPTION" />
|
||||||
|
|
||||||
<protected-broadcast android:name="com.android.settingslib.action.REGISTER_SLICE_RECEIVER" />
|
<protected-broadcast android:name="com.android.settingslib.action.REGISTER_SLICE_RECEIVER" />
|
||||||
<protected-broadcast android:name="com.android.settingslib.action.UNREGISTER_SLICE_RECEIVER" />
|
<protected-broadcast android:name="com.android.settingslib.action.UNREGISTER_SLICE_RECEIVER" />
|
||||||
<protected-broadcast android:name="com.android.settings.flashlight.action.FLASHLIGHT_CHANGED" />
|
<protected-broadcast android:name="com.android.settings.flashlight.action.FLASHLIGHT_CHANGED" />
|
||||||
|
|||||||
@@ -60,7 +60,6 @@ public interface VolumeDialogController {
|
|||||||
|
|
||||||
boolean areCaptionsEnabled();
|
boolean areCaptionsEnabled();
|
||||||
void setCaptionsEnabled(boolean isEnabled);
|
void setCaptionsEnabled(boolean isEnabled);
|
||||||
boolean isCaptionStreamOptedOut();
|
|
||||||
|
|
||||||
void getCaptionsComponentState(boolean fromTooltip);
|
void getCaptionsComponentState(boolean fromTooltip);
|
||||||
|
|
||||||
|
|||||||
@@ -16,8 +16,5 @@
|
|||||||
-->
|
-->
|
||||||
<selector xmlns:android="http://schemas.android.com/apk/res/android"
|
<selector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:sysui="http://schemas.android.com/apk/res-auto">
|
xmlns:sysui="http://schemas.android.com/apk/res-auto">
|
||||||
<item sysui:optedOut="true"
|
|
||||||
android:color="?android:attr/colorButtonNormal"/>
|
|
||||||
|
|
||||||
<item android:color="?android:attr/colorAccent"/>
|
<item android:color="?android:attr/colorAccent"/>
|
||||||
</selector>
|
</selector>
|
||||||
@@ -73,8 +73,7 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:tint="@color/caption_tint_color_selector"
|
android:tint="@color/caption_tint_color_selector"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:soundEffectsEnabled="false"
|
android:soundEffectsEnabled="false"/>
|
||||||
sysui:optedOut="false"/>
|
|
||||||
|
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
||||||
|
|||||||
@@ -136,8 +136,7 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:tint="?android:attr/colorAccent"
|
android:tint="?android:attr/colorAccent"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:soundEffectsEnabled="false"
|
android:soundEffectsEnabled="false" />
|
||||||
sysui:optedOut="false"/>
|
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|||||||
@@ -135,8 +135,7 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:tint="?android:attr/colorAccent"
|
android:tint="?android:attr/colorAccent"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:soundEffectsEnabled="false"
|
android:soundEffectsEnabled="false"/>
|
||||||
sysui:optedOut="false"/>
|
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|||||||
@@ -154,10 +154,6 @@
|
|||||||
<attr name="showAirplaneMode" format="boolean" />
|
<attr name="showAirplaneMode" format="boolean" />
|
||||||
</declare-styleable>
|
</declare-styleable>
|
||||||
|
|
||||||
<declare-styleable name="CaptionsToggleImageButton">
|
|
||||||
<attr name="optedOut" format="boolean" />
|
|
||||||
</declare-styleable>
|
|
||||||
|
|
||||||
<declare-styleable name="IlluminationDrawable">
|
<declare-styleable name="IlluminationDrawable">
|
||||||
<attr name="highlight" format="integer" />
|
<attr name="highlight" format="integer" />
|
||||||
<attr name="cornerRadius" format="dimension" />
|
<attr name="cornerRadius" format="dimension" />
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ import android.view.ViewConfiguration;
|
|||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.view.WindowManagerGlobal;
|
import android.view.WindowManagerGlobal;
|
||||||
import android.view.accessibility.AccessibilityManager;
|
import android.view.accessibility.AccessibilityManager;
|
||||||
|
import android.view.accessibility.CaptioningManager;
|
||||||
import android.view.inputmethod.InputMethodManager;
|
import android.view.inputmethod.InputMethodManager;
|
||||||
|
|
||||||
import com.android.internal.app.IBatteryStats;
|
import com.android.internal.app.IBatteryStats;
|
||||||
@@ -118,6 +119,12 @@ public class FrameworkServicesModule {
|
|||||||
return context.getSystemService(AudioManager.class);
|
return context.getSystemService(AudioManager.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
static CaptioningManager provideCaptioningManager(Context context) {
|
||||||
|
return context.getSystemService(CaptioningManager.class);
|
||||||
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
static ColorDisplayManager provideColorDisplayManager(Context context) {
|
static ColorDisplayManager provideColorDisplayManager(Context context) {
|
||||||
|
|||||||
@@ -28,14 +28,11 @@ import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.Accessibilit
|
|||||||
import com.android.keyguard.AlphaOptimizedImageButton;
|
import com.android.keyguard.AlphaOptimizedImageButton;
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
|
|
||||||
/** Toggle button in Volume Dialog that allows extra state for when streams are opted-out */
|
/** Toggle button in Volume Dialog for controlling system captions state */
|
||||||
public class CaptionsToggleImageButton extends AlphaOptimizedImageButton {
|
public class CaptionsToggleImageButton extends AlphaOptimizedImageButton {
|
||||||
|
|
||||||
private static final int[] OPTED_OUT_STATE = new int[] { R.attr.optedOut };
|
|
||||||
|
|
||||||
private ConfirmedTapListener mConfirmedTapListener;
|
private ConfirmedTapListener mConfirmedTapListener;
|
||||||
private boolean mCaptionsEnabled = false;
|
private boolean mCaptionsEnabled = false;
|
||||||
private boolean mOptedOut = false;
|
|
||||||
|
|
||||||
private GestureDetector mGestureDetector;
|
private GestureDetector mGestureDetector;
|
||||||
private GestureDetector.SimpleOnGestureListener mGestureListener =
|
private GestureDetector.SimpleOnGestureListener mGestureListener =
|
||||||
@@ -60,11 +57,7 @@ public class CaptionsToggleImageButton extends AlphaOptimizedImageButton {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int[] onCreateDrawableState(int extraSpace) {
|
public int[] onCreateDrawableState(int extraSpace) {
|
||||||
int[] state = super.onCreateDrawableState(extraSpace + 1);
|
return super.onCreateDrawableState(extraSpace + 1);
|
||||||
if (mOptedOut) {
|
|
||||||
mergeDrawableStates(state, OPTED_OUT_STATE);
|
|
||||||
}
|
|
||||||
return state;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Runnable setCaptionsEnabled(boolean areCaptionsEnabled) {
|
Runnable setCaptionsEnabled(boolean areCaptionsEnabled) {
|
||||||
@@ -95,16 +88,6 @@ public class CaptionsToggleImageButton extends AlphaOptimizedImageButton {
|
|||||||
return this.mCaptionsEnabled;
|
return this.mCaptionsEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets whether or not the current stream has opted out of captions */
|
|
||||||
void setOptedOut(boolean isOptedOut) {
|
|
||||||
this.mOptedOut = isOptedOut;
|
|
||||||
refreshDrawableState();
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean getOptedOut() {
|
|
||||||
return this.mOptedOut;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setOnConfirmedTapListener(ConfirmedTapListener listener, Handler handler) {
|
void setOnConfirmedTapListener(ConfirmedTapListener listener, Handler handler) {
|
||||||
mConfirmedTapListener = listener;
|
mConfirmedTapListener = listener;
|
||||||
|
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ import android.util.ArrayMap;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
import android.view.accessibility.AccessibilityManager;
|
import android.view.accessibility.AccessibilityManager;
|
||||||
|
import android.view.accessibility.CaptioningManager;
|
||||||
|
|
||||||
import androidx.lifecycle.Observer;
|
import androidx.lifecycle.Observer;
|
||||||
|
|
||||||
@@ -130,6 +131,7 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa
|
|||||||
private final Receiver mReceiver = new Receiver();
|
private final Receiver mReceiver = new Receiver();
|
||||||
private final RingerModeObservers mRingerModeObservers;
|
private final RingerModeObservers mRingerModeObservers;
|
||||||
private final MediaSessions mMediaSessions;
|
private final MediaSessions mMediaSessions;
|
||||||
|
private final CaptioningManager mCaptioningManager;
|
||||||
protected C mCallbacks = new C();
|
protected C mCallbacks = new C();
|
||||||
private final State mState = new State();
|
private final State mState = new State();
|
||||||
protected final MediaSessionsCallbacks mMediaSessionsCallbacksW;
|
protected final MediaSessionsCallbacks mMediaSessionsCallbacksW;
|
||||||
@@ -175,7 +177,8 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa
|
|||||||
IAudioService iAudioService,
|
IAudioService iAudioService,
|
||||||
AccessibilityManager accessibilityManager,
|
AccessibilityManager accessibilityManager,
|
||||||
PackageManager packageManager,
|
PackageManager packageManager,
|
||||||
WakefulnessLifecycle wakefulnessLifecycle) {
|
WakefulnessLifecycle wakefulnessLifecycle,
|
||||||
|
CaptioningManager captioningManager) {
|
||||||
mContext = context.getApplicationContext();
|
mContext = context.getApplicationContext();
|
||||||
mPackageManager = packageManager;
|
mPackageManager = packageManager;
|
||||||
mWakefulnessLifecycle = wakefulnessLifecycle;
|
mWakefulnessLifecycle = wakefulnessLifecycle;
|
||||||
@@ -200,6 +203,7 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa
|
|||||||
mVibrator = vibrator;
|
mVibrator = vibrator;
|
||||||
mHasVibrator = mVibrator.hasVibrator();
|
mHasVibrator = mVibrator.hasVibrator();
|
||||||
mAudioService = iAudioService;
|
mAudioService = iAudioService;
|
||||||
|
mCaptioningManager = captioningManager;
|
||||||
|
|
||||||
boolean accessibilityVolumeStreamActive = accessibilityManager
|
boolean accessibilityVolumeStreamActive = accessibilityManager
|
||||||
.isAccessibilityVolumeStreamActive();
|
.isAccessibilityVolumeStreamActive();
|
||||||
@@ -307,20 +311,11 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean areCaptionsEnabled() {
|
public boolean areCaptionsEnabled() {
|
||||||
int currentValue = Settings.Secure.getIntForUser(mContext.getContentResolver(),
|
return mCaptioningManager.isSystemAudioCaptioningEnabled();
|
||||||
Settings.Secure.ODI_CAPTIONS_ENABLED, 0, UserHandle.USER_CURRENT);
|
|
||||||
return currentValue == 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCaptionsEnabled(boolean isEnabled) {
|
public void setCaptionsEnabled(boolean isEnabled) {
|
||||||
Settings.Secure.putIntForUser(mContext.getContentResolver(),
|
mCaptioningManager.setSystemAudioCaptioningEnabled(isEnabled);
|
||||||
Settings.Secure.ODI_CAPTIONS_ENABLED, isEnabled ? 1 : 0, UserHandle.USER_CURRENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isCaptionStreamOptedOut() {
|
|
||||||
// TODO(b/129768185): Removing secure setting, to be replaced by sound event listener
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void getCaptionsComponentState(boolean fromTooltip) {
|
public void getCaptionsComponentState(boolean fromTooltip) {
|
||||||
@@ -423,6 +418,13 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void onGetCaptionsComponentStateW(boolean fromTooltip) {
|
private void onGetCaptionsComponentStateW(boolean fromTooltip) {
|
||||||
|
if (mCaptioningManager.isSystemAudioCaptioningUiEnabled()) {
|
||||||
|
mCallbacks.onCaptionComponentStateChanged(true, fromTooltip);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(b/220968335): Remove this check once system captions component migrates
|
||||||
|
// to new CaptioningManager APIs.
|
||||||
try {
|
try {
|
||||||
String componentNameString = mContext.getString(
|
String componentNameString = mContext.getString(
|
||||||
com.android.internal.R.string.config_defaultSystemCaptionsService);
|
com.android.internal.R.string.config_defaultSystemCaptionsService);
|
||||||
|
|||||||
@@ -1180,11 +1180,6 @@ public class VolumeDialogImpl implements VolumeDialog,
|
|||||||
if (mODICaptionsIcon.getCaptionsEnabled() != captionsEnabled) {
|
if (mODICaptionsIcon.getCaptionsEnabled() != captionsEnabled) {
|
||||||
mHandler.post(mODICaptionsIcon.setCaptionsEnabled(captionsEnabled));
|
mHandler.post(mODICaptionsIcon.setCaptionsEnabled(captionsEnabled));
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isOptedOut = mController.isCaptionStreamOptedOut();
|
|
||||||
if (mODICaptionsIcon.getOptedOut() != isOptedOut) {
|
|
||||||
mHandler.post(() -> mODICaptionsIcon.setOptedOut(isOptedOut));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onCaptionIconClicked() {
|
private void onCaptionIconClicked() {
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import android.os.Process;
|
|||||||
import android.testing.AndroidTestingRunner;
|
import android.testing.AndroidTestingRunner;
|
||||||
import android.testing.TestableLooper;
|
import android.testing.TestableLooper;
|
||||||
import android.view.accessibility.AccessibilityManager;
|
import android.view.accessibility.AccessibilityManager;
|
||||||
|
import android.view.accessibility.CaptioningManager;
|
||||||
|
|
||||||
import androidx.test.filters.SmallTest;
|
import androidx.test.filters.SmallTest;
|
||||||
|
|
||||||
@@ -88,6 +89,8 @@ public class VolumeDialogControllerImplTest extends SysuiTestCase {
|
|||||||
private PackageManager mPackageManager;
|
private PackageManager mPackageManager;
|
||||||
@Mock
|
@Mock
|
||||||
private WakefulnessLifecycle mWakefullnessLifcycle;
|
private WakefulnessLifecycle mWakefullnessLifcycle;
|
||||||
|
@Mock
|
||||||
|
private CaptioningManager mCaptioningManager;
|
||||||
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
@@ -109,7 +112,7 @@ public class VolumeDialogControllerImplTest extends SysuiTestCase {
|
|||||||
mVolumeController = new TestableVolumeDialogControllerImpl(mContext,
|
mVolumeController = new TestableVolumeDialogControllerImpl(mContext,
|
||||||
mBroadcastDispatcher, mRingerModeTracker, mThreadFactory, mAudioManager,
|
mBroadcastDispatcher, mRingerModeTracker, mThreadFactory, mAudioManager,
|
||||||
mNotificationManager, mVibrator, mIAudioService, mAccessibilityManager,
|
mNotificationManager, mVibrator, mIAudioService, mAccessibilityManager,
|
||||||
mPackageManager, mWakefullnessLifcycle, mCallback);
|
mPackageManager, mWakefullnessLifcycle, mCaptioningManager, mCallback);
|
||||||
mVolumeController.setEnableDialogs(true, true);
|
mVolumeController.setEnableDialogs(true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,10 +187,11 @@ public class VolumeDialogControllerImplTest extends SysuiTestCase {
|
|||||||
AccessibilityManager accessibilityManager,
|
AccessibilityManager accessibilityManager,
|
||||||
PackageManager packageManager,
|
PackageManager packageManager,
|
||||||
WakefulnessLifecycle wakefulnessLifecycle,
|
WakefulnessLifecycle wakefulnessLifecycle,
|
||||||
|
CaptioningManager captioningManager,
|
||||||
C callback) {
|
C callback) {
|
||||||
super(context, broadcastDispatcher, ringerModeTracker, theadFactory, audioManager,
|
super(context, broadcastDispatcher, ringerModeTracker, theadFactory, audioManager,
|
||||||
notificationManager, optionalVibrator, iAudioService, accessibilityManager,
|
notificationManager, optionalVibrator, iAudioService, accessibilityManager,
|
||||||
packageManager, wakefulnessLifecycle);
|
packageManager, wakefulnessLifecycle, captioningManager);
|
||||||
mCallbacks = callback;
|
mCallbacks = callback;
|
||||||
|
|
||||||
ArgumentCaptor<WakefulnessLifecycle.Observer> observerCaptor =
|
ArgumentCaptor<WakefulnessLifecycle.Observer> observerCaptor =
|
||||||
|
|||||||
Reference in New Issue
Block a user