Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 11b68bc4 authored by Daniel Solomon's avatar Daniel Solomon Committed by Android (Google) Code Review
Browse files

Merge "Hide display white balance setting depending on accessibility" into qt-dev

parents 576cb8b0 608ad6f6
Loading
Loading
Loading
Loading
+77 −7
Original line number Diff line number Diff line
@@ -13,17 +13,34 @@
 */
package com.android.settings.display;

import android.app.ActivityManager;
import android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
import android.hardware.display.ColorDisplayManager;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.os.UserHandle;
import android.provider.Settings.Secure;
import android.provider.Settings.System;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;

import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnStart;
import com.android.settingslib.core.lifecycle.events.OnStop;

import com.android.settings.core.TogglePreferenceController;

public class DisplayWhiteBalancePreferenceController extends TogglePreferenceController {
public class DisplayWhiteBalancePreferenceController extends TogglePreferenceController
    implements LifecycleObserver, OnStart, OnStop {

    private ColorDisplayManager mColorDisplayManager;
    @VisibleForTesting
    ContentObserver mContentObserver;
    private Preference mPreference;

    public DisplayWhiteBalancePreferenceController(Context context, String key) {
        super(context, key);
@@ -31,11 +48,7 @@ public class DisplayWhiteBalancePreferenceController extends TogglePreferenceCon

    @Override
    public int getAvailabilityStatus() {
        // Display white balance is only valid in linear light space. COLOR_MODE_SATURATED implies
        // unmanaged color mode, and hence unknown color processing conditions.
        return ColorDisplayManager.isDisplayWhiteBalanceAvailable(mContext) &&
                getColorDisplayManager().getColorMode() !=
                        ColorDisplayManager.COLOR_MODE_SATURATED ?
        return getColorDisplayManager().isDisplayWhiteBalanceAvailable(mContext) ?
            AVAILABLE : DISABLED_FOR_USER;
    }

@@ -49,6 +62,50 @@ public class DisplayWhiteBalancePreferenceController extends TogglePreferenceCon
        return getColorDisplayManager().setDisplayWhiteBalanceEnabled(isChecked);
    }

    @Override
    public void onStart() {
        if (!isAvailable()) {
            return;
        }

        final ContentResolver cr = mContext.getContentResolver();
        mContentObserver = new ContentObserver(new Handler(Looper.getMainLooper())) {
            @Override
            public void onChange(boolean selfChange, Uri uri) {
                super.onChange(selfChange, uri);
                updateVisibility();
            }
        };
        cr.registerContentObserver(
                Secure.getUriFor(Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED),
                false /* notifyForDescendants */, mContentObserver,
                ActivityManager.getCurrentUser());
        cr.registerContentObserver(
                Secure.getUriFor(Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED),
                false /* notifyForDescendants */, mContentObserver,
                ActivityManager.getCurrentUser());
        cr.registerContentObserver(
                System.getUriFor(System.DISPLAY_COLOR_MODE),
                false /* notifyForDescendants */, mContentObserver,
                ActivityManager.getCurrentUser());

        updateVisibility();
    }

    @Override
    public void onStop() {
        if (mContentObserver != null) {
            mContext.getContentResolver().unregisterContentObserver(mContentObserver);
            mContentObserver = null;
        }
    }

    @Override
    public void displayPreference(PreferenceScreen screen) {
        super.displayPreference(screen);
        mPreference = screen.findPreference(getPreferenceKey());
    }

    @VisibleForTesting
    ColorDisplayManager getColorDisplayManager() {
        if (mColorDisplayManager == null) {
@@ -56,4 +113,17 @@ public class DisplayWhiteBalancePreferenceController extends TogglePreferenceCon
        }
        return mColorDisplayManager;
    }

    @VisibleForTesting
    void updateVisibility() {
        if (mPreference != null) {
            ColorDisplayManager cdm = getColorDisplayManager();

            // Display white balance is only valid in linear light space. COLOR_MODE_SATURATED
            // implies unmanaged color mode, and hence unknown color processing conditions.
            // We also disallow display white balance when color accessibility features are enabled.
            mPreference.setVisible(cdm.getColorMode() != ColorDisplayManager.COLOR_MODE_SATURATED &&
                    !cdm.areAccessibilityTransformsEnabled(mContext));
        }
    }
}
+126 −18
Original line number Diff line number Diff line
package com.android.settings.display;

import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static com.google.common.truth.Truth.assertThat;


import android.content.ContentResolver;
import android.content.Context;
import android.hardware.display.ColorDisplayManager;
import android.provider.Settings;

import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;

import com.android.settings.testutils.shadow.SettingsShadowResources;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
@@ -27,6 +38,15 @@ public class DisplayWhiteBalancePreferenceControllerTest {

  @Mock
  private ColorDisplayManager mColorDisplayManager;
  private ContentResolver mContentResolver;
  @Mock(answer = Answers.RETURNS_DEEP_STUBS)
  private Context mContext;
  @Mock
  private PreferenceScreen mScreen;
  @Mock
  private Preference mPreference;

  private final String PREFERENCE_KEY = "display_white_balance";

  @After
  public void tearDown() {
@@ -36,17 +56,21 @@ public class DisplayWhiteBalancePreferenceControllerTest {
  @Before
  public void setUp() {
    MockitoAnnotations.initMocks(this);
    mController = spy(new DisplayWhiteBalancePreferenceController(RuntimeEnvironment.application,
        "display_white_balance"));

    mContentResolver = RuntimeEnvironment.application.getContentResolver();
    when(mContext.getContentResolver()).thenReturn(mContentResolver);
    when(mContext.getResources()).thenReturn(RuntimeEnvironment.application.getResources());
    when(mScreen.findPreference(PREFERENCE_KEY)).thenReturn(mPreference);

    mController = spy(new DisplayWhiteBalancePreferenceController(mContext, PREFERENCE_KEY));
    doReturn(mColorDisplayManager).when(mController).getColorDisplayManager();
  }

  @Test
  public void isAvailable_configuredAvailable() {
  public void isAvailable() {
    SettingsShadowResources.overrideResource(
        com.android.internal.R.bool.config_displayWhiteBalanceAvailable, true);
    when(mColorDisplayManager.getColorMode())
        .thenReturn(ColorDisplayManager.COLOR_MODE_NATURAL);

    assertThat(mController.isAvailable()).isTrue();
  }

@@ -54,20 +78,7 @@ public class DisplayWhiteBalancePreferenceControllerTest {
  public void isAvailable_configuredUnavailable() {
    SettingsShadowResources.overrideResource(
        com.android.internal.R.bool.config_displayWhiteBalanceAvailable, false);
    when(mColorDisplayManager.getColorMode())
        .thenReturn(ColorDisplayManager.COLOR_MODE_SATURATED);
    assertThat(mController.isAvailable()).isFalse();

    SettingsShadowResources.overrideResource(
        com.android.internal.R.bool.config_displayWhiteBalanceAvailable, false);
    when(mColorDisplayManager.getColorMode())
        .thenReturn(ColorDisplayManager.COLOR_MODE_NATURAL);
    assertThat(mController.isAvailable()).isFalse();

    SettingsShadowResources.overrideResource(
        com.android.internal.R.bool.config_displayWhiteBalanceAvailable, true);
    when(mColorDisplayManager.getColorMode())
        .thenReturn(ColorDisplayManager.COLOR_MODE_SATURATED);
    assertThat(mController.isAvailable()).isFalse();
  }

@@ -94,4 +105,101 @@ public class DisplayWhiteBalancePreferenceControllerTest {
    when(mColorDisplayManager.isDisplayWhiteBalanceEnabled()).thenReturn(false);
    assertThat(mController.isChecked()).isFalse();
  }

  @Test
  public void onStart_configuredUnavailable() {
    SettingsShadowResources.overrideResource(
        com.android.internal.R.bool.config_displayWhiteBalanceAvailable, false);
    mController.displayPreference(mScreen);
    mController.onStart();
    assertThat(mController.mContentObserver).isNull();
  }

  @Test
  public void onStart_configuredAvailable() {
    SettingsShadowResources.overrideResource(
        com.android.internal.R.bool.config_displayWhiteBalanceAvailable, true);
    when(mColorDisplayManager.getColorMode())
        .thenReturn(ColorDisplayManager.COLOR_MODE_NATURAL);
    toggleAccessibilityInversion(false);
    toggleAccessibilityDaltonizer(false);

    mController.displayPreference(mScreen);
    mController.onStart();
    assertThat(mController.mContentObserver).isNotNull();
  }

  @Test
  public void visibility_configuredAvailableAccessibilityToggled() {
    SettingsShadowResources.overrideResource(
        com.android.internal.R.bool.config_displayWhiteBalanceAvailable, true);
    mController.displayPreference(mScreen);

    // Accessibility features disabled
    toggleAccessibilityInversion(false);
    reset(mPreference);
    mController.updateVisibility();
    verify(mPreference).setVisible(true);

    toggleAccessibilityDaltonizer(false);
    reset(mPreference);
    mController.updateVisibility();
    verify(mPreference).setVisible(true);

    // Accessibility features enabled one by one
    toggleAccessibilityInversion(true);
    mController.updateVisibility();
    verify(mPreference).setVisible(false);

    toggleAccessibilityDaltonizer(true);
    reset(mPreference);
    mController.updateVisibility();
    verify(mPreference).setVisible(false);

    // Accessibility features disabled one by one
    toggleAccessibilityInversion(false);
    reset(mPreference);
    mController.updateVisibility();
    // Daltonizer is still enabled, so we expect the preference to still be invisible
    verify(mPreference).setVisible(false);

    // Now both a11y features are disabled, so we expect the preference to become visible
    toggleAccessibilityDaltonizer(false);
    mController.updateVisibility();
    verify(mPreference).setVisible(true);
  }

  @Test
  public void visibility_configuredAvailableColorModeChanged() {
    SettingsShadowResources.overrideResource(
            com.android.internal.R.bool.config_displayWhiteBalanceAvailable, true);
    mController.displayPreference(mScreen);

    // Non-Saturated color mode selected
    when(mColorDisplayManager.getColorMode()).thenReturn(ColorDisplayManager.COLOR_MODE_NATURAL);
    reset(mPreference);
    mController.updateVisibility();
    verify(mPreference).setVisible(true);

    // Saturated color mode selected
    when(mColorDisplayManager.getColorMode()).thenReturn(ColorDisplayManager.COLOR_MODE_SATURATED);
    mController.updateVisibility();
    verify(mPreference).setVisible(false);

    // Switch back to non-Saturated color mode
    when(mColorDisplayManager.getColorMode()).thenReturn(ColorDisplayManager.COLOR_MODE_NATURAL);
    reset(mPreference);
    mController.updateVisibility();
    verify(mPreference).setVisible(true);
  }

  private void toggleAccessibilityInversion(boolean enable) {
    Settings.Secure.putInt(mContentResolver,
        Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, enable ? 1 : 0);
  }

  private void toggleAccessibilityDaltonizer(boolean enable) {
    Settings.Secure.putInt(mContentResolver,
        Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, enable ? 1 : 0);
  }
}