mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
feat(Android): add support for invert colors check on android accessibility (#47341)
Summary: This PR provides a fix for the long existing issue of missing check for invert color in accessibility options on Android. Reference Issue : https://github.com/facebook/react-native/issues/30870 ## Changelog: - Added native module code to check for invert color settings value - Updated js module to return a proper promise instead of default false for isInvertColorsEnabled() Pick one each for the category and type tags: [ANDROID] [FIXED] - Missing isInvertColorsEnabled implementation for Android For more details, see: https://reactnative.dev/contributing/changelogs-in-pull-requests Pull Request resolved: https://github.com/facebook/react-native/pull/47341 Test Plan: Tested on OnePlus 12 with Android 14 and Pixel 6 with Android 15. The try catch exists because in some cases if the switch hasn't been toggled before the android system raises the missing settings exception. Reviewed By: cortinico, fabriziocucci Differential Revision: D65419632 Pulled By: javache fbshipit-source-id: ddb103445a9d0f318e52ba9d23750140ce5a7ed0
This commit is contained in:
1 parent
dc9db01665
commit
cc1d2853fb
4 files changed
+47
-7
No files matched your search
+8
-1
@@ -55,6 +55,7 @@ const EventNames: Map<
|
||||
['highTextContrastChanged', 'highTextContrastDidChange'],
|
||||
['screenReaderChanged', 'touchExplorationDidChange'],
|
||||
['accessibilityServiceChanged', 'accessibilityServiceDidChange'],
|
||||
['invertColorsChanged', 'invertColorDidChange'],
|
||||
])
|
||||
: new Map([
|
||||
['announcementFinished', 'announcementFinished'],
|
||||
@@ -138,7 +139,13 @@ const AccessibilityInfo = {
|
||||
*/
|
||||
isInvertColorsEnabled(): Promise<boolean> {
|
||||
if (Platform.OS === 'android') {
|
||||
return Promise.resolve(false);
|
||||
return new Promise((resolve, reject) => {
|
||||
if (NativeAccessibilityInfoAndroid?.isInvertColorsEnabled != null) {
|
||||
NativeAccessibilityInfoAndroid.isInvertColorsEnabled(resolve);
|
||||
} else {
|
||||
reject(null);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (NativeAccessibilityManagerIOS != null) {
|
||||
|
||||
+29
@@ -86,6 +86,7 @@ internal class AccessibilityInfoModule(context: ReactApplicationContext) :
|
||||
private var touchExplorationEnabled = false
|
||||
private var accessibilityServiceEnabled = false
|
||||
private var recommendedTimeout = 0
|
||||
private var invertColorsEnabled = false
|
||||
|
||||
init {
|
||||
val appContext = context.applicationContext
|
||||
@@ -111,6 +112,17 @@ internal class AccessibilityInfoModule(context: ReactApplicationContext) :
|
||||
return parsedValue == 0f
|
||||
}
|
||||
|
||||
@get:TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
private val isInvertColorsEnabledValue: Boolean
|
||||
get() {
|
||||
try {
|
||||
return Settings.Secure.getInt(
|
||||
contentResolver, Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED) == 1
|
||||
} catch (e: Settings.SettingNotFoundException) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
@get:TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
private val isHighTextContrastEnabledValue: Boolean
|
||||
get() {
|
||||
@@ -125,6 +137,10 @@ internal class AccessibilityInfoModule(context: ReactApplicationContext) :
|
||||
successCallback.invoke(reduceMotionEnabled)
|
||||
}
|
||||
|
||||
override fun isInvertColorsEnabled(successCallback: Callback) {
|
||||
successCallback.invoke(invertColorsEnabled)
|
||||
}
|
||||
|
||||
override fun isHighTextContrastEnabled(successCallback: Callback) {
|
||||
successCallback.invoke(highTextContrastEnabled)
|
||||
}
|
||||
@@ -148,6 +164,17 @@ internal class AccessibilityInfoModule(context: ReactApplicationContext) :
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateAndSendInvertColorsChangeEvent() {
|
||||
val isInvertColorsEnabled = isInvertColorsEnabledValue
|
||||
if (invertColorsEnabled != isInvertColorsEnabled) {
|
||||
invertColorsEnabled = isInvertColorsEnabled
|
||||
val reactApplicationContext = getReactApplicationContextIfActiveOrWarn()
|
||||
if (reactApplicationContext != null) {
|
||||
reactApplicationContext.emitDeviceEvent(INVERT_COLOR_EVENT_NAME, invertColorsEnabled)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateAndSendHighTextContrastChangeEvent() {
|
||||
val isHighTextContrastEnabled = isHighTextContrastEnabledValue
|
||||
if (highTextContrastEnabled != isHighTextContrastEnabled) {
|
||||
@@ -199,6 +226,7 @@ internal class AccessibilityInfoModule(context: ReactApplicationContext) :
|
||||
updateAndSendAccessibilityServiceChangeEvent(accessibilityManager?.isEnabled == true)
|
||||
updateAndSendReduceMotionChangeEvent()
|
||||
updateAndSendHighTextContrastChangeEvent()
|
||||
updateAndSendInvertColorsChangeEvent()
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
@@ -263,5 +291,6 @@ internal class AccessibilityInfoModule(context: ReactApplicationContext) :
|
||||
private const val ACCESSIBILITY_SERVICE_EVENT_NAME = "accessibilityServiceDidChange"
|
||||
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"
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,9 @@ export interface Spec extends TurboModule {
|
||||
+isReduceMotionEnabled: (
|
||||
onSuccess: (isReduceMotionEnabled: boolean) => void,
|
||||
) => void;
|
||||
+isInvertColorsEnabled?: (
|
||||
onSuccess: (isInvertColorsEnabled: boolean) => void,
|
||||
) => void;
|
||||
+isHighTextContrastEnabled?: (
|
||||
onSuccess: (isHighTextContrastEnabled: boolean) => void,
|
||||
) => void;
|
||||
|
||||
@@ -1341,12 +1341,6 @@ class EnabledExamples extends React.Component<{}> {
|
||||
eventListener="grayscaleChanged"
|
||||
/>
|
||||
</RNTesterBlock>
|
||||
<RNTesterBlock title="isInvertColorsEnabled()">
|
||||
<EnabledExample
|
||||
test="invert colors"
|
||||
eventListener="invertColorsChanged"
|
||||
/>
|
||||
</RNTesterBlock>
|
||||
<RNTesterBlock title="isReduceTransparencyEnabled()">
|
||||
<EnabledExample
|
||||
test="reduce transparency"
|
||||
@@ -1376,6 +1370,13 @@ class EnabledExamples extends React.Component<{}> {
|
||||
/>
|
||||
</RNTesterBlock>
|
||||
|
||||
<RNTesterBlock title="isInvertColorsEnabled()">
|
||||
<EnabledExample
|
||||
test="invert colors"
|
||||
eventListener="invertColorsChanged"
|
||||
/>
|
||||
</RNTesterBlock>
|
||||
|
||||
<RNTesterBlock title="isScreenReaderEnabled()">
|
||||
<EnabledExample
|
||||
test="screen reader"
|
||||
|
||||
Reference in new issue
Block a user