From 817db84c6b58d35af207d4f93368dceeceb328d1 Mon Sep 17 00:00:00 2001 From: David Vacca Date: Thu, 30 Mar 2023 20:06:20 -0700 Subject: [PATCH] Refactor creation of SendAccessibilityEventMountItem (#36607) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/36607 In this I'm refactoring the creation of SendAccessibilityEventMountItem to reduce visibility of classes Changelog: [Internal] Internal Reviewed By: javache Differential Revision: D44115052 fbshipit-source-id: 021f59a65aed152324a13947609e23c0191ca0e8 --- .../react/fabric/FabricUIManager.java | 7 ++- .../DispatchIntCommandMountItem.java | 3 +- .../DispatchStringCommandMountItem.java | 3 +- .../mounting/mountitems/MountItemFactory.java | 6 ++ .../SendAccessibilityEventMountItem.java | 55 +++++++++++++++++++ 5 files changed, 69 insertions(+), 5 deletions(-) create mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/SendAccessibilityEventMountItem.java diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java index f35195b5b5b..dd2a91f0478 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java @@ -63,7 +63,6 @@ import com.facebook.react.fabric.mounting.mountitems.IntBufferBatchMountItem; import com.facebook.react.fabric.mounting.mountitems.MountItem; import com.facebook.react.fabric.mounting.mountitems.MountItemFactory; import com.facebook.react.fabric.mounting.mountitems.PreAllocateViewMountItem; -import com.facebook.react.fabric.mounting.mountitems.SendAccessibilityEvent; import com.facebook.react.modules.core.ReactChoreographer; import com.facebook.react.modules.i18nmanager.I18nUtil; import com.facebook.react.uimanager.IllegalViewOperationException; @@ -1042,7 +1041,8 @@ public class FabricUIManager implements UIManager, LifecycleEventListener { public void sendAccessibilityEvent(int reactTag, int eventType) { // Can be called from native, not just JS - we need to migrate the native callsites // before removing this entirely. - mMountItemDispatcher.addMountItem(new SendAccessibilityEvent(View.NO_ID, reactTag, eventType)); + mMountItemDispatcher.addMountItem( + MountItemFactory.createSendAccessibilityEventMountItem(View.NO_ID, reactTag, eventType)); } @AnyThread @@ -1061,7 +1061,8 @@ public class FabricUIManager implements UIManager, LifecycleEventListener { throw new IllegalArgumentException( "sendAccessibilityEventFromJS: invalid eventType " + eventTypeJS); } - mMountItemDispatcher.addMountItem(new SendAccessibilityEvent(surfaceId, reactTag, eventType)); + mMountItemDispatcher.addMountItem( + MountItemFactory.createSendAccessibilityEventMountItem(surfaceId, reactTag, eventType)); } /** diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/DispatchIntCommandMountItem.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/DispatchIntCommandMountItem.java index c9cc25db8cd..23bae74ef15 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/DispatchIntCommandMountItem.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/DispatchIntCommandMountItem.java @@ -19,7 +19,7 @@ class DispatchIntCommandMountItem extends DispatchCommandMountItem { private final int mCommandId; private final @Nullable ReadableArray mCommandArgs; - public DispatchIntCommandMountItem( + DispatchIntCommandMountItem( int surfaceId, int reactTag, int commandId, @Nullable ReadableArray commandArgs) { mSurfaceId = surfaceId; mReactTag = reactTag; @@ -38,6 +38,7 @@ class DispatchIntCommandMountItem extends DispatchCommandMountItem { } @Override + @NonNull public String toString() { return "DispatchIntCommandMountItem [" + mReactTag + "] " + mCommandId; } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/DispatchStringCommandMountItem.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/DispatchStringCommandMountItem.java index b72c9ab24b1..b686935cfbc 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/DispatchStringCommandMountItem.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/DispatchStringCommandMountItem.java @@ -19,7 +19,7 @@ class DispatchStringCommandMountItem extends DispatchCommandMountItem { private final @NonNull String mCommandId; private final @Nullable ReadableArray mCommandArgs; - public DispatchStringCommandMountItem( + DispatchStringCommandMountItem( int surfaceId, int reactTag, @NonNull String commandId, @Nullable ReadableArray commandArgs) { mSurfaceId = surfaceId; mReactTag = reactTag; @@ -38,6 +38,7 @@ class DispatchStringCommandMountItem extends DispatchCommandMountItem { } @Override + @NonNull public String toString() { return "DispatchStringCommandMountItem [" + mReactTag + "] " + mCommandId; } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/MountItemFactory.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/MountItemFactory.java index cf2e8b96c27..98c868750a6 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/MountItemFactory.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/MountItemFactory.java @@ -25,4 +25,10 @@ public class MountItemFactory { int surfaceId, int reactTag, @NonNull String commandId, @Nullable ReadableArray commandArgs) { return new DispatchStringCommandMountItem(surfaceId, reactTag, commandId, commandArgs); } + + /** @return a {@link MountItem} that will control the execution of an AccessibilityEvent */ + public static MountItem createSendAccessibilityEventMountItem( + int surfaceId, int reactTag, int eventType) { + return new SendAccessibilityEventMountItem(surfaceId, reactTag, eventType); + } } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/SendAccessibilityEventMountItem.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/SendAccessibilityEventMountItem.java new file mode 100644 index 00000000000..8ed05f8e6f8 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/SendAccessibilityEventMountItem.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +package com.facebook.react.fabric.mounting.mountitems; + +import androidx.annotation.NonNull; +import com.facebook.react.bridge.ReactSoftExceptionLogger; +import com.facebook.react.bridge.RetryableMountingLayerException; +import com.facebook.react.fabric.mounting.MountingManager; + +class SendAccessibilityEventMountItem implements MountItem { + + private final String TAG = "Fabric.SendAccessibilityEvent"; + + private final int mSurfaceId; + private final int mReactTag; + private final int mEventType; + + SendAccessibilityEventMountItem(int surfaceId, int reactTag, int eventType) { + mSurfaceId = surfaceId; + mReactTag = reactTag; + mEventType = eventType; + } + + @Override + public void execute(@NonNull MountingManager mountingManager) { + try { + mountingManager.sendAccessibilityEvent(mSurfaceId, mReactTag, mEventType); + } catch (RetryableMountingLayerException e) { + // Accessibility events are similar to commands in that they're imperative + // calls from JS, disconnected from the commit lifecycle, and therefore + // inherently unpredictable and dangerous. If we encounter a "retryable" + // error, that is, a known category of errors that this is likely to hit + // due to race conditions (like the view disappearing after the event is + // queued and before it executes), we log a soft exception and continue along. + // Other categories of errors will still cause a hard crash. + ReactSoftExceptionLogger.logSoftException(TAG, e); + } + } + + @Override + public int getSurfaceId() { + return mSurfaceId; + } + + @Override + @NonNull + public String toString() { + return "SendAccessibilityEventMountItem [" + mReactTag + "] " + mEventType; + } +}