mirror of
https://github.com/facebook/react-native.git
synced 2024-11-21 22:10:14 +00:00
feat(Android): add support for detecting grayscale mode enabled on android (#47497)
Summary: On android the isGrayScaleEnabled method of AccessibilityInfo always returns false due to missing implementation. This PR fills the gap by providing the native module logic for checking grayscale mode. ## Changelog: - Added native module code to check for grayscale mode on android - Updated js accessibility info module to return the correct promise instead of default false for isGrayScaleEnabled() - Moved the test for isGrayScaleEnabled() out of ios scope to common Android and iOS scope [ANDROID] [ADDED] - logic to check for grayscale mode on android Pull Request resolved: https://github.com/facebook/react-native/pull/47497 Test Plan: Tested on : - Google Pixel 7 Pro (Android 14) - OnePlus 12 (Android 14) - Pixel 6 (Android 15) Reviewed By: cortinico Differential Revision: D65662583 Pulled By: javache fbshipit-source-id: 39f9ce37c9375b5380257847395393045eedbadc
This commit is contained in:
parent
2c31fe99e1
commit
e70202e606
@ -56,6 +56,7 @@ const EventNames: Map<
|
||||
['screenReaderChanged', 'touchExplorationDidChange'],
|
||||
['accessibilityServiceChanged', 'accessibilityServiceDidChange'],
|
||||
['invertColorsChanged', 'invertColorDidChange'],
|
||||
['grayscaleChanged', 'grayscaleModeDidChange'],
|
||||
])
|
||||
: new Map([
|
||||
['announcementFinished', 'announcementFinished'],
|
||||
@ -114,7 +115,13 @@ const AccessibilityInfo = {
|
||||
*/
|
||||
isGrayscaleEnabled(): Promise<boolean> {
|
||||
if (Platform.OS === 'android') {
|
||||
return Promise.resolve(false);
|
||||
return new Promise((resolve, reject) => {
|
||||
if (NativeAccessibilityInfoAndroid?.isGrayscaleEnabled != null) {
|
||||
NativeAccessibilityInfoAndroid.isGrayscaleEnabled(resolve);
|
||||
} else {
|
||||
reject(null);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (NativeAccessibilityManagerIOS != null) {
|
||||
|
@ -87,6 +87,7 @@ internal class AccessibilityInfoModule(context: ReactApplicationContext) :
|
||||
private var accessibilityServiceEnabled = false
|
||||
private var recommendedTimeout = 0
|
||||
private var invertColorsEnabled = false
|
||||
private var grayscaleModeEnabled = false
|
||||
|
||||
init {
|
||||
val appContext = context.applicationContext
|
||||
@ -97,6 +98,7 @@ internal class AccessibilityInfoModule(context: ReactApplicationContext) :
|
||||
accessibilityServiceEnabled = accessibilityManager.isEnabled
|
||||
reduceMotionEnabled = isReduceMotionEnabledValue
|
||||
highTextContrastEnabled = isHighTextContrastEnabledValue
|
||||
grayscaleModeEnabled = isGrayscaleEnabledValue
|
||||
}
|
||||
|
||||
@get:TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
@ -123,6 +125,21 @@ internal class AccessibilityInfoModule(context: ReactApplicationContext) :
|
||||
}
|
||||
}
|
||||
|
||||
@get:TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
private val isGrayscaleEnabledValue: Boolean
|
||||
get() {
|
||||
try {
|
||||
val colorCorrectionSettingKey = "accessibility_display_daltonizer_enabled"
|
||||
val colorModeSettingKey = "accessibility_display_daltonizer"
|
||||
// for grayscale mode to be detected, the color correction accessibility setting should be
|
||||
// on and the color correction mode should be set to grayscale (0)
|
||||
return Settings.Secure.getInt(contentResolver, colorCorrectionSettingKey) == 1 &&
|
||||
Settings.Secure.getInt(contentResolver, colorModeSettingKey) == 0
|
||||
} catch (e: Settings.SettingNotFoundException) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
@get:TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
private val isHighTextContrastEnabledValue: Boolean
|
||||
get() {
|
||||
@ -141,6 +158,10 @@ internal class AccessibilityInfoModule(context: ReactApplicationContext) :
|
||||
successCallback.invoke(invertColorsEnabled)
|
||||
}
|
||||
|
||||
override fun isGrayscaleEnabled(successCallback: Callback) {
|
||||
successCallback.invoke(grayscaleModeEnabled)
|
||||
}
|
||||
|
||||
override fun isHighTextContrastEnabled(successCallback: Callback) {
|
||||
successCallback.invoke(highTextContrastEnabled)
|
||||
}
|
||||
@ -211,6 +232,17 @@ internal class AccessibilityInfoModule(context: ReactApplicationContext) :
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateAndSendGrayscaleModeChangeEvent() {
|
||||
val isGrayscaleModeEnabled = isGrayscaleEnabledValue
|
||||
if (grayscaleModeEnabled != isGrayscaleModeEnabled) {
|
||||
grayscaleModeEnabled = isGrayscaleModeEnabled
|
||||
val reactApplicationContext = getReactApplicationContextIfActiveOrWarn()
|
||||
if (reactApplicationContext != null) {
|
||||
reactApplicationContext.emitDeviceEvent(GRAYSCALE_MODE_EVENT_NAME, grayscaleModeEnabled)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
override fun onHostResume() {
|
||||
accessibilityManager?.addTouchExplorationStateChangeListener(
|
||||
@ -227,6 +259,7 @@ internal class AccessibilityInfoModule(context: ReactApplicationContext) :
|
||||
updateAndSendReduceMotionChangeEvent()
|
||||
updateAndSendHighTextContrastChangeEvent()
|
||||
updateAndSendInvertColorsChangeEvent()
|
||||
updateAndSendGrayscaleModeChangeEvent()
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
@ -292,5 +325,6 @@ internal class AccessibilityInfoModule(context: ReactApplicationContext) :
|
||||
private const val ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED_CONSTANT =
|
||||
"high_text_contrast_enabled" // constant is marked with @hide
|
||||
private const val INVERT_COLOR_EVENT_NAME = "invertColorDidChange"
|
||||
private const val GRAYSCALE_MODE_EVENT_NAME = "grayscaleModeDidChange"
|
||||
}
|
||||
}
|
||||
|
@ -34,6 +34,9 @@ export interface Spec extends TurboModule {
|
||||
mSec: number,
|
||||
onSuccess: (recommendedTimeoutMillis: number) => void,
|
||||
) => void;
|
||||
+isGrayscaleEnabled?: (
|
||||
onSuccess: (isGrayscaleEnabled: boolean) => void,
|
||||
) => void;
|
||||
}
|
||||
|
||||
export default (TurboModuleRegistry.get<Spec>('AccessibilityInfo'): ?Spec);
|
||||
|
@ -1336,12 +1336,6 @@ class EnabledExamples extends React.Component<{}> {
|
||||
eventListener="boldTextChanged"
|
||||
/>
|
||||
</RNTesterBlock>
|
||||
<RNTesterBlock title="isGrayScaleEnabled()">
|
||||
<EnabledExample
|
||||
test="gray scale"
|
||||
eventListener="grayscaleChanged"
|
||||
/>
|
||||
</RNTesterBlock>
|
||||
<RNTesterBlock title="isReduceTransparencyEnabled()">
|
||||
<EnabledExample
|
||||
test="reduce transparency"
|
||||
@ -1384,6 +1378,9 @@ class EnabledExamples extends React.Component<{}> {
|
||||
eventListener="screenReaderChanged"
|
||||
/>
|
||||
</RNTesterBlock>
|
||||
<RNTesterBlock title="isGrayScaleEnabled()">
|
||||
<EnabledExample test="gray scale" eventListener="grayscaleChanged" />
|
||||
</RNTesterBlock>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user