Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import com.facebook.react.fabric.events.EventEmitterWrapper;
import com.facebook.react.fabric.mounting.MountingManager.MountItemExecutor;
import com.facebook.react.fabric.mounting.mountitems.MountItem;
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags;
import com.facebook.react.modules.core.ReactChoreographer;
import com.facebook.react.touch.JSResponderHandler;
import com.facebook.react.uimanager.IViewGroupManager;
Expand All @@ -49,6 +50,7 @@
import com.facebook.react.uimanager.ViewManager;
import com.facebook.react.uimanager.ViewManagerRegistry;
import com.facebook.react.uimanager.events.EventCategoryDef;
import com.facebook.react.views.view.ReactViewGroup;
import com.facebook.react.views.view.ReactViewManagerWrapper;
import java.util.ArrayDeque;
import java.util.HashSet;
Expand Down Expand Up @@ -387,8 +389,25 @@ public void addViewAt(final int parentTag, final int tag, final int index) {
// should be impossible - we mark this as a "readded" View and
// thus prevent the RemoveDeleteTree worker from deleting this
// View in the future.
if (viewParent instanceof ViewGroup) {
((ViewGroup) viewParent).removeView(view);
if (ReactNativeFeatureFlags.enableFixForClippedSubviewsCrash()) {
if (viewParent instanceof ReactViewGroup) {
ReactViewGroup viewParentGroup = (ReactViewGroup) viewParent;
// If the parent group has subview clipping enabled, we need to use the specialized
// method.
// Otherwise, ReactViewGroup's member variables managing subview clipping
// will get out of sync with Android's view hierarchy, leading to a crash.
if (viewParentGroup.getRemoveClippedSubviews()) {
viewParentGroup.removeViewWithSubviewClippingEnabled(view);
} else {
viewParentGroup.removeView(view);
}
} else if (viewParent instanceof ViewGroup) {
((ViewGroup) viewParent).removeView(view);
}
} else {
if (viewParent instanceof ViewGroup) {
((ViewGroup) viewParent).removeView(view);
}
}
mErroneouslyReaddedReactTags.add(tag);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<fccbff20f478efc0778ed7991065d189>>
* @generated SignedSource<<f4268973a38ba972e68474cc31bab5a7>>
*/

/**
Expand Down Expand Up @@ -64,6 +64,12 @@ object ReactNativeFeatureFlags {
@JvmStatic
fun enableCustomDrawOrderFabric() = accessor.enableCustomDrawOrderFabric()

/**
* Attempt at fixing a crash related to subview clipping on Android. This is a kill switch for the fix
*/
@JvmStatic
fun enableFixForClippedSubviewsCrash() = accessor.enableFixForClippedSubviewsCrash()

/**
* Overrides the feature flags with the ones provided by the given provider
* (generally one that extends `ReactNativeFeatureFlagsDefaults`).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<126de7eafa27c27df31d9d4e984ab96c>>
* @generated SignedSource<<5b653e8a53f557ffc0f46b3e81e99bed>>
*/

/**
Expand All @@ -26,6 +26,7 @@ class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccessor {
private var batchRenderingUpdatesInEventLoopCache: Boolean? = null
private var enableSpannableBuildingUnificationCache: Boolean? = null
private var enableCustomDrawOrderFabricCache: Boolean? = null
private var enableFixForClippedSubviewsCrashCache: Boolean? = null

override fun commonTestFlag(): Boolean {
var cached = commonTestFlagCache
Expand Down Expand Up @@ -81,6 +82,15 @@ class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccessor {
return cached
}

override fun enableFixForClippedSubviewsCrash(): Boolean {
var cached = enableFixForClippedSubviewsCrashCache
if (cached == null) {
cached = ReactNativeFeatureFlagsCxxInterop.enableFixForClippedSubviewsCrash()
enableFixForClippedSubviewsCrashCache = cached
}
return cached
}

override fun override(provider: ReactNativeFeatureFlagsProvider) =
ReactNativeFeatureFlagsCxxInterop.override(provider as Any)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<9638eb154fe6e488aebcf20c462f498e>>
* @generated SignedSource<<47be3dbe5558f720a6c61742f2c63bf8>>
*/

/**
Expand Down Expand Up @@ -40,6 +40,8 @@ object ReactNativeFeatureFlagsCxxInterop {

@DoNotStrip @JvmStatic external fun enableCustomDrawOrderFabric(): Boolean

@DoNotStrip @JvmStatic external fun enableFixForClippedSubviewsCrash(): Boolean

@DoNotStrip @JvmStatic external fun override(provider: Any)

@DoNotStrip @JvmStatic external fun dangerouslyReset()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<53537c2dcc2f4e298822eaa92b5c507f>>
* @generated SignedSource<<70c19d5bb1e0c09f52b89b4bb3645b9d>>
*/

/**
Expand Down Expand Up @@ -34,4 +34,6 @@ open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvider {
override fun enableSpannableBuildingUnification(): Boolean = false

override fun enableCustomDrawOrderFabric(): Boolean = false

override fun enableFixForClippedSubviewsCrash(): Boolean = false
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<9ea3b9587aa49be565b990b4c2f4a870>>
* @generated SignedSource<<7ba0cb94c10989838250252fa06768a0>>
*/

/**
Expand All @@ -30,6 +30,7 @@ class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAccessor {
private var batchRenderingUpdatesInEventLoopCache: Boolean? = null
private var enableSpannableBuildingUnificationCache: Boolean? = null
private var enableCustomDrawOrderFabricCache: Boolean? = null
private var enableFixForClippedSubviewsCrashCache: Boolean? = null

override fun commonTestFlag(): Boolean {
var cached = commonTestFlagCache
Expand Down Expand Up @@ -91,6 +92,16 @@ class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAccessor {
return cached
}

override fun enableFixForClippedSubviewsCrash(): Boolean {
var cached = enableFixForClippedSubviewsCrashCache
if (cached == null) {
cached = currentProvider.enableFixForClippedSubviewsCrash()
accessedFeatureFlags.add("enableFixForClippedSubviewsCrash")
enableFixForClippedSubviewsCrashCache = cached
}
return cached
}

override fun override(provider: ReactNativeFeatureFlagsProvider) {
if (accessedFeatureFlags.isNotEmpty()) {
val accessedFeatureFlagsStr = accessedFeatureFlags.joinToString(separator = ", ") { it }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<9abdc5010330b660feded87e9db882c4>>
* @generated SignedSource<<b0f60718eedab65390ebfb7864a10a27>>
*/

/**
Expand Down Expand Up @@ -34,4 +34,6 @@ interface ReactNativeFeatureFlagsProvider {
@DoNotStrip fun enableSpannableBuildingUnification(): Boolean

@DoNotStrip fun enableCustomDrawOrderFabric(): Boolean

@DoNotStrip fun enableFixForClippedSubviewsCrash(): Boolean
}
Original file line number Diff line number Diff line change
Expand Up @@ -686,7 +686,8 @@ public void run() {
}
}

/*package*/ void removeViewWithSubviewClippingEnabled(View view) {
// TODO: make this method package only once we remove Android's mounting layer retry mechanism.
public void removeViewWithSubviewClippingEnabled(View view) {
UiThreadUtil.assertOnUiThread();

Assertions.assertCondition(mRemoveClippedSubviews);
Expand Down Expand Up @@ -754,7 +755,6 @@ private void addInArray(View child, int index) {
}
}

// This method also sets the child's mParent to null
private void removeFromArray(int index) {
final View[] children = Assertions.assertNotNull(mAllChildren);
final int count = mAllChildrenCount;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<1ba33b527792e241891e821b18b11000>>
* @generated SignedSource<<dab6daf99192f983b7c8ad7633b43a33>>
*/

/**
Expand Down Expand Up @@ -53,6 +53,11 @@ bool JReactNativeFeatureFlagsCxxInterop::enableCustomDrawOrderFabric(
return ReactNativeFeatureFlags::enableCustomDrawOrderFabric();
}

bool JReactNativeFeatureFlagsCxxInterop::enableFixForClippedSubviewsCrash(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
return ReactNativeFeatureFlags::enableFixForClippedSubviewsCrash();
}

void JReactNativeFeatureFlagsCxxInterop::override(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/,
jni::alias_ref<jobject> provider) {
Expand Down Expand Up @@ -88,6 +93,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() {
makeNativeMethod(
"enableCustomDrawOrderFabric",
JReactNativeFeatureFlagsCxxInterop::enableCustomDrawOrderFabric),
makeNativeMethod(
"enableFixForClippedSubviewsCrash",
JReactNativeFeatureFlagsCxxInterop::enableFixForClippedSubviewsCrash),
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<c1e65591af5042353647d3afb4e181b4>>
* @generated SignedSource<<c2a4da926b870497f76c03c8f97199e2>>
*/

/**
Expand Down Expand Up @@ -48,6 +48,9 @@ class JReactNativeFeatureFlagsCxxInterop
static bool enableCustomDrawOrderFabric(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);

static bool enableFixForClippedSubviewsCrash(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);

static void override(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>,
jni::alias_ref<jobject> provider);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<47d7a81b555e133f79db174f599a1940>>
* @generated SignedSource<<feb0342515d10b3519675cd91efa65dc>>
*/

/**
Expand Down Expand Up @@ -63,4 +63,10 @@ bool ReactNativeFeatureFlagsProviderHolder::enableCustomDrawOrderFabric() {
return method(javaProvider_);
}

bool ReactNativeFeatureFlagsProviderHolder::enableFixForClippedSubviewsCrash() {
static const auto method =
getJClass()->getMethod<jboolean()>("enableFixForClippedSubviewsCrash");
return method(javaProvider_);
}

} // namespace facebook::react
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<228921c4374aa45bdcd496f0f10d653a>>
* @generated SignedSource<<879b0c096c4a2e9692a5e133bdfd8809>>
*/

/**
Expand Down Expand Up @@ -41,6 +41,7 @@ class ReactNativeFeatureFlagsProviderHolder
bool batchRenderingUpdatesInEventLoop() override;
bool enableSpannableBuildingUnification() override;
bool enableCustomDrawOrderFabric() override;
bool enableFixForClippedSubviewsCrash() override;

private:
jni::global_ref<jobject> javaProvider_;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<a9ddd8a35e80c21c36fd57526a58ae84>>
* @generated SignedSource<<6ccf42209dea35cd5c6ac9eb882c2ef7>>
*/

/**
Expand Down Expand Up @@ -45,6 +45,10 @@ bool ReactNativeFeatureFlags::enableCustomDrawOrderFabric() {
return getAccessor().enableCustomDrawOrderFabric();
}

bool ReactNativeFeatureFlags::enableFixForClippedSubviewsCrash() {
return getAccessor().enableFixForClippedSubviewsCrash();
}

void ReactNativeFeatureFlags::override(
std::unique_ptr<ReactNativeFeatureFlagsProvider> provider) {
getAccessor().override(std::move(provider));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<479f3a75128ee7e9ea60af544b69e0d7>>
* @generated SignedSource<<d3e8b0cc31fd8e44c3f83d836485e6f6>>
*/

/**
Expand Down Expand Up @@ -62,6 +62,11 @@ class ReactNativeFeatureFlags {
*/
static bool enableCustomDrawOrderFabric();

/**
* Attempt at fixing a crash related to subview clipping on Android. This is a kill switch for the fix
*/
static bool enableFixForClippedSubviewsCrash();

/**
* Overrides the feature flags with the ones provided by the given provider
* (generally one that extends `ReactNativeFeatureFlagsDefaults`).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<dc95df7a5e58ca72e19a77e4d190225e>>
* @generated SignedSource<<7d50752c48503e31eccfe64d66ee2e99>>
*/

/**
Expand Down Expand Up @@ -130,6 +130,23 @@ bool ReactNativeFeatureFlagsAccessor::enableCustomDrawOrderFabric() {
return enableCustomDrawOrderFabric_.value();
}

bool ReactNativeFeatureFlagsAccessor::enableFixForClippedSubviewsCrash() {
if (!enableFixForClippedSubviewsCrash_.has_value()) {
// Mark the flag as accessed.
static const char* flagName = "enableFixForClippedSubviewsCrash";
if (std::find(
accessedFeatureFlags_.begin(),
accessedFeatureFlags_.end(),
flagName) == accessedFeatureFlags_.end()) {
accessedFeatureFlags_.push_back(flagName);
}

enableFixForClippedSubviewsCrash_.emplace(currentProvider_->enableFixForClippedSubviewsCrash());
}

return enableFixForClippedSubviewsCrash_.value();
}

void ReactNativeFeatureFlagsAccessor::override(
std::unique_ptr<ReactNativeFeatureFlagsProvider> provider) {
if (!accessedFeatureFlags_.empty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<f85ebb4efba429a4c943dc26e5a70541>>
* @generated SignedSource<<1514c04fb9d175308e106b84a14bc89d>>
*/

/**
Expand Down Expand Up @@ -36,6 +36,7 @@ class ReactNativeFeatureFlagsAccessor {
bool batchRenderingUpdatesInEventLoop();
bool enableSpannableBuildingUnification();
bool enableCustomDrawOrderFabric();
bool enableFixForClippedSubviewsCrash();

void override(std::unique_ptr<ReactNativeFeatureFlagsProvider> provider);

Expand All @@ -49,6 +50,7 @@ class ReactNativeFeatureFlagsAccessor {
std::optional<bool> batchRenderingUpdatesInEventLoop_;
std::optional<bool> enableSpannableBuildingUnification_;
std::optional<bool> enableCustomDrawOrderFabric_;
std::optional<bool> enableFixForClippedSubviewsCrash_;
};

} // namespace facebook::react
Loading