Skip to content

Commit

Permalink
[Android] Add isInvertColorsEnabled accessibility info
Browse files Browse the repository at this point in the history
  • Loading branch information
MSzalowski committed May 26, 2021
1 parent 1fe5cac commit 46e8a13
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@ import {type ElementRef} from 'react';

const REDUCE_MOTION_EVENT = 'reduceMotionDidChange';
const TOUCH_EXPLORATION_EVENT = 'touchExplorationDidChange';
const INVERT_COLORS_EVENT = 'invertColorsDidChange;';

type AccessibilityEventDefinitions = {
reduceMotionChanged: [boolean],
screenReaderChanged: [boolean],
invertColorsChanged: [boolean],
// alias for screenReaderChanged
change: [boolean],
};
Expand Down Expand Up @@ -55,11 +57,14 @@ const AccessibilityInfo = {
return Promise.resolve(false);
},

/**
* iOS only
*/
isInvertColorsEnabled: function(): Promise<boolean> {
return Promise.resolve(false);
return new Promise((resolve, reject) => {
if (NativeAccessibilityInfo) {
NativeAccessibilityInfo.isInvertColorsEnabled(resolve);
} else {
reject(false);
}
});
},

isReduceMotionEnabled: function(): Promise<boolean> {
Expand Down Expand Up @@ -118,6 +123,11 @@ const AccessibilityInfo = {
REDUCE_MOTION_EVENT,
handler,
);
} else if (eventName === 'invertColorsChanged') {
listener = RCTDeviceEventEmitter.addListener(
INVERT_COLORS_EVENT,
handler,
);
}

// $FlowFixMe[escaped-generic]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ export interface Spec extends TurboModule {
+isReduceMotionEnabled: (
onSuccess: (isReduceMotionEnabled: boolean) => void,
) => void;
+isInvertColorsEnabled: (
onSuccess: (isInvertColorsEnabled: boolean) => void,
) => void;
+isTouchExplorationEnabled: (
onSuccess: (isScreenReaderEnabled: boolean) => void,
) => void;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,32 @@ public void onChange(boolean selfChange, Uri uri) {
}
};

// Listener that is notified when the secure ACCESSIBILITY_DISPLAY_INVERSION_ENABLED.
private final ContentObserver accessibilityDisplayInversionObserver =
new ContentObserver(new Handler(Looper.getMainLooper())) {
@Override
public void onChange(boolean selfChange) {
this.onChange(selfChange, null);
}

@Override
public void onChange(boolean selfChange, Uri uri) {
if (getReactApplicationContext().hasActiveCatalystInstance()) {
AccessibilityInfoModule.this.updateAndSendInvertColorsChangeEvent();
}
}
};

private @Nullable AccessibilityManager mAccessibilityManager;
private @Nullable ReactTouchExplorationStateChangeListener mTouchExplorationStateChangeListener;
private final ContentResolver mContentResolver;
private boolean mReduceMotionEnabled = false;
private boolean mTouchExplorationEnabled = false;
private boolean mInvertColorsEnabled = false;

private static final String REDUCE_MOTION_EVENT_NAME = "reduceMotionDidChange";
private static final String TOUCH_EXPLORATION_EVENT_NAME = "touchExplorationDidChange";
private static final String INVERT_COLORS_EVENT_NAME = "invertColorsDidChange";

public AccessibilityInfoModule(ReactApplicationContext context) {
super(context);
Expand All @@ -79,6 +97,7 @@ public AccessibilityInfoModule(ReactApplicationContext context) {
mContentResolver = getReactApplicationContext().getContentResolver();
mTouchExplorationEnabled = mAccessibilityManager.isTouchExplorationEnabled();
mReduceMotionEnabled = this.getIsReduceMotionEnabledValue();
mInvertColorsEnabled = this.getIsInvertColorsEnabled();
mTouchExplorationStateChangeListener = new ReactTouchExplorationStateChangeListener();
}

Expand All @@ -95,6 +114,15 @@ private boolean getIsReduceMotionEnabledValue() {
return value != null && value.equals("0.0");
}

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private boolean getIsInvertColorsEnabled() {
String value =
Settings.Secure.getString(
mContentResolver, Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED);

return value != null && value.equals("1");
}

@Override
public void isReduceMotionEnabled(Callback successCallback) {
successCallback.invoke(mReduceMotionEnabled);
Expand All @@ -105,6 +133,11 @@ public void isTouchExplorationEnabled(Callback successCallback) {
successCallback.invoke(mTouchExplorationEnabled);
}

@Override
public void isInvertColorsEnabled(Callback successCallback) {
successCallback.invoke(mInvertColorsEnabled);
}

private void updateAndSendReduceMotionChangeEvent() {
boolean isReduceMotionEnabled = this.getIsReduceMotionEnabledValue();

Expand Down Expand Up @@ -133,17 +166,35 @@ private void updateAndSendTouchExplorationChangeEvent(boolean enabled) {
}
}

private void updateAndSendInvertColorsChangeEvent() {
boolean isInvertColorsEnabled = this.getIsInvertColorsEnabled();

if (mInvertColorsEnabled != isInvertColorsEnabled) {
mInvertColorsEnabled = isInvertColorsEnabled;

ReactApplicationContext reactApplicationContext = getReactApplicationContextIfActiveOrWarn();
if (reactApplicationContext != null) {
reactApplicationContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(INVERT_COLORS_EVENT_NAME, mInvertColorsEnabled);
}
}
}

@Override
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public void onHostResume() {
mAccessibilityManager.addTouchExplorationStateChangeListener(
mTouchExplorationStateChangeListener);

Uri transitionUri = Settings.Global.getUriFor(Settings.Global.TRANSITION_ANIMATION_SCALE);
Uri invertColorsUri = Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED);
mContentResolver.registerContentObserver(transitionUri, false, animationScaleObserver);
mContentResolver.registerContentObserver(invertColorsUri, false, accessibilityDisplayInversionObserver);

updateAndSendTouchExplorationChangeEvent(mAccessibilityManager.isTouchExplorationEnabled());
updateAndSendReduceMotionChangeEvent();
updateAndSendInvertColorsChangeEvent();
}

@Override
Expand All @@ -153,13 +204,15 @@ public void onHostPause() {
mTouchExplorationStateChangeListener);

mContentResolver.unregisterContentObserver(animationScaleObserver);
mContentResolver.unregisterContentObserver(accessibilityDisplayInversionObserver);
}

@Override
public void initialize() {
getReactApplicationContext().addLifecycleEventListener(this);
updateAndSendTouchExplorationChangeEvent(mAccessibilityManager.isTouchExplorationEnabled());
updateAndSendReduceMotionChangeEvent();
updateAndSendInvertColorsChangeEvent();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -761,12 +761,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"
Expand All @@ -789,6 +783,13 @@ class EnabledExamples extends React.Component<{}> {
eventListener="screenReaderChanged"
/>
</RNTesterBlock>

<RNTesterBlock title="isInvertColorsEnabled()">
<EnabledExample
test="invert colors"
eventListener="invertColorsChanged"
/>
</RNTesterBlock>
</View>
);
}
Expand Down

0 comments on commit 46e8a13

Please sign in to comment.