Skip to content
Merged
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 @@ -23,8 +23,8 @@ Size measureHostComponent(
return {};
}

const auto fabricUIManager =
contextContainer->at<jni::global_ref<jobject>>("FabricUIManager");
auto fabricUIManager =
contextContainer->at<jni::alias_ref<jobject>>("FabricUIManager");
static const auto measure =
jni::findClassStatic("com/facebook/react/fabric/FabricUIManager")
->getMethod<jlong(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -609,7 +609,12 @@ void FabricUIManagerBinding::installFabricUIManager(
globalJavaUiManager);
};

contextContainer->insert("FabricUIManager", globalJavaUiManager);
auto fabricUIManagerOwner =
std::make_shared<jni::global_ref<jobject>>(globalJavaUiManager);
// The alias and its owner must stay registered for the container's lifetime.
contextContainer->insert("FabricUIManagerOwner", fabricUIManagerOwner);
contextContainer->insert(
"FabricUIManager", jni::alias_ref<jobject>(*fabricUIManagerOwner));

animationChoreographer_ = std::make_shared<AndroidAnimationChoreographer>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,63 @@ std::vector<Tag> toTags(jni::alias_ref<jni::JArrayInt> tags) {
return {region.get(), region.get() + tags->size()};
}

bool fabricUIManagerAliasUsesOwnedHandle(
[[maybe_unused]] jni::alias_ref<jclass> javaClass,
jni::alias_ref<JFabricUIManager::javaobject> javaUIManager) {
auto contextContainer =
javaUIManager->getBinding()->getScheduler()->getContextContainer();
auto owner = contextContainer->at<std::shared_ptr<jni::global_ref<jobject>>>(
"FabricUIManagerOwner");
auto alias = contextContainer->at<jni::alias_ref<jobject>>("FabricUIManager");
auto env = jni::Environment::current();
return alias.get() == owner->get() &&
env->GetObjectRefType(alias.get()) == JNIGlobalRefType &&
jni::isSameObject(alias.get(), javaUIManager.get());
}

jni::local_ref<JFabricUIManager::javaobject> readFabricUIManagerFromContext(
[[maybe_unused]] jni::alias_ref<jclass> javaClass,
jni::alias_ref<JFabricUIManager::javaobject> javaUIManager,
jboolean useGlobalRef,
jboolean uninstall) {
static const auto bindingField =
JFabricUIManager::javaClassStatic()
->getField<FabricUIManagerBinding::javaobject>("mBinding");
static const auto unregister =
jni::findClassStatic("com/facebook/react/fabric/FabricUIManagerBinding")
->getMethod<void()>("unregister");
auto javaBinding = javaUIManager->getFieldValue(bindingField);
auto contextContainer =
javaBinding->cthis()->getScheduler()->getContextContainer();
if (useGlobalRef != 0) {
auto global =
contextContainer->at<jni::global_ref<jobject>>("FabricUIManager");
if (uninstall != 0) {
std::weak_ptr<jni::global_ref<jobject>> owner =
contextContainer->at<std::shared_ptr<jni::global_ref<jobject>>>(
"FabricUIManagerOwner");
unregister(javaBinding);
contextContainer->erase("FabricUIManager");
contextContainer->erase("FabricUIManagerOwner");
if (!owner.expired()) {
jni::throwNewJavaException(
"java/lang/AssertionError",
"FabricUIManager owner survived teardown");
}
contextContainer.reset();
}
return jni::make_local(
jni::static_ref_cast<JFabricUIManager::javaobject>(
jni::alias_ref<jobject>(global)));
}
if (uninstall != 0) {
unregister(javaBinding);
}
auto alias = contextContainer->at<jni::alias_ref<jobject>>("FabricUIManager");
return jni::make_local(
jni::static_ref_cast<JFabricUIManager::javaobject>(alias));
}

} // namespace

FabricMountingManagerTestHelper::FabricMountingManagerTestHelper(
Expand Down Expand Up @@ -402,6 +459,11 @@ FabricMountingManagerTestHelper::pulledDeleteTags() {

void FabricMountingManagerTestHelper::registerNatives() {
registerHybrid({
makeNativeMethod(
"fabricUIManagerAliasUsesOwnedHandle",
fabricUIManagerAliasUsesOwnedHandle),
makeNativeMethod(
"readFabricUIManagerFromContext", readFabricUIManagerFromContext),
makeNativeMethod(
"initHybrid", FabricMountingManagerTestHelper::initHybrid),
makeNativeMethod(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ class FabricMountingManagerInstrumentationTest {
}

private fun mountPaddedView(
fixTextLayoutOnPixelDensityChange: Boolean
fixTextLayoutOnPixelDensityChange: Boolean,
): Pair<FabricMountingManagerTestHelper, ReactViewGroup> {
val fabricUIManager = createFabricUIManager(listOf(PaddingViewManager()))
val helper = FabricMountingManagerTestHelper.create(fabricUIManager)
Expand Down Expand Up @@ -281,7 +281,7 @@ class FabricMountingManagerInstrumentationTest {
ReactNativeFeatureFlagsCxxInterop.dangerouslyForceOverride(
object : ReactNativeFeatureFlagsDefaults() {
override fun enableMountingCoordinatorPullModelAndroid(): Boolean = true
}
},
)
}

Expand Down Expand Up @@ -501,7 +501,7 @@ class FabricMountingManagerInstrumentationTest {
override fun enablePropsUpdateReconciliationAndroid(): Boolean = pullModel

override fun enablePreallocatedPropsDiffOnInsertAndroid(): Boolean = pullModel
}
},
)
}

Expand Down Expand Up @@ -582,6 +582,71 @@ class FabricMountingManagerInstrumentationTest {
return surfaceId to { fabricUIManager.stopSurface(surfaceId) }
}

@Test
fun native_fabricUIManagerContext_aliasUsesOwnedGlobalHandle() {
val fabricUIManager = createFabricUIManager()
registerBinding(fabricUIManager)

assertThat(FabricMountingManagerTestHelper.fabricUIManagerAliasUsesOwnedHandle(fabricUIManager))
.isTrue()
assertThat(
FabricMountingManagerTestHelper.readFabricUIManagerFromContext(
fabricUIManager,
useGlobalRef = false,
uninstall = false,
),
)
.isSameAs(fabricUIManager)
}

@Test
fun native_fabricUIManagerContext_legacyCopiesLeaveAliasValid() {
val fabricUIManager = createFabricUIManager()
registerBinding(fabricUIManager)

repeat(64) {
assertThat(
FabricMountingManagerTestHelper.readFabricUIManagerFromContext(
fabricUIManager,
useGlobalRef = true,
uninstall = false,
),
)
.isSameAs(fabricUIManager)
assertThat(
FabricMountingManagerTestHelper.fabricUIManagerAliasUsesOwnedHandle(fabricUIManager),
)
.isTrue()
assertThat(
FabricMountingManagerTestHelper.readFabricUIManagerFromContext(
fabricUIManager,
useGlobalRef = false,
uninstall = false,
),
)
.isSameAs(fabricUIManager)
}
}

@Test
fun native_fabricUIManagerContext_readsSurviveUninstall() {
for (useGlobalRef in listOf(false, true)) {
repeat(8) {
val fabricUIManager = createFabricUIManager()
registerBinding(fabricUIManager)

assertThat(
FabricMountingManagerTestHelper.readFabricUIManagerFromContext(
fabricUIManager,
useGlobalRef = useGlobalRef,
uninstall = true,
),
)
.isSameAs(fabricUIManager)
}
}
}

@Test
fun native_stopSurfaceWithSurfaceHandler_pullModel_pullsDeletes() {
assertStoppingSurfacePullsDeletes(pullModel = true, ::startBridgelessSurface)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,16 @@ private constructor(fabricUIManager: FabricUIManager) : HybridClassBase() {
SoLoader.loadLibrary("fabricjni_test_helper")
}

@JvmStatic
external fun fabricUIManagerAliasUsesOwnedHandle(fabricUIManager: FabricUIManager): Boolean

@JvmStatic
external fun readFabricUIManagerFromContext(
fabricUIManager: FabricUIManager,
useGlobalRef: Boolean,
uninstall: Boolean,
): FabricUIManager

@JvmStatic
fun create(fabricUIManager: FabricUIManager): FabricMountingManagerTestHelper {
return FabricMountingManagerTestHelper(fabricUIManager)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ State::Shared ModalHostViewComponentDescriptor::createInitialState(

int surfaceId = family->getSurfaceId();

const jni::global_ref<jobject>& fabricUIManager =
contextContainer_->at<jni::global_ref<jobject>>("FabricUIManager");
auto fabricUIManager =
contextContainer_->at<jni::alias_ref<jobject>>("FabricUIManager");

static auto getEncodedScreenSizeWithoutVerticalInsets =
jni::findClassStatic(UIManagerJavaDescriptor)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@ class AndroidTextInputComponentDescriptor final : public ConcreteComponentDescri
if (surfaceIdToThemePaddingMap_.find(surfaceId) != surfaceIdToThemePaddingMap_.end()) {
theme = surfaceIdToThemePaddingMap_[surfaceId];
} else {
const jni::global_ref<jobject> &fabricUIManager =
contextContainer_->at<jni::global_ref<jobject>>("FabricUIManager");
auto fabricUIManager = contextContainer_->at<jni::alias_ref<jobject>>("FabricUIManager");

auto env = jni::Environment::current();
auto defaultTextInputPaddingArray = env->NewFloatArray(4);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ SharedColor parsePlatformColor(
if (iterator != getColorCache.end()) {
resolvedColor = iterator->second;
} else {
const auto& fabricUIManager =
contextContainer.at<jni::global_ref<jobject>>("FabricUIManager");
auto fabricUIManager =
contextContainer.at<jni::alias_ref<jobject>>("FabricUIManager");
// Boxed Integer: null is an explicit miss; a non-null value may be 0
// (transparent black).
static auto getColorFromJava =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ void ImageFetcher::flushImageRequests() {
}

auto fabricUIManager_ =
contextContainer_->at<jni::global_ref<jobject>>("FabricUIManager");
contextContainer_->at<jni::alias_ref<jobject>>("FabricUIManager");
static auto prefetchResources =
fabricUIManager_->getClass()
->getMethod<void(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ Size measureText(
float minHeight,
float maxHeight,
jfloatArray attachmentPositions) {
const jni::global_ref<jobject>& fabricUIManager =
contextContainer->at<jni::global_ref<jobject>>("FabricUIManager");
auto fabricUIManager =
contextContainer->at<jni::alias_ref<jobject>>("FabricUIManager");

static auto measure =
jni::findClassStatic("com/facebook/react/fabric/FabricUIManager")
Expand Down Expand Up @@ -245,8 +245,8 @@ LinesMeasurements TextLayoutManager::measureLines(
const auto& attributedString = attributedStringBox.getValue();

auto doMeasureLines = [&]() {
const jni::global_ref<jobject>& fabricUIManager =
contextContainer_->at<jni::global_ref<jobject>>("FabricUIManager");
auto fabricUIManager =
contextContainer_->at<jni::alias_ref<jobject>>("FabricUIManager");
static auto measureLines =
jni::findClassStatic("com/facebook/react/fabric/FabricUIManager")
->getMethod<NativeArray::javaobject(
Expand Down Expand Up @@ -319,8 +319,8 @@ TextLayoutManager::PreparedTextLayout TextLayoutManager::prepareLayout(
.layoutConstraints = layoutConstraints,
.pointScaleFactor = layoutContext.pointScaleFactor},
[&]() {
const auto& fabricUIManager =
contextContainer_->at<jni::global_ref<jobject>>("FabricUIManager");
auto fabricUIManager =
contextContainer_->at<jni::alias_ref<jobject>>("FabricUIManager");
auto attributedStringMB = JReadableMapBuffer::createWithContents(
toMapBuffer(attributedString));
auto paragraphAttributesMB = JReadableMapBuffer::createWithContents(
Expand Down Expand Up @@ -364,8 +364,8 @@ TextLayoutManager::PreparedTextLayout TextLayoutManager::prepareLayout(
javaReactTags->setRegion(
0, static_cast<jsize>(reactTags.size()), reactTags.data());

const auto& fabricUIManager =
contextContainer_->at<jni::global_ref<jobject>>("FabricUIManager");
auto fabricUIManager =
contextContainer_->at<jni::alias_ref<jobject>>("FabricUIManager");
return PreparedTextLayout{
jni::make_global(reusePreparedLayoutWithNewReactTags(
fabricUIManager, preparedText->get(), javaReactTags.get()))};
Expand All @@ -378,8 +378,8 @@ TextMeasurement TextLayoutManager::measurePreparedLayout(
const PreparedTextLayout& preparedLayout,
const TextLayoutContext& /*layoutContext*/,
const LayoutConstraints& layoutConstraints) const {
const auto& fabricUIManager =
contextContainer_->at<jni::global_ref<jobject>>("FabricUIManager");
auto fabricUIManager =
contextContainer_->at<jni::alias_ref<jobject>>("FabricUIManager");

static auto measurePreparedLayout =
jni::findClassStatic("com/facebook/react/fabric/FabricUIManager")
Expand Down
Loading