aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulia Sullivan <juliansull@google.com>2024-05-07 11:28:12 -0700
committerCopybara-Service <copybara-worker@google.com>2024-05-07 11:30:08 -0700
commit87a666523229bbb9b0ee9d2d560ee0ebf24ae79e (patch)
tree763ca2de1887579018cb49d53e2e04f290233f64
parent6aecbb4b15e7d33ae684c0e9b110230ec830e182 (diff)
downloadrobolectric-87a666523229bbb9b0ee9d2d560ee0ebf24ae79e.tar.gz
Rewrites ShadowCaptioningManager so it uses more real code.
Before, this would fake out some, but not all of the functionality of ShadowCaptioningManager. This lead to a disjointed Shadow. This now has users update the Settings.Secure as they would on real android and only shadows functions that call into AccessibilityManager since that calls into a service. PiperOrigin-RevId: 631491210
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowCaptioningManagerTest.java155
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowCaptioningManager.java80
2 files changed, 140 insertions, 95 deletions
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowCaptioningManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowCaptioningManagerTest.java
index 470eeff75..bb9e408fd 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowCaptioningManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowCaptioningManagerTest.java
@@ -1,31 +1,81 @@
package org.robolectric.shadows;
+import static android.os.Build.VERSION_CODES.KITKAT;
+import static android.os.Build.VERSION_CODES.TIRAMISU;
import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.robolectric.Shadows.shadowOf;
import android.content.Context;
+import android.os.Looper;
+import android.provider.Settings;
+import android.provider.Settings.Secure;
import android.view.accessibility.CaptioningManager;
+import android.view.accessibility.CaptioningManager.CaptionStyle;
import android.view.accessibility.CaptioningManager.CaptioningChangeListener;
+import androidx.annotation.NonNull;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.Locale;
+import javax.annotation.Nullable;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
/** Tests for the ShadowCaptioningManager. */
@RunWith(AndroidJUnit4.class)
-@Config(minSdk = 19)
+@Config(minSdk = KITKAT)
public final class ShadowCaptioningManagerTest {
- @Mock private CaptioningChangeListener captioningChangeListener;
+ private TestCaptioningChangeListener captioningChangeListener =
+ new TestCaptioningChangeListener();
+
+ private static final int ENABLED = 1;
+ private static final int DISABLED = 0;
private CaptioningManager captioningManager;
+ private Context context;
+
+ public class TestCaptioningChangeListener extends CaptioningChangeListener {
+ public boolean isEnabled = false;
+ @Nullable public CaptionStyle captionStyle = null;
+ @Nullable public Locale locale = null;
+ public float fontScale = 1.0f;
+ public boolean systemAudioCaptioningEnabled = false;
+ public boolean systemAudioCaptioningUiEnabled = false;
+
+ @Override
+ public void onEnabledChanged(boolean enabled) {
+ isEnabled = enabled;
+ }
+
+ @Override
+ public void onUserStyleChanged(@NonNull CaptionStyle userStyle) {
+ captionStyle = userStyle;
+ }
+
+ @Override
+ public void onLocaleChanged(@Nullable Locale locale) {
+ this.locale = locale;
+ }
+
+ @Override
+ public void onFontScaleChanged(float fontScale) {
+ this.fontScale = fontScale;
+ }
+
+ @Override
+ public void onSystemAudioCaptioningChanged(boolean enabled) {
+ this.systemAudioCaptioningEnabled = enabled;
+ }
+
+ @Override
+ public void onSystemAudioCaptioningUiChanged(boolean enabled) {
+ this.systemAudioCaptioningUiEnabled = enabled;
+ }
+ }
@Before
public void setUp() {
@@ -34,87 +84,106 @@ public final class ShadowCaptioningManagerTest {
(CaptioningManager)
ApplicationProvider.getApplicationContext()
.getSystemService(Context.CAPTIONING_SERVICE);
+ context = RuntimeEnvironment.getApplication();
}
@Test
public void setEnabled_true() {
- assertThat(captioningManager.isEnabled()).isFalse();
-
- shadowOf(captioningManager).setEnabled(true);
+ Settings.Secure.putInt(
+ context.getContentResolver(), Secure.ACCESSIBILITY_CAPTIONING_ENABLED, ENABLED);
assertThat(captioningManager.isEnabled()).isTrue();
}
@Test
public void setEnabled_false() {
- shadowOf(captioningManager).setEnabled(false);
+ Settings.Secure.putInt(
+ context.getContentResolver(), Secure.ACCESSIBILITY_CAPTIONING_ENABLED, DISABLED);
assertThat(captioningManager.isEnabled()).isFalse();
}
@Test
- public void setFontScale_changesValueOfGetFontScale() {
- float fontScale = 1.5f;
- shadowOf(captioningManager).setFontScale(fontScale);
+ public void setEnabled_callsCallback() {
+ captioningManager.addCaptioningChangeListener(captioningChangeListener);
+ Settings.Secure.putInt(
+ context.getContentResolver(), Secure.ACCESSIBILITY_CAPTIONING_ENABLED, ENABLED);
- assertThat(captioningManager.getFontScale()).isWithin(0.001f).of(fontScale);
+ shadowOf(Looper.getMainLooper()).idle();
+ assertThat(captioningChangeListener.isEnabled).isTrue();
}
@Test
- public void setFontScale_notifiesObservers() {
- float fontScale = 1.5f;
- captioningManager.addCaptioningChangeListener(captioningChangeListener);
-
- shadowOf(captioningManager).setFontScale(fontScale);
+ public void setFontScale_updatesValue() {
+ Settings.Secure.putFloat(
+ context.getContentResolver(), Secure.ACCESSIBILITY_CAPTIONING_FONT_SCALE, 2.0f);
- verify(captioningChangeListener).onFontScaleChanged(fontScale);
+ assertThat(captioningManager.getFontScale()).isEqualTo(2.0f);
}
@Test
- public void addCaptioningChangeListener_doesNotRegisterSameListenerTwice() {
- float fontScale = 1.5f;
+ public void setFontScale_callsCallback() {
captioningManager.addCaptioningChangeListener(captioningChangeListener);
+ Settings.Secure.putFloat(
+ context.getContentResolver(), Secure.ACCESSIBILITY_CAPTIONING_FONT_SCALE, 3.0f);
- captioningManager.addCaptioningChangeListener(captioningChangeListener);
+ shadowOf(Looper.getMainLooper()).idle();
+ assertThat(captioningChangeListener.fontScale).isEqualTo(3.0f);
+ }
- shadowOf(captioningManager).setFontScale(fontScale);
- verify(captioningChangeListener).onFontScaleChanged(fontScale);
+ @Test
+ public void setLocale_updatesValue() {
+ Settings.Secure.putString(
+ context.getContentResolver(),
+ Secure.ACCESSIBILITY_CAPTIONING_LOCALE,
+ Locale.JAPANESE.toLanguageTag());
+
+ assertThat(captioningManager.getLocale()).isEqualTo(Locale.JAPANESE);
}
@Test
- public void removeCaptioningChangeListener_unregistersFontScaleListener() {
+ public void setLocale_callsCallback() {
captioningManager.addCaptioningChangeListener(captioningChangeListener);
+ Settings.Secure.putString(
+ context.getContentResolver(),
+ Secure.ACCESSIBILITY_CAPTIONING_LOCALE,
+ Locale.FRENCH.toLanguageTag());
- captioningManager.removeCaptioningChangeListener(captioningChangeListener);
-
- shadowOf(captioningManager).setFontScale(1.5f);
- verifyNoMoreInteractions(captioningChangeListener);
+ shadowOf(Looper.getMainLooper()).idle();
+ assertThat(captioningChangeListener.locale).isEqualTo(Locale.FRENCH);
}
@Test
- public void setLocale_nonNull() {
- Locale locale = Locale.US;
- assertThat(captioningManager.getLocale()).isNull();
-
- shadowOf(captioningManager).setLocale(locale);
+ @Config(minSdk = TIRAMISU)
+ public void setSystemAudioCaptioningEnabled_updatesValue() {
+ captioningManager.setSystemAudioCaptioningEnabled(true);
- assertThat(captioningManager.getLocale()).isEqualTo(locale);
+ assertThat(captioningManager.isSystemAudioCaptioningEnabled()).isEqualTo(true);
}
@Test
- public void setLocale_null() {
- shadowOf(captioningManager).setLocale(null);
+ @Config(minSdk = TIRAMISU)
+ public void setSystemAudioCaptioningEnabled_callsCallback() {
+ captioningManager.setSystemAudioCaptioningEnabled(false);
- assertThat(captioningManager.getLocale()).isNull();
+ shadowOf(Looper.getMainLooper()).idle();
+ assertThat(captioningChangeListener.systemAudioCaptioningEnabled).isEqualTo(false);
}
@Test
- public void setLocale_notifiesObservers() {
- Locale locale = Locale.US;
- captioningManager.addCaptioningChangeListener(captioningChangeListener);
+ @Config(minSdk = TIRAMISU)
+ public void setSystemAudioCaptioningUiEnabled_updatesValue() {
+ captioningManager.setSystemAudioCaptioningUiEnabled(true);
+
+ assertThat(captioningManager.isSystemAudioCaptioningUiEnabled()).isEqualTo(true);
+ }
- shadowOf(captioningManager).setLocale(locale);
+ @Test
+ @Config(minSdk = TIRAMISU)
+ public void setSystemAudioCaptioningUiEnabled_callsCallback() {
+ captioningManager.setSystemAudioCaptioningUiEnabled(false);
- verify(captioningChangeListener).onLocaleChanged(locale);
+ shadowOf(Looper.getMainLooper()).idle();
+ assertThat(captioningChangeListener.systemAudioCaptioningUiEnabled).isEqualTo(false);
}
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCaptioningManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCaptioningManager.java
index 19762d193..203e43968 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCaptioningManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCaptioningManager.java
@@ -1,72 +1,48 @@
package org.robolectric.shadows;
-import android.annotation.NonNull;
-import android.util.ArraySet;
+import static android.os.Build.VERSION_CODES.TIRAMISU;
+import static org.robolectric.util.reflector.Reflector.reflector;
+
+import android.content.ContentResolver;
+import android.provider.Settings;
import android.view.accessibility.CaptioningManager;
-import android.view.accessibility.CaptioningManager.CaptioningChangeListener;
-import java.util.Locale;
-import javax.annotation.Nullable;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.RealObject;
+import org.robolectric.util.reflector.Accessor;
+import org.robolectric.util.reflector.ForType;
/** Shadow of {@link android.view.accessibility.CaptioningManager}. */
@Implements(CaptioningManager.class)
public class ShadowCaptioningManager {
- private float fontScale = 1;
- private boolean isEnabled = false;
- @Nullable private Locale locale;
-
- private final ArraySet<CaptioningChangeListener> listeners = new ArraySet<>();
-
- /** Returns 1.0 as default or the most recent value passed to {@link #setFontScale()} */
- @Implementation(minSdk = 19)
- protected float getFontScale() {
- return fontScale;
- }
-
- /** Sets the value to be returned by {@link CaptioningManager#getFontScale()} */
- public void setFontScale(float fontScale) {
- this.fontScale = fontScale;
+ @RealObject private CaptioningManager realCaptioningManager;
- for (CaptioningChangeListener captioningChangeListener : listeners) {
- captioningChangeListener.onFontScaleChanged(fontScale);
- }
+ @Implementation(minSdk = TIRAMISU)
+ protected void setSystemAudioCaptioningEnabled(boolean isEnabled) {
+ Settings.Secure.putInt(
+ getContentResolver(), Settings.Secure.ODI_CAPTIONS_ENABLED, isEnabled ? 1 : 0);
}
- /** Returns false or the most recent value passed to {@link #setEnabled(boolean)} */
- @Implementation(minSdk = 19)
- protected boolean isEnabled() {
- return isEnabled;
+ @Implementation(minSdk = TIRAMISU)
+ protected void setSystemAudioCaptioningUiEnabled(boolean isEnabled) {
+ Settings.Secure.putInt(
+ getContentResolver(), Settings.Secure.ODI_CAPTIONS_VOLUME_UI_ENABLED, isEnabled ? 1 : 0);
}
- /** Sets the value to be returned by {@link CaptioningManager#isEnabled()} */
- public void setEnabled(boolean isEnabled) {
- this.isEnabled = isEnabled;
+ @Implementation(minSdk = TIRAMISU)
+ protected boolean isSystemAudioCaptioningUiEnabled() {
+ return Settings.Secure.getInt(
+ getContentResolver(), Settings.Secure.ODI_CAPTIONS_VOLUME_UI_ENABLED, 1)
+ == 1;
}
- @Implementation(minSdk = 19)
- protected void addCaptioningChangeListener(@NonNull CaptioningChangeListener listener) {
- listeners.add(listener);
+ private ContentResolver getContentResolver() {
+ return reflector(CaptioningManagerReflector.class, realCaptioningManager).getContentResolver();
}
- @Implementation(minSdk = 19)
- protected void removeCaptioningChangeListener(@NonNull CaptioningChangeListener listener) {
- listeners.remove(listener);
- }
-
- /** Returns null or the most recent value passed to {@link #setLocale(Locale)} */
- @Implementation(minSdk = 19)
- @Nullable
- protected Locale getLocale() {
- return locale;
- }
-
- /** Sets the value to be returned by {@link CaptioningManager#getLocale()} */
- public void setLocale(@Nullable Locale locale) {
- this.locale = locale;
-
- for (CaptioningChangeListener captioningChangeListener : listeners) {
- captioningChangeListener.onLocaleChanged(locale);
- }
+ @ForType(CaptioningManager.class)
+ interface CaptioningManagerReflector {
+ @Accessor("mContentResolver")
+ ContentResolver getContentResolver();
}
}