Skip to content

Commit d553c31

Browse files
fabriziocuccimeta-codesync[bot]
authored andcommitted
Reset clickable in prepareToRecycleView (#54627)
Summary: Pull Request resolved: #54627 Changelog: [Android][Fixed] - Reset isClickable when recycling views to prevent accessibility tools from detecting incorrect state ### Internal In D87430057, we have mixed two changes: 1. setting `isClickabe=true` for all views 2. resetting `isClickable` when recycling the view Since `1` is a major change and will require a bit more testing, here we are splitting the changes so that we can start flipping the flag for `2`. Reviewed By: javache, cipolleschi Differential Revision: D87637737 fbshipit-source-id: 55ef070c0ab384f4d03e717e179037b1c0df9690
1 parent a210409 commit d553c31

21 files changed

+159
-43
lines changed

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<87d3308992d9f10b714b3b8c53da6b1b>>
7+
* @generated SignedSource<<1c742f07be860af7f36041b1ae8d681c>>
88
*/
99

1010
/**
@@ -450,6 +450,12 @@ public object ReactNativeFeatureFlags {
450450
@JvmStatic
451451
public fun shouldPressibilityUseW3CPointerEventsForHover(): Boolean = accessor.shouldPressibilityUseW3CPointerEventsForHover()
452452

453+
/**
454+
* Reset isClickable to false when recycling views on Android to avoid accessibility tools finding views with incorrect state after recycling.
455+
*/
456+
@JvmStatic
457+
public fun shouldResetClickableWhenRecyclingView(): Boolean = accessor.shouldResetClickableWhenRecyclingView()
458+
453459
/**
454460
* Reset OnClickListener to null when recycling views on Android to avoid accessibility tools finding views with incorrect state after recycling.
455461
*/

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<b5efd0c0e73a02a3016733d6d49b981d>>
7+
* @generated SignedSource<<907a488c5b01ea5adc57a6895fbaffb8>>
88
*/
99

1010
/**
@@ -90,6 +90,7 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
9090
private var preparedTextCacheSizeCache: Double? = null
9191
private var preventShadowTreeCommitExhaustionCache: Boolean? = null
9292
private var shouldPressibilityUseW3CPointerEventsForHoverCache: Boolean? = null
93+
private var shouldResetClickableWhenRecyclingViewCache: Boolean? = null
9394
private var shouldResetOnClickListenerWhenRecyclingViewCache: Boolean? = null
9495
private var shouldSetEnabledBasedOnAccessibilityStateCache: Boolean? = null
9596
private var shouldSetIsClickableByDefaultCache: Boolean? = null
@@ -742,6 +743,15 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
742743
return cached
743744
}
744745

746+
override fun shouldResetClickableWhenRecyclingView(): Boolean {
747+
var cached = shouldResetClickableWhenRecyclingViewCache
748+
if (cached == null) {
749+
cached = ReactNativeFeatureFlagsCxxInterop.shouldResetClickableWhenRecyclingView()
750+
shouldResetClickableWhenRecyclingViewCache = cached
751+
}
752+
return cached
753+
}
754+
745755
override fun shouldResetOnClickListenerWhenRecyclingView(): Boolean {
746756
var cached = shouldResetOnClickListenerWhenRecyclingViewCache
747757
if (cached == null) {

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<e4603ced557b3baeb7a88f270678a437>>
7+
* @generated SignedSource<<f12380025ab4582128d5aff4ad0fc9cc>>
88
*/
99

1010
/**
@@ -168,6 +168,8 @@ public object ReactNativeFeatureFlagsCxxInterop {
168168

169169
@DoNotStrip @JvmStatic public external fun shouldPressibilityUseW3CPointerEventsForHover(): Boolean
170170

171+
@DoNotStrip @JvmStatic public external fun shouldResetClickableWhenRecyclingView(): Boolean
172+
171173
@DoNotStrip @JvmStatic public external fun shouldResetOnClickListenerWhenRecyclingView(): Boolean
172174

173175
@DoNotStrip @JvmStatic public external fun shouldSetEnabledBasedOnAccessibilityState(): Boolean

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<50435a85758921672f7c05c6ac6790f9>>
7+
* @generated SignedSource<<cfdeb7b6ddf02d0eebd04d6fe55d4775>>
88
*/
99

1010
/**
@@ -163,6 +163,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi
163163

164164
override fun shouldPressibilityUseW3CPointerEventsForHover(): Boolean = false
165165

166+
override fun shouldResetClickableWhenRecyclingView(): Boolean = false
167+
166168
override fun shouldResetOnClickListenerWhenRecyclingView(): Boolean = false
167169

168170
override fun shouldSetEnabledBasedOnAccessibilityState(): Boolean = true

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<aedd122d17339b8c2acf189c1bb00f4d>>
7+
* @generated SignedSource<<a6f4d72d3d59d909b09b3e0d00bed611>>
88
*/
99

1010
/**
@@ -94,6 +94,7 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
9494
private var preparedTextCacheSizeCache: Double? = null
9595
private var preventShadowTreeCommitExhaustionCache: Boolean? = null
9696
private var shouldPressibilityUseW3CPointerEventsForHoverCache: Boolean? = null
97+
private var shouldResetClickableWhenRecyclingViewCache: Boolean? = null
9798
private var shouldResetOnClickListenerWhenRecyclingViewCache: Boolean? = null
9899
private var shouldSetEnabledBasedOnAccessibilityStateCache: Boolean? = null
99100
private var shouldSetIsClickableByDefaultCache: Boolean? = null
@@ -816,6 +817,16 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
816817
return cached
817818
}
818819

820+
override fun shouldResetClickableWhenRecyclingView(): Boolean {
821+
var cached = shouldResetClickableWhenRecyclingViewCache
822+
if (cached == null) {
823+
cached = currentProvider.shouldResetClickableWhenRecyclingView()
824+
accessedFeatureFlags.add("shouldResetClickableWhenRecyclingView")
825+
shouldResetClickableWhenRecyclingViewCache = cached
826+
}
827+
return cached
828+
}
829+
819830
override fun shouldResetOnClickListenerWhenRecyclingView(): Boolean {
820831
var cached = shouldResetOnClickListenerWhenRecyclingViewCache
821832
if (cached == null) {

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<f09b47e1200d3164ee5f495ef991d6cf>>
7+
* @generated SignedSource<<ce03b5f4dd0903582cfb90fe45d9177e>>
88
*/
99

1010
/**
@@ -163,6 +163,8 @@ public interface ReactNativeFeatureFlagsProvider {
163163

164164
@DoNotStrip public fun shouldPressibilityUseW3CPointerEventsForHover(): Boolean
165165

166+
@DoNotStrip public fun shouldResetClickableWhenRecyclingView(): Boolean
167+
166168
@DoNotStrip public fun shouldResetOnClickListenerWhenRecyclingView(): Boolean
167169

168170
@DoNotStrip public fun shouldSetEnabledBasedOnAccessibilityState(): Boolean

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManager.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,8 @@ public BaseViewManager(@Nullable ReactApplicationContext reactContext) {
149149
// https://android.googlesource.com/platform/frameworks/base/+/a175a5b/core/java/android/view/View.java#2712
150150
// `mViewFlags = SOUND_EFFECTS_ENABLED | HAPTIC_FEEDBACK_ENABLED | LAYOUT_DIRECTION_INHERIT`
151151
// Therefore we set the following options as such:
152-
if (ReactNativeFeatureFlags.shouldSetIsClickableByDefault()) {
153-
view.setClickable(true);
152+
if (ReactNativeFeatureFlags.shouldResetClickableWhenRecyclingView()) {
153+
view.setClickable(ReactNativeFeatureFlags.shouldSetIsClickableByDefault());
154154
}
155155
if (ReactNativeFeatureFlags.shouldResetOnClickListenerWhenRecyclingView()) {
156156
view.setOnClickListener(null);

packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<d30f5ffcbec1c5175623573fdbd0be87>>
7+
* @generated SignedSource<<e3040fc39c8b9a47fe9809fac48f9f32>>
88
*/
99

1010
/**
@@ -459,6 +459,12 @@ class ReactNativeFeatureFlagsJavaProvider
459459
return method(javaProvider_);
460460
}
461461

462+
bool shouldResetClickableWhenRecyclingView() override {
463+
static const auto method =
464+
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("shouldResetClickableWhenRecyclingView");
465+
return method(javaProvider_);
466+
}
467+
462468
bool shouldResetOnClickListenerWhenRecyclingView() override {
463469
static const auto method =
464470
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("shouldResetOnClickListenerWhenRecyclingView");
@@ -939,6 +945,11 @@ bool JReactNativeFeatureFlagsCxxInterop::shouldPressibilityUseW3CPointerEventsFo
939945
return ReactNativeFeatureFlags::shouldPressibilityUseW3CPointerEventsForHover();
940946
}
941947

948+
bool JReactNativeFeatureFlagsCxxInterop::shouldResetClickableWhenRecyclingView(
949+
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
950+
return ReactNativeFeatureFlags::shouldResetClickableWhenRecyclingView();
951+
}
952+
942953
bool JReactNativeFeatureFlagsCxxInterop::shouldResetOnClickListenerWhenRecyclingView(
943954
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
944955
return ReactNativeFeatureFlags::shouldResetOnClickListenerWhenRecyclingView();
@@ -1285,6 +1296,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() {
12851296
makeNativeMethod(
12861297
"shouldPressibilityUseW3CPointerEventsForHover",
12871298
JReactNativeFeatureFlagsCxxInterop::shouldPressibilityUseW3CPointerEventsForHover),
1299+
makeNativeMethod(
1300+
"shouldResetClickableWhenRecyclingView",
1301+
JReactNativeFeatureFlagsCxxInterop::shouldResetClickableWhenRecyclingView),
12881302
makeNativeMethod(
12891303
"shouldResetOnClickListenerWhenRecyclingView",
12901304
JReactNativeFeatureFlagsCxxInterop::shouldResetOnClickListenerWhenRecyclingView),

packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<4fac1a3773ded6bb80528aab5662ca96>>
7+
* @generated SignedSource<<7f3e9f6c4417bb9cd83f81763be7e9be>>
88
*/
99

1010
/**
@@ -240,6 +240,9 @@ class JReactNativeFeatureFlagsCxxInterop
240240
static bool shouldPressibilityUseW3CPointerEventsForHover(
241241
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
242242

243+
static bool shouldResetClickableWhenRecyclingView(
244+
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
245+
243246
static bool shouldResetOnClickListenerWhenRecyclingView(
244247
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
245248

packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<d3573c8b6251753cc68d82cff6c4855e>>
7+
* @generated SignedSource<<642bad37eb5b2fa363c9364dff7774af>>
88
*/
99

1010
/**
@@ -306,6 +306,10 @@ bool ReactNativeFeatureFlags::shouldPressibilityUseW3CPointerEventsForHover() {
306306
return getAccessor().shouldPressibilityUseW3CPointerEventsForHover();
307307
}
308308

309+
bool ReactNativeFeatureFlags::shouldResetClickableWhenRecyclingView() {
310+
return getAccessor().shouldResetClickableWhenRecyclingView();
311+
}
312+
309313
bool ReactNativeFeatureFlags::shouldResetOnClickListenerWhenRecyclingView() {
310314
return getAccessor().shouldResetOnClickListenerWhenRecyclingView();
311315
}

0 commit comments

Comments
 (0)