diff --git a/ReactAndroid/src/androidTest/java/com/facebook/react/testing/BUCK b/ReactAndroid/src/androidTest/java/com/facebook/react/testing/BUCK index fb77610c0..f0b24945f 100644 --- a/ReactAndroid/src/androidTest/java/com/facebook/react/testing/BUCK +++ b/ReactAndroid/src/androidTest/java/com/facebook/react/testing/BUCK @@ -13,6 +13,8 @@ rn_android_library( "PUBLIC", ], deps = [ + react_native_dep("java/com/facebook/fbreact/fabricxx:fabricxx"), + react_native_dep("java/com/facebook/fbreact/fabricxx/jsi:jsi"), react_native_dep("libraries/soloader/java/com/facebook/soloader:soloader"), react_native_dep("third-party/android/support/v4:lib-support-v4"), react_native_dep("third-party/java/buck-android-support:buck-android-support"), @@ -28,7 +30,6 @@ rn_android_library( react_native_target("java/com/facebook/react/common:common"), react_native_target("java/com/facebook/react/devsupport:interfaces"), react_native_target("java/com/facebook/react/fabric:fabric"), - react_native_target("java/com/facebook/react/fabric/jsc:jsc"), react_native_target("java/com/facebook/react/module/annotations:annotations"), react_native_target("java/com/facebook/react/module/model:model"), react_native_target("java/com/facebook/react/modules/core:core"), @@ -38,3 +39,5 @@ rn_android_library( react_native_target("res:uimanager"), ], ) + +# /Users/dvacca/fbsource/fbandroid/xplat_cell/ReactAndroid/src/androidTest/java/com/facebook/react/testing/BUCK diff --git a/ReactAndroid/src/androidTest/java/com/facebook/react/testing/ReactAppTestActivity.java b/ReactAndroid/src/androidTest/java/com/facebook/react/testing/ReactAppTestActivity.java index 372415b8c..043f2faf1 100644 --- a/ReactAndroid/src/androidTest/java/com/facebook/react/testing/ReactAppTestActivity.java +++ b/ReactAndroid/src/androidTest/java/com/facebook/react/testing/ReactAppTestActivity.java @@ -10,12 +10,12 @@ import static com.facebook.react.bridge.UiThreadUtil.runOnUiThread; import android.content.Intent; import android.graphics.Bitmap; -import android.os.AsyncTask; import android.os.Bundle; import android.support.v4.app.FragmentActivity; import android.view.View; import android.view.ViewTreeObserver; import android.widget.FrameLayout; +import com.facebook.fbreact.fabricxx.jsi.Binding; import com.facebook.infer.annotation.Assertions; import com.facebook.react.ReactInstanceManager; import com.facebook.react.ReactInstanceManagerBuilder; @@ -29,8 +29,8 @@ import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContext; import com.facebook.react.bridge.UIManager; import com.facebook.react.common.LifecycleState; -import com.facebook.react.fabric.FabricUIManager; -import com.facebook.react.fabric.jsc.FabricJSCBinding; +import com.facebook.react.fabric.FabricBinder; +import com.facebook.react.fabric.FabricBinding; import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler; import com.facebook.react.modules.core.PermissionAwareActivity; import com.facebook.react.modules.core.PermissionListener; @@ -239,7 +239,7 @@ public class ReactAppTestActivity extends FragmentActivity public JSIModuleProvider getJSIModuleProvider() { return new JSIModuleProvider() { @Override - public FabricUIManager get() { + public UIManager get() { List viewManagers = mReactInstanceManager.getOrCreateViewManagers( reactApplicationContext); @@ -247,14 +247,18 @@ public class ReactAppTestActivity extends FragmentActivity reactApplicationContext .getNativeModule(UIManagerModule.class) .getEventDispatcher(); - FabricUIManager fabricUIManager = - new FabricUIManager( - reactApplicationContext, - new ViewManagerRegistry(viewManagers), - jsContext, - eventDispatcher); - new FabricJSCBinding().installFabric(jsContext, fabricUIManager); - return fabricUIManager; + + ViewManagerRegistry viewManagerRegistry = + new ViewManagerRegistry( + mReactInstanceManager.getOrCreateViewManagers(reactApplicationContext)); + + UIManager uiManager = + new com.facebook.fbreact.fabricxx.UIManager( + reactApplicationContext, viewManagerRegistry, jsContext); + + FabricBinding binding = new Binding(); + binding.installFabric(jsContext, (FabricBinder) uiManager); + return uiManager; } }; } diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricReconciler.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricReconciler.java deleted file mode 100644 index a5e114a3a..000000000 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricReconciler.java +++ /dev/null @@ -1,158 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its 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; - -import com.facebook.common.logging.FLog; -import com.facebook.debug.holder.PrinterHolder; -import com.facebook.debug.tags.ReactDebugOverlayTags; -import com.facebook.react.common.ArrayUtils; -import com.facebook.react.common.build.ReactBuildConfig; -import com.facebook.react.uimanager.ReactShadowNode; -import com.facebook.react.uimanager.UIViewOperationQueue; -import com.facebook.react.uimanager.ViewAtIndex; -import com.facebook.systrace.Systrace; -import com.facebook.systrace.SystraceMessage; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; -import javax.annotation.Nullable; - -public class FabricReconciler { - - private static final String TAG = FabricReconciler.class.getSimpleName(); - private static final boolean DEBUG = ReactBuildConfig.DEBUG || PrinterHolder - .getPrinter().shouldDisplayLogMessage(ReactDebugOverlayTags.FABRIC_RECONCILER); - - private UIViewOperationQueue uiViewOperationQueue; - - public FabricReconciler(UIViewOperationQueue uiViewOperationQueue) { - this.uiViewOperationQueue = uiViewOperationQueue; - } - - public void manageChildren(ReactShadowNode previousRootShadowNode, ReactShadowNode newRootShadowNode) { - SystraceMessage.beginSection( - Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, - "FabricReconciler.manageChildren") - .flush(); - - try { - List prevList = - previousRootShadowNode == null ? null : previousRootShadowNode.getChildrenList(); - manageChildren(newRootShadowNode, prevList, newRootShadowNode.getChildrenList()); - } finally{ - Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE); - } - } - - private void manageChildren( - ReactShadowNode parent, - @Nullable List prevList, - @Nullable List newList) { - prevList = prevList == null ? Collections.emptyList() : prevList; - newList = newList == null ? Collections.emptyList() : newList; - - // Iterate through each child list and compare each previous and next child. Same nodes - // implies no change is needed. If the nodes are different but are referencing the same view, - // the view needs to be updated with new props and children. Otherwise, there has been - // a change in the children positions. - int sameReactTagIndex = 0; - for (; sameReactTagIndex < Math.min(prevList.size(), newList.size()); sameReactTagIndex++) { - ReactShadowNode prevNode = prevList.get(sameReactTagIndex); - ReactShadowNode newNode = newList.get(sameReactTagIndex); - if (prevNode == newNode) { - continue; - } - if (prevNode.getReactTag() != newNode.getReactTag()) { - break; - } - enqueueUpdateProperties(newNode, prevNode); - manageChildren(prevNode, prevNode.getChildrenList(), newNode.getChildrenList()); - newNode.setOriginalReactShadowNode(null); - } - int firstRemovedOrAddedViewIndex = sameReactTagIndex; - - // Every ReactShadowNode on the newList that is on the right side of - // firstRemovedOrAddedViewIndex is defined as an added view. - // It is more efficient to reorder removing and adding all the views in the right order, instead - // of calculating the minimum amount of reorder operations. - Set addedTags = new HashSet<>(); - List viewsToAdd = new LinkedList<>(); - for (int k = firstRemovedOrAddedViewIndex; k < newList.size(); k++) { - ReactShadowNode newNode = newList.get(k); - if (newNode.isVirtual()) continue; - enqueueUpdateProperties(newNode, newNode.getOriginalReactShadowNode()); - viewsToAdd.add(new ViewAtIndex(newNode.getReactTag(), k)); - List previousChildrenList = newNode.getOriginalReactShadowNode() == null ? null : newNode.getOriginalReactShadowNode().getChildrenList(); - manageChildren(newNode, previousChildrenList, newNode.getChildrenList()); - newNode.setOriginalReactShadowNode(null); - addedTags.add(newNode.getReactTag()); - } - - // Every ReactShadowNode on the prevList that is on the right side of - // firstRemovedOrAddedViewIndex is defined as a removed view. - // It is more efficient to reorder removing and adding all the views in the right order, instead - // of calculating the minimum amount of reorder operations. - // If a View is not re-ordered, then the ReactTag is deleted (ReactShadowNode and native View - // are released from memory) - List tagsToDelete = new LinkedList<>(); - List indicesToRemove = new LinkedList<>(); - for (int j = prevList.size() - 1; j >= firstRemovedOrAddedViewIndex; j--) { - ReactShadowNode nodeToRemove = prevList.get(j); - if (nodeToRemove.isVirtual()) continue; - indicesToRemove.add(0, j); - if (!addedTags.contains(nodeToRemove.getReactTag())) { - tagsToDelete.add(nodeToRemove.getReactTag()); - } - } - - // TODO (t27180994): Mutate views synchronously on main thread - if (!(indicesToRemove.isEmpty() && viewsToAdd.isEmpty() && tagsToDelete.isEmpty())) { - int[] indicesToRemoveArray = ArrayUtils.copyListToArray(indicesToRemove); - ViewAtIndex[] viewsToAddArray = viewsToAdd.toArray(new ViewAtIndex[viewsToAdd.size()]); - int[] tagsToDeleteArray = ArrayUtils.copyListToArray(tagsToDelete); - if (DEBUG) { - FLog.d( - TAG, - "manageChildren.enqueueManageChildren parent: " + parent.getReactTag() + - "\n\tIndices2Remove: " + Arrays.toString(indicesToRemoveArray) + - "\n\tViews2Add: " + Arrays.toString(viewsToAddArray) + - "\n\tTags2Delete: " + Arrays.toString(tagsToDeleteArray)); - } - uiViewOperationQueue.enqueueManageChildren( - parent.getReactTag(), indicesToRemoveArray, viewsToAddArray, tagsToDeleteArray); - } - } - - private void enqueueUpdateProperties(ReactShadowNode newNode, ReactShadowNode prevNode) { - int reactTag = newNode.getReactTag(); - if (DEBUG) { - FLog.d( - TAG, - "manageChildren.enqueueUpdateProperties " + - "\n\ttag: " + reactTag + - "\n\tviewClass: " + newNode.getViewClass() + - "\n\tinstanceHandle: " + newNode.getInstanceHandle() + - "\n\tnewProps: " + newNode.getNewProps()); - } - - if (prevNode != null) { - newNode.updateScreenLayout(prevNode); - } - - if (newNode.getNewProps() != null) { - uiViewOperationQueue.enqueueUpdateProperties( - reactTag, newNode.getViewClass(), newNode.getNewProps()); - } - - uiViewOperationQueue.enqueueUpdateInstanceHandle( - reactTag, newNode.getInstanceHandle()); - } -} diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java deleted file mode 100644 index 836adc4c2..000000000 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java +++ /dev/null @@ -1,688 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its 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; - -import static android.view.View.MeasureSpec.AT_MOST; -import static android.view.View.MeasureSpec.EXACTLY; -import static android.view.View.MeasureSpec.UNSPECIFIED; -import static com.facebook.react.uimanager.common.UIManagerType.FABRIC; - -import android.os.SystemClock; -import android.view.View; -import com.facebook.common.logging.FLog; -import com.facebook.debug.holder.PrinterHolder; -import com.facebook.debug.tags.ReactDebugOverlayTags; -import com.facebook.infer.annotation.Assertions; -import com.facebook.proguard.annotations.DoNotStrip; -import com.facebook.react.bridge.JavaScriptContextHolder; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.bridge.ReadableArray; -import com.facebook.react.bridge.ReadableMap; -import com.facebook.react.bridge.ReadableNativeMap; -import com.facebook.react.bridge.UIManager; -import com.facebook.react.bridge.WritableMap; -import com.facebook.react.bridge.WritableNativeMap; -import com.facebook.react.common.ReactConstants; -import com.facebook.react.common.annotations.VisibleForTesting; -import com.facebook.react.common.build.ReactBuildConfig; -import com.facebook.react.fabric.events.FabricEventEmitter; -import com.facebook.react.modules.i18nmanager.I18nUtil; -import com.facebook.react.uimanager.DisplayMetricsHolder; -import com.facebook.react.uimanager.NativeViewHierarchyManager; -import com.facebook.react.uimanager.ReactRootViewTagGenerator; -import com.facebook.react.uimanager.ReactShadowNode; -import com.facebook.react.uimanager.ReactShadowNodeImpl; -import com.facebook.react.uimanager.ReactStylesDiffMap; -import com.facebook.react.uimanager.ThemedReactContext; -import com.facebook.react.uimanager.UIViewOperationQueue; -import com.facebook.react.uimanager.ViewManager; -import com.facebook.react.uimanager.ViewManagerRegistry; -import com.facebook.react.uimanager.common.MeasureSpecProvider; -import com.facebook.react.uimanager.common.SizeMonitoringFrameLayout; -import com.facebook.react.uimanager.events.EventDispatcher; -import com.facebook.systrace.Systrace; -import com.facebook.systrace.SystraceMessage; -import com.facebook.yoga.YogaDirection; -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import javax.annotation.Nullable; - -/** - * This class is responsible to create, clone and update {@link ReactShadowNode} using the Fabric - * API. - */ -@SuppressWarnings("unused") // used from JNI -@DoNotStrip -public class FabricUIManager implements UIManager, JSHandler, FabricBinder { - - private static final String TAG = FabricUIManager.class.getSimpleName(); - private static final boolean DEBUG = ReactBuildConfig.DEBUG || PrinterHolder.getPrinter().shouldDisplayLogMessage(ReactDebugOverlayTags.FABRIC_UI_MANAGER); - - private final RootShadowNodeRegistry mRootShadowNodeRegistry = new RootShadowNodeRegistry(); - private final ReactApplicationContext mReactApplicationContext; - private final ViewManagerRegistry mViewManagerRegistry; - private final UIViewOperationQueue mUIViewOperationQueue; - private final NativeViewHierarchyManager mNativeViewHierarchyManager; - private final JavaScriptContextHolder mJSContext; - private volatile int mCurrentBatch = 0; - private final FabricReconciler mFabricReconciler; - private final EventDispatcher mEventDispatcher; - private FabricBinding mBinding; - private final FabricEventEmitter mFabricEventEmitter; - private long mEventHandlerPointer; - private long mLastCalculateLayoutTime = 0; - - public FabricUIManager( - ReactApplicationContext reactContext, - ViewManagerRegistry viewManagerRegistry, - JavaScriptContextHolder jsContext, - EventDispatcher eventDispatcher) { - DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(reactContext); - mReactApplicationContext = reactContext; - mViewManagerRegistry = viewManagerRegistry; - mNativeViewHierarchyManager = new NativeViewHierarchyManager(viewManagerRegistry); - mUIViewOperationQueue = - new UIViewOperationQueue( - reactContext, mNativeViewHierarchyManager, 0); - mFabricReconciler = new FabricReconciler(mUIViewOperationQueue); - mFabricEventEmitter = - new FabricEventEmitter(mReactApplicationContext, this); - mEventDispatcher = eventDispatcher; - mJSContext = jsContext; - } - - @Override - public void setBinding(FabricBinding binding) { - mBinding = binding; - } - - /** Creates a new {@link ReactShadowNode} */ - @Nullable - @DoNotStrip - public ReactShadowNode createNode( - int reactTag, String viewName, int rootTag, ReadableNativeMap props, long eventTarget) { - if (DEBUG) { - FLog.d(TAG, "createNode \n\ttag: " + reactTag + - "\n\tviewName: " + viewName + - "\n\trootTag: " + rootTag + - "\n\tprops: " + props); - } - try { - ViewManager viewManager = mViewManagerRegistry.get(viewName); - ReactShadowNode node = viewManager.createShadowNodeInstance(mReactApplicationContext); - ReactShadowNode rootNode = getRootNode(rootTag); - node.setRootTag(rootNode.getReactTag()); - node.setViewClassName(viewName); - node.setInstanceHandle(eventTarget); - node.setReactTag(reactTag); - node.setThemedContext(rootNode.getThemedContext()); - - ReactStylesDiffMap styles = updateProps(node, props); - - if (!node.isVirtual()) { - mUIViewOperationQueue.enqueueCreateView( - rootNode.getThemedContext(), reactTag, viewName, styles); - } - return node; - } catch (Throwable t) { - handleException(getRootNode(rootTag), t); - return null; - } - } - - @VisibleForTesting - ReactShadowNode getRootNode(int rootTag) { - return mRootShadowNodeRegistry.getNode(rootTag); - } - - private ReactStylesDiffMap updateProps(ReactShadowNode node, @Nullable ReadableNativeMap props) { - ReactStylesDiffMap styles = null; - if (props != null) { - styles = new ReactStylesDiffMap(props); - node.updateProperties(styles); - } - return styles; - } - - /** - * @return a clone of the {@link ReactShadowNode} received by parameter. The cloned - * ReactShadowNode will contain a copy of all the internal data of the original node, - * including its children set (note that the children nodes will not be cloned). - */ - @Nullable - @DoNotStrip - public ReactShadowNode cloneNode(ReactShadowNode node) { - if (DEBUG) { - FLog.d(TAG, "cloneNode \n\tnode: " + node); - } - SystraceMessage.beginSection( - Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, - "FabricUIManager.cloneNode") - .flush(); - try { - ReactShadowNode clone = node.mutableCopy(node.getInstanceHandle()); - assertReactShadowNodeCopy(node, clone); - return clone; - } catch (Throwable t) { - handleException(node, t); - return null; - } finally{ - Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE); - } - } - - /** - * @return a clone of the {@link ReactShadowNode} received by parameter. The cloned - * ReactShadowNode will contain a copy of all the internal data of the original node, but its - * children set will be empty. - */ - @Nullable - @DoNotStrip - public ReactShadowNode cloneNodeWithNewChildren(ReactShadowNode node) { - if (DEBUG) { - FLog.d(TAG, "cloneNodeWithNewChildren \n\tnode: " + node); - } - SystraceMessage.beginSection( - Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, - "FabricUIManager.cloneNodeWithNewChildren") - .flush(); - try { - ReactShadowNode clone = node.mutableCopyWithNewChildren(node.getInstanceHandle()); - assertReactShadowNodeCopy(node, clone); - return clone; - } catch (Throwable t) { - handleException(node, t); - return null; - } finally{ - Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE); - } - } - - /** - * @return a clone of the {@link ReactShadowNode} received by parameter. The cloned - * ReactShadowNode will contain a copy of all the internal data of the original node, but its - * props will be overridden with the {@link ReadableMap} received by parameter. - */ - @Nullable - @DoNotStrip - public ReactShadowNode cloneNodeWithNewProps( - ReactShadowNode node, @Nullable ReadableNativeMap newProps) { - if (DEBUG) { - FLog.d(TAG, "cloneNodeWithNewProps \n\tnode: " + node + "\n\tprops: " + newProps); - } - SystraceMessage.beginSection( - Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, - "FabricUIManager.cloneNodeWithNewProps") - .flush(); - try { - ReactShadowNode clone = node.mutableCopyWithNewProps(node.getInstanceHandle(), - newProps == null ? null : new ReactStylesDiffMap(newProps)); - assertReactShadowNodeCopy(node, clone); - return clone; - } catch (Throwable t) { - handleException(node, t); - return null; - } finally{ - Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE); - } - } - - /** - * @return a clone of the {@link ReactShadowNode} received by parameter. The cloned - * ReactShadowNode will contain a copy of all the internal data of the original node, but its - * props will be overridden with the {@link ReadableMap} received by parameter and its - * children set will be empty. - */ - @Nullable - @DoNotStrip - public ReactShadowNode cloneNodeWithNewChildrenAndProps( - ReactShadowNode node, ReadableNativeMap newProps) { - if (DEBUG) { - FLog.d(TAG, "cloneNodeWithNewChildrenAndProps \n\tnode: " + node + "\n\tnewProps: " + newProps); - } - SystraceMessage.beginSection( - Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, - "FabricUIManager.cloneNodeWithNewChildrenAndProps") - .flush(); - try { - ReactShadowNode clone = - node.mutableCopyWithNewChildrenAndProps(node.getInstanceHandle(), - newProps == null ? null : new ReactStylesDiffMap(newProps)); - assertReactShadowNodeCopy(node, clone); - return clone; - } catch (Throwable t) { - handleException(node, t); - return null; - } finally{ - Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE); - } - } - - private void assertReactShadowNodeCopy(ReactShadowNode source, ReactShadowNode target) { - Assertions.assertCondition( - source.getClass().equals(target.getClass()), - "Found " - + target.getClass() - + " class when expecting: " - + source.getClass() - + ". Check that " - + source.getClass() - + " implements the copy() method correctly."); - } - - /** - * Appends the child {@link ReactShadowNode} to the children set of the parent {@link - * ReactShadowNode}. - */ - @Nullable - @DoNotStrip - public void appendChild(ReactShadowNode parent, ReactShadowNode child) { - if (DEBUG) { - FLog.d(TAG, "appendChild \n\tparent: " + parent + "\n\tchild: " + child); - } - SystraceMessage.beginSection( - Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, - "FabricUIManager.appendChild") - .flush(); - try { - // If the child to append was already committed (child.isSealed()), - // then we add a mutation of it. In the future this will be performed by FabricJS / Fiber. - //TODO: T27926878 avoid cloning shared child - if (child.isSealed()) { - child = child.mutableCopy(child.getInstanceHandle()); - } - parent.addChildAt(child, parent.getChildCount()); - } catch (Throwable t) { - handleException(parent, t); - } finally{ - Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE); - } - } - - /** - * @return an empty {@link List} that will be used to append the {@link - * ReactShadowNode} elements of the root. Typically this List will contain one element. - */ - @DoNotStrip - public List createChildSet(int rootTag) { - if (DEBUG) { - FLog.d(TAG, "createChildSet rootTag: " + rootTag); - } - return new ArrayList<>(1); - } - - /** - * Adds the {@link ReactShadowNode} to the {@link List} received by parameter. - */ - @DoNotStrip - public void appendChildToSet(List childList, ReactShadowNode child) { - childList.add(child); - } - - @DoNotStrip - public synchronized void completeRoot(int rootTag, @Nullable List childList) { - SystraceMessage.beginSection( - Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, - "FabricUIManager.completeRoot") - .flush(); - try { - long startTime = SystemClock.uptimeMillis(); - childList = childList == null ? new LinkedList() : childList; - if (DEBUG) { - FLog.d(TAG, "completeRoot rootTag: " + rootTag + ", childList: " + childList); - } - ReactShadowNode currentRootShadowNode = getRootNode(rootTag); - Assertions.assertNotNull( - currentRootShadowNode, - "Root view with tag " + rootTag + " must be added before completeRoot is called"); - - currentRootShadowNode = calculateDiffingAndCreateNewRootNode(currentRootShadowNode, childList); - - if (DEBUG) { - FLog.d( - TAG, - "ReactShadowNodeHierarchy after diffing: " + currentRootShadowNode.getHierarchyInfo()); - } - - applyUpdatesRecursive(currentRootShadowNode); - mUIViewOperationQueue.dispatchViewUpdates( - mCurrentBatch++, startTime, mLastCalculateLayoutTime); - - mRootShadowNodeRegistry.replaceNode(currentRootShadowNode); - } catch (Exception e) { - handleException(getRootNode(rootTag), e); - } finally{ - Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE); - } - } - - public void dispatchCommand(int reactTag, int commandId, @Nullable ReadableArray commandArgs) { - mUIViewOperationQueue.enqueueDispatchCommand(reactTag, commandId, commandArgs); - } - - private void notifyOnBeforeLayoutRecursive(ReactShadowNode node) { - if (!node.hasUpdates()) { - return; - } - for (int i = 0; i < node.getChildCount(); i++) { - notifyOnBeforeLayoutRecursive(node.getChildAt(i)); - } - node.onBeforeLayout(); - } - - private ReactShadowNode calculateDiffingAndCreateNewRootNode( - ReactShadowNode currentRootShadowNode, List newChildList) { - SystraceMessage.beginSection( - Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, - "FabricUIManager.calculateDiffingAndCreateNewRootNode") - .flush(); - try { - ReactShadowNode newRootShadowNode = currentRootShadowNode.mutableCopyWithNewChildren(currentRootShadowNode.getInstanceHandle()); - for (ReactShadowNode child : newChildList) { - appendChild(newRootShadowNode, child); - } - - if (DEBUG) { - FLog.d( - TAG, - "ReactShadowNodeHierarchy before calculateLayout: " + newRootShadowNode.getHierarchyInfo()); - } - - notifyOnBeforeLayoutRecursive(newRootShadowNode); - - calculateLayout(newRootShadowNode); - - if (DEBUG) { - FLog.d( - TAG, - "ReactShadowNodeHierarchy after calculateLayout: " + newRootShadowNode.getHierarchyInfo()); - } - - mFabricReconciler.manageChildren(currentRootShadowNode, newRootShadowNode); - return newRootShadowNode; - } finally{ - Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE); - } - } - - private void calculateLayout(ReactShadowNode newRootShadowNode) { - SystraceMessage.beginSection( - Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, - "FabricUIManager.calculateLayout") - .flush(); - long startTime = SystemClock.uptimeMillis(); - try { - newRootShadowNode.calculateLayout(); - } finally{ - mLastCalculateLayoutTime = SystemClock.uptimeMillis() - startTime; - Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE); - } - } - - private void applyUpdatesRecursive(ReactShadowNode node) { - SystraceMessage.beginSection( - Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "FabricUIManager.applyUpdatesRecursive") - .flush(); - try { - applyUpdatesRecursive(node, 0, 0); - } finally{ - SystraceMessage.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE); - } - } - - private void applyUpdatesRecursive(ReactShadowNode node, float absoluteX, float absoluteY) { - if (!node.hasUpdates()) { - return; - } - - if (!node.isVirtualAnchor()) { - for (int i = 0; i < node.getChildCount(); i++) { - applyUpdatesRecursive( - node.getChildAt(i), - absoluteX + node.getLayoutX(), - absoluteY + node.getLayoutY()); - } - } - - int tag = node.getReactTag(); - if (getRootNode(tag) == null) { - boolean frameDidChange = - node.dispatchUpdates(absoluteX, absoluteY, mUIViewOperationQueue, null); - // Notify JS about layout event if requested - // and if the position or dimensions actually changed - // (consistent with iOS and Android Default implementation). - if (frameDidChange && node.shouldNotifyOnLayout()) { - mUIViewOperationQueue.enqueueOnLayoutEvent(tag, - node.getScreenX(), - node.getScreenY(), - node.getScreenWidth(), - node.getScreenHeight()); - } - } - - // Set the reference to the OriginalReactShadowNode to NULL, as the tree is already committed - // and we do not need to hold references to the previous tree anymore - node.setOriginalReactShadowNode(null); - node.markUpdateSeen(); - node.markAsSealed(); - } - - @Override - @DoNotStrip - public int addRootView( - final T rootView) { - - SystraceMessage.beginSection( - Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, - "FabricUIManager.addRootView") - .flush(); - try { - final int rootTag = ReactRootViewTagGenerator.getNextRootViewTag(); - ThemedReactContext themedRootContext = - new ThemedReactContext(mReactApplicationContext, rootView.getContext()); - - ReactShadowNode rootShadowNode = createRootShadowNode(rootTag, themedRootContext); - - int widthMeasureSpec = rootView.getWidthMeasureSpec(); - int heightMeasureSpec = rootView.getHeightMeasureSpec(); - updateRootView(rootShadowNode, widthMeasureSpec, heightMeasureSpec); - - rootView.setOnSizeChangedListener( - new SizeMonitoringFrameLayout.OnSizeChangedListener() { - @Override - public void onSizeChanged(final int width, final int height, int oldW, int oldH) { - updateRootSize(rootTag, width, height); - } - }); - - mRootShadowNodeRegistry.registerNode(rootShadowNode); - mUIViewOperationQueue.addRootView(rootTag, rootView, themedRootContext); - return rootTag; - } finally{ - Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE); - } - } - - @Override - @DoNotStrip - public synchronized void updateRootLayoutSpecs(final int rootViewTag, final int widthMeasureSpec, final int heightMeasureSpec) { - mReactApplicationContext.runOnNativeModulesQueueThread(new Runnable() { - @Override - public void run() { - ReactShadowNode rootNode = getRootNode(rootViewTag); - if (rootNode == null) { - FLog.w(ReactConstants.TAG, "Tried to update non-existent root tag: " + rootViewTag); - return; - } - - ReactShadowNode newRootNode = rootNode.mutableCopy(rootNode.getInstanceHandle()); - updateRootView(newRootNode, widthMeasureSpec, heightMeasureSpec); - mRootShadowNodeRegistry.replaceNode(newRootNode); - } - }); - } - - /** - * Updates the root view size and re-render the RN surface. - * - * //TODO: change synchronization to integrate with new #render loop. - */ - private synchronized void updateRootSize(int rootTag, int newWidth, int newHeight) { - ReactShadowNode rootNode = getRootNode(rootTag); - if (rootNode == null) { - FLog.w( - ReactConstants.TAG, - "Tried to update size of non-existent tag: " + rootTag); - return; - } - - ReactShadowNode newRootNode = rootNode.mutableCopy(rootNode.getInstanceHandle()); - int newWidthSpec = View.MeasureSpec.makeMeasureSpec(newWidth, View.MeasureSpec.EXACTLY); - int newHeightSpec = View.MeasureSpec.makeMeasureSpec(newHeight, View.MeasureSpec.EXACTLY); - updateRootView(newRootNode, newWidthSpec, newHeightSpec); - - completeRoot(rootTag, newRootNode.getChildrenList()); - } - - public void removeRootView(int rootTag) { - mUIViewOperationQueue.enqueueRemoveRootView(rootTag); - mRootShadowNodeRegistry.removeNode(rootTag); - } - - private ReactShadowNode createRootShadowNode(int rootTag, ThemedReactContext themedReactContext) { - ReactShadowNode rootNode = new ReactShadowNodeImpl(); - I18nUtil sharedI18nUtilInstance = I18nUtil.getInstance(); - if (sharedI18nUtilInstance.isRTL(themedReactContext)) { - rootNode.setLayoutDirection(YogaDirection.RTL); - } - rootNode.setViewClassName("Root"); - rootNode.setReactTag(rootTag); - rootNode.setThemedContext(themedReactContext); - return rootNode; - } - - /** - * Updates the styles of the {@link ReactShadowNode} based on the Measure specs received by - * parameters. - */ - private void updateRootView( - ReactShadowNode node, int widthMeasureSpec, int heightMeasureSpec) { - int widthMode = View.MeasureSpec.getMode(widthMeasureSpec); - int widthSize = View.MeasureSpec.getSize(widthMeasureSpec); - switch (widthMode) { - case EXACTLY: - node.setStyleWidth(widthSize); - break; - case AT_MOST: - node.setStyleMaxWidth(widthSize); - break; - case UNSPECIFIED: - node.setStyleWidthAuto(); - break; - } - - int heightMode = View.MeasureSpec.getMode(heightMeasureSpec); - int heightSize = View.MeasureSpec.getSize(heightMeasureSpec); - switch (heightMode) { - case EXACTLY: - node.setStyleHeight(heightSize); - break; - case AT_MOST: - node.setStyleMaxHeight(heightSize); - break; - case UNSPECIFIED: - node.setStyleHeightAuto(); - break; - } - } - - private void handleException(ReactShadowNode node, Throwable t) { - try { - ThemedReactContext context = node.getThemedContext(); - // TODO move exception management to JNI side, and refactor to avoid wrapping Throwable into - // a RuntimeException - context.handleException(new RuntimeException(t)); - } catch (Exception ex) { - FLog.e(TAG, "Exception while executing a Fabric method", t); - throw new RuntimeException(ex.getMessage(), t); - } - } - - @Nullable - @DoNotStrip - public long getEventTarget(int reactTag) { - long instanceHandle = mNativeViewHierarchyManager.getInstanceHandle(reactTag); - return instanceHandle; - } - - @DoNotStrip - public void registerEventHandler(long eventHandlerPointer) { - mEventHandlerPointer = eventHandlerPointer; - } - - @DoNotStrip - public void releaseEventTarget(long eventTargetPointer) { - mBinding.releaseEventTarget(mJSContext.get(), eventTargetPointer); - } - - @DoNotStrip - public void releaseEventHandler(long eventHandlerPointer) { - mBinding.releaseEventHandler(mJSContext.get(), eventHandlerPointer); - } - - @Override - @DoNotStrip - public void invoke(long eventTarget, String name, WritableMap params) { - if (DEBUG) { - FLog.d( - TAG, - "Dispatching event for target: " + eventTarget); - } - if (params == null) { - params = new WritableNativeMap(); - } - mBinding.dispatchEventToTarget(mJSContext.get(), mEventHandlerPointer, eventTarget, name, (WritableNativeMap) params); - } - - @Override - public void setJSResponder(int reactTag, boolean blockNativeResponder) { - // TODO: Do nothing for now - } - - @Override - public void clearJSResponder() { - // TODO: Do nothing for now - } - - @Override - public void initialize() { - FabricEventEmitter eventEmitter = - new FabricEventEmitter(mReactApplicationContext, this); - mEventDispatcher.registerEventEmitter(FABRIC, mFabricEventEmitter); - } - - @Override - public void onCatalystInstanceDestroy() { - mBinding.releaseEventHandler(mJSContext.get(), mEventHandlerPointer); - mEventDispatcher.unregisterEventEmitter(FABRIC); - mFabricEventEmitter.close(); - } - - @Override - public void profileNextBatch() { - mUIViewOperationQueue.profileNextBatch(); - } - - @Override - public Map getPerformanceCounters() { - // TODO change profiling when enabling multi-thread rendering. - return mUIViewOperationQueue.getProfiledBatchPerfCounters(); - } -} diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/JSHandler.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/JSHandler.java deleted file mode 100644 index ba5646878..000000000 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/JSHandler.java +++ /dev/null @@ -1,15 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its 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; - -import com.facebook.react.bridge.WritableMap; - -public interface JSHandler { - - void invoke(long instanceHandle, String name, WritableMap params); - -} diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/RootShadowNodeRegistry.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/RootShadowNodeRegistry.java deleted file mode 100644 index 0bd3b2942..000000000 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/RootShadowNodeRegistry.java +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its 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; - -import com.facebook.react.uimanager.ReactShadowNode; -import java.util.concurrent.ConcurrentHashMap; -import javax.annotation.concurrent.ThreadSafe; - -/** - * Simple container class to keep track of {@link ReactShadowNode}s that represents the Root - * Shadow Nodes of a {@link FabricUIManager}. - */ -@ThreadSafe -public class RootShadowNodeRegistry { - - private final ConcurrentHashMap mTagsToRootNodes = new ConcurrentHashMap<>(); - - /** - * Registers the {@link ReactShadowNode} received as a parameter as a RootShadowNode. - */ - public synchronized void registerNode(ReactShadowNode node) { - mTagsToRootNodes.put(node.getReactTag(), node); - } - - /** - * Register the {@link ReactShadowNode} received as a parameter as a RootShadowNode, replacing - * the previous RootShadowNode associated for the {@link ReactShadowNode#getReactTag()} - */ - public void replaceNode(ReactShadowNode node) { - mTagsToRootNodes.replace(node.getReactTag(), node); - } - - public void removeNode(Integer tag) { - mTagsToRootNodes.remove(tag); - } - - public ReactShadowNode getNode(int tag) { - return mTagsToRootNodes.get(tag); - } - -} diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/Scheduler.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/Scheduler.java deleted file mode 100644 index fb199435f..000000000 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/Scheduler.java +++ /dev/null @@ -1,95 +0,0 @@ -package com.facebook.react.fabric; - -import com.facebook.common.logging.FLog; -import com.facebook.react.bridge.ReactContext; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.LinkedBlockingDeque; -import java.util.concurrent.RejectedExecutionException; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; - -/** - * This class allows Native code to schedule work in JS. - * Work (following JS naming) represents a task that needs to be executed in JS. - * - * Four types of work are supported by this class: - * - * Synchronous: - * - Sync work -> flushSync() - * - Work work -> flushSerial() - * - * Asynchronous: - * - Interactive work (serial): -> scheduleSerial() - * - Deferred work: -> scheduleWork() - * - */ -public class Scheduler { - - private static final String TAG = Scheduler.class.getSimpleName(); - // The usage of this executor might change in the near future. - private final ExecutorService mExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingDeque()); - private final ReactContext mReactContext; - - public Scheduler(ReactContext reactContext) { - mReactContext = reactContext; - } - - /** - * This method schedules work to be executed with the lowest priority in the JS Thread. - * - * The current implementation queues "work"s in an unbounded queue tight to a SingleThreadExecutor. - * Work objects are going to be submitted one-by-one at the end of the JS Queue Thread. - * - * Notice that the current implementation might experience some delays in JS work execution, - * depending on the size of the JS Queue and the time it takes to execute each work in JS. - * - * TODO: This implementation is very likely to change in the near future. - */ - public void scheduleWork(final Work work) { - try { - mExecutor.execute(new Runnable() { - @Override - public void run() { - mReactContext.runOnJSQueueThread(new Runnable() { - @Override - public void run() { - try { - work.run(); - } catch (Exception ex) { - FLog.w(TAG, "Exception running work in JS.", ex); - throw ex; - } - } - }); - } - }); - } catch (RejectedExecutionException ex) { - // This can happen if a Work is scheduled when the Scheduler is being shutdown. - // For now, we log and do not take any action. - FLog.i(TAG, "Unable to schedule task."); - } - } - - public void flushSync(Work work) { - // TODO T26717866 this method needs to be implemented. The current implementation is just for - // testing purpose. - } - - public void flushSerial(Work work) { - // TODO T26717866 this method needs to be implemented. The current implementation is just for - // testing purpose. - } - - public void scheduleSerial(Work work) { - // TODO T26717866 this method needs to be implemented. The current implementation is just for - // testing purpose. - } - - /** - * Shutdowns the {@link Scheduler}. this operation will attempt to stop all "active executing" - * Works items and it will "halts:" all the Works items waiting to be executed. - */ - public void shutdown() { - mExecutor.shutdownNow(); - } -} diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/Work.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/Work.java deleted file mode 100644 index a9d0dc3d6..000000000 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/Work.java +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its 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; - -/** - * Interface that represents a task or piece of code that will be executed by {@link Scheduler} - * This follows React API naming for consistency. - */ -public interface Work { - - void run(); - -} - - diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/events/FabricEventEmitter.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/events/FabricEventEmitter.java deleted file mode 100644 index 3f8749bcc..000000000 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/events/FabricEventEmitter.java +++ /dev/null @@ -1,183 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its 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.events; - -import static com.facebook.react.uimanager.events.TouchesHelper.CHANGED_TOUCHES_KEY; -import static com.facebook.react.uimanager.events.TouchesHelper.TARGET_KEY; -import static com.facebook.react.uimanager.events.TouchesHelper.TOP_TOUCH_CANCEL_KEY; -import static com.facebook.react.uimanager.events.TouchesHelper.TOP_TOUCH_END_KEY; -import static com.facebook.react.uimanager.events.TouchesHelper.TOUCHES_KEY; - -import android.annotation.TargetApi; -import android.os.Build; -import android.util.Pair; -import com.facebook.common.logging.FLog; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.bridge.ReadableMap; -import com.facebook.react.bridge.WritableArray; -import com.facebook.react.bridge.WritableMap; -import com.facebook.react.bridge.WritableNativeArray; -import com.facebook.react.bridge.WritableNativeMap; -import com.facebook.react.fabric.FabricUIManager; -import com.facebook.react.fabric.Scheduler; -import com.facebook.react.fabric.Work; -import com.facebook.react.uimanager.IllegalViewOperationException; -import com.facebook.react.uimanager.events.RCTEventEmitter; -import java.io.Closeable; -import java.util.HashSet; -import java.util.Set; -import javax.annotation.Nullable; - -@TargetApi(Build.VERSION_CODES.ECLAIR) -public class FabricEventEmitter implements RCTEventEmitter, Closeable { - - private static final String TAG = FabricEventEmitter.class.getSimpleName(); - - private final FabricUIManager mFabricUIManager; - private final Scheduler mScheduler; - - public FabricEventEmitter(ReactApplicationContext context, FabricUIManager fabricUIManager) { - mScheduler = new Scheduler(context); - mFabricUIManager = fabricUIManager; - } - - @Override - public void receiveEvent(int reactTag, String eventName, @Nullable WritableMap params) { - try { - long eventTarget = mFabricUIManager.getEventTarget(reactTag); - mScheduler.scheduleWork(new FabricUIManagerWork(eventTarget, eventName, params)); - } catch (IllegalViewOperationException e) { - FLog.e(TAG, "Unable to emmit event for tag " + reactTag, e); - } - } - - @Override - public void close() { - mScheduler.shutdown(); - } - - private class FabricUIManagerWork implements Work { - private final long mEventTarget; - private final String mEventName; - private final WritableMap mParams; - - public FabricUIManagerWork(long eventTarget, String eventName, @Nullable WritableMap params) { - mEventTarget = eventTarget; - mEventName = eventName; - mParams = params; - } - - @Override - public void run() { - try { - mFabricUIManager.invoke(mEventTarget, mEventName, mParams); - } catch (Throwable t) { - FLog.e(TAG, "Error sending event " + mEventName, t); - //TODO: manage exception properly - } finally{ - // TODO(dvacca): We need to only release this after all shadow nodes - // have been released. The easiest way would be to adopt the event - // emitter approach from the C++ Fabric. For now, we'll just leak. - // mFabricUIManager.releaseEventTarget(mEventTarget); - } - } - } - - @Override - public void receiveTouches(String eventTopLevelType, WritableArray touches, - WritableArray changedIndices) { - Pair result = - TOP_TOUCH_END_KEY.equalsIgnoreCase(eventTopLevelType) || - TOP_TOUCH_CANCEL_KEY.equalsIgnoreCase(eventTopLevelType) - ? removeTouchesAtIndices(touches, changedIndices) - : touchSubsequence(touches, changedIndices); - - WritableArray changedTouches = result.first; - touches = result.second; - - for (int jj = 0; jj < changedTouches.size(); jj++) { - WritableMap touch = getWritableMap(changedTouches.getMap(jj)); - // Touch objects can fulfill the role of `DOM` `Event` objects if we set - // the `changedTouches`/`touches`. This saves allocations. - touch.putArray(CHANGED_TOUCHES_KEY, changedTouches); - touch.putArray(TOUCHES_KEY, touches); - WritableMap nativeEvent = touch; - int rootNodeID = 0; - int target = nativeEvent.getInt(TARGET_KEY); - if (target < 1) { - FLog.e(TAG,"A view is reporting that a touch occurred on tag zero."); - } else { - rootNodeID = target; - } - receiveEvent(rootNodeID, eventTopLevelType, touch); - } - } - - /** - * Destroys `touches` by removing touch objects at indices `indices`. This is - * to maintain compatibility with W3C touch "end" events, where the active - * touches don't include the set that has just been "ended". - * - * This method was originally in ReactNativeRenderer.js - * - * TODO: this method is a copy from ReactNativeRenderer.removeTouchesAtIndices and it needs - * to be rewritten in a more efficient way, - * - * @param touches {@link WritableArray} Deserialized touch objects. - * @param indices {WritableArray} Indices to remove from `touches`. - * @return {Array} Subsequence of removed touch objects. - */ - private Pair removeTouchesAtIndices(WritableArray touches, WritableArray indices) { - WritableArray rippedOut = new WritableNativeArray(); - // use an unsafe downcast to alias to nullable elements, - // so we can delete and then compact. - WritableArray tempTouches = new WritableNativeArray(); - Set rippedOutIndices = new HashSet<>(); - for (int i = 0; i < indices.size(); i++) { - int index = indices.getInt(i); - rippedOut.pushMap(getWritableMap(touches.getMap(index))); - rippedOutIndices.add(index); - } - for (int j = 0 ; j < touches.size() ; j++) { - if (!rippedOutIndices.contains(j)) { - tempTouches.pushMap(getWritableMap(touches.getMap(j))); - } - } - - return new Pair<>(rippedOut, tempTouches); - } - - /** - * Selects a subsequence of `Touch`es, without destroying `touches`. - * - * This method was originally in ReactNativeRenderer.js - * - * @param touches {@link WritableArray} Deserialized touch objects. - * @param changedIndices {@link WritableArray} Indices by which to pull subsequence. - * @return {Array} Subsequence of touch objects. - */ - private Pair touchSubsequence(WritableArray touches, WritableArray changedIndices) { - WritableArray result = new WritableNativeArray(); - for (int i = 0; i < changedIndices.size(); i++) { - result.pushMap(getWritableMap(touches.getMap(i))); - } - return new Pair<>(result, touches); - } - - /** - * TODO: this is required because the WritableNativeArray.getMap() returns a ReadableMap instead - * of the original writableMap. this will change in the near future. - * - * @param readableMap {@link ReadableMap} source map - */ - private WritableMap getWritableMap(ReadableMap readableMap) { - WritableNativeMap map = new WritableNativeMap(); - map.merge(readableMap); - return map; - } -} diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jsc/BUCK b/ReactAndroid/src/main/java/com/facebook/react/fabric/jsc/BUCK deleted file mode 100644 index 5163ab176..000000000 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jsc/BUCK +++ /dev/null @@ -1,24 +0,0 @@ -load("//tools/build_defs/oss:rn_defs.bzl", "react_native_dep", "react_native_target", "rn_android_library") - -rn_android_library( - name = "jsc", - srcs = glob(["**/*.java"]), - provided_deps = [ - react_native_dep("third-party/android/support/v4:lib-support-v4"), - ], - required_for_source_only_abi = True, - visibility = [ - "PUBLIC", - ], - deps = [ - react_native_dep("libraries/soloader/java/com/facebook/soloader:soloader"), - react_native_dep("third-party/java/infer-annotations:infer-annotations"), - react_native_target("java/com/facebook/react/bridge:bridge"), - react_native_target("java/com/facebook/react/fabric:fabric"), - react_native_target("java/com/facebook/react/fabric/jsc/jni:jni"), - ], - exported_deps = [ - react_native_dep("java/com/facebook/jni:jni"), - react_native_dep("java/com/facebook/proguard/annotations:annotations"), - ], -) diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jsc/FabricJSCBinding.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/jsc/FabricJSCBinding.java deleted file mode 100644 index 24643bf85..000000000 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jsc/FabricJSCBinding.java +++ /dev/null @@ -1,67 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its 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.jsc; - -import com.facebook.jni.HybridData; -import com.facebook.proguard.annotations.DoNotStrip; -import com.facebook.react.bridge.JavaScriptContextHolder; -import com.facebook.react.bridge.UIManager; -import com.facebook.react.fabric.FabricBinder; -import com.facebook.react.fabric.FabricBinding; -import com.facebook.react.fabric.FabricUIManager; -import com.facebook.react.bridge.NativeMap; -import com.facebook.soloader.SoLoader; - -@DoNotStrip -public class FabricJSCBinding implements FabricBinding { - - static { - SoLoader.loadLibrary("fabricjscjni"); - } - - // used from native - @SuppressWarnings("unused") - private final HybridData mHybridData; - - private static native HybridData initHybrid(); - - @Override - public native void releaseEventTarget(long jsContextNativePointer, long eventTargetPointer); - - @Override - public native void releaseEventHandler(long jsContextNativePointer, long eventHandlerPointer); - - @Override - public native void dispatchEventToEmptyTarget( - long jsContextNativePointer, - long eventHandlerPointer, - String type, - NativeMap payload - ); - - @Override - public native void dispatchEventToTarget( - long jsContextNativePointer, - long eventHandlerPointer, - long eventTargetPointer, - String type, - NativeMap payload - ); - - private native void installFabric(long jsContextNativePointer, Object fabricModule); - - public FabricJSCBinding() { - mHybridData = initHybrid(); - } - - @Override - public void installFabric(JavaScriptContextHolder jsContext, FabricBinder fabricModule) { - fabricModule.setBinding(this); - installFabric(jsContext.get(), fabricModule); - } -} diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jsc/jni/BUCK b/ReactAndroid/src/main/java/com/facebook/react/fabric/jsc/jni/BUCK deleted file mode 100644 index 90500506a..000000000 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jsc/jni/BUCK +++ /dev/null @@ -1,21 +0,0 @@ -load("//tools/build_defs/oss:rn_defs.bzl", "ANDROID", "FBJNI_TARGET", "react_native_target", "react_native_xplat_target", "rn_xplat_cxx_library") - -rn_xplat_cxx_library( - name = "jni", - srcs = glob(["*.cpp"]), - headers = glob(["*.h"]), - compiler_flags = [ - "-Wall", - "-fexceptions", - "-std=c++1y", - ], - platforms = ANDROID, - soname = "libfabricjscjni.$(ext)", - visibility = ["PUBLIC"], - deps = [ - FBJNI_TARGET, - "xplat//folly:molly", - react_native_xplat_target("jschelpers:jschelpers"), - react_native_target("jni/react/jni:jni"), - ], -) diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jsc/jni/FabricJSCBinding.cpp b/ReactAndroid/src/main/java/com/facebook/react/fabric/jsc/jni/FabricJSCBinding.cpp deleted file mode 100644 index 3367a9e5e..000000000 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jsc/jni/FabricJSCBinding.cpp +++ /dev/null @@ -1,415 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#include "FabricJSCBinding.h" -#include -#include -#include - -using namespace facebook::jni; - -namespace facebook { -namespace react { - -namespace { - -bool useCustomJSC = false; - -struct JList : public JavaClass { - static constexpr auto kJavaDescriptor = "Ljava/util/List;"; -}; - -struct JShadowNode : public JavaClass { - static constexpr auto kJavaDescriptor = "Lcom/facebook/react/uimanager/ReactShadowNode;"; -}; - -typedef struct FabricJSCUIManager { - FabricJSCUIManager(alias_ref module, JSClassRef classRef, bool customJSC) - : wrapperObjectClassRef(classRef) - , useCustomJSC(customJSC) { - fabricUiManager = make_global(module); - JSC_JSClassRetain(useCustomJSC, wrapperObjectClassRef); - } - global_ref fabricUiManager; - JSClassRef wrapperObjectClassRef; - bool useCustomJSC; - - ~FabricJSCUIManager() { - JSC_JSClassRelease(useCustomJSC, wrapperObjectClassRef); - } -} FabricJSCUIManager; - -jobject makePlainGlobalRef(jobject object) { - // When storing the global reference we need it to be a plain - // pointer. That's why we use plain jni instead of fbjni here. - return Environment::current()->NewGlobalRef(object); -} - -local_ref JSValueToJString(JSContextRef ctx, JSValueRef value) { - JSStringRef strRef = JSC_JSValueToStringCopy(ctx, value, NULL); - const size_t size = JSStringGetMaximumUTF8CStringSize(strRef); - char buffer[size]; - JSStringGetUTF8CString(strRef, buffer, size); - JSC_JSStringRelease(ctx, strRef); - return make_jstring(buffer); -} - -local_ref JSValueToJShadowNode(JSContextRef ctx, JSValueRef value) { - JSObjectRef obj = JSC_JSValueToObject(ctx, value, NULL); - auto node = static_cast(JSC_JSObjectGetPrivate(useCustomJSC, obj)); - return make_local(node); -} - -local_ref JSValueToJList(JSContextRef ctx, JSValueRef value) { - JSObjectRef obj = JSC_JSValueToObject(ctx, value, NULL); - auto node = static_cast(JSC_JSObjectGetPrivate(useCustomJSC, obj)); - return make_local(node); -} - -local_ref JSValueToReadableMapViaJSON(JSContextRef ctx, JSValueRef value) { - JSStringRef jsonRef = JSC_JSValueCreateJSONString(ctx, value, 0, NULL); - size_t size = JSC_JSStringGetLength(ctx, jsonRef); - const JSChar* utf16 = JSC_JSStringGetCharactersPtr(ctx, jsonRef); - std::string json = unicode::utf16toUTF8(utf16, size); - JSC_JSStringRelease(ctx, jsonRef); - folly::dynamic dynamicValue = folly::parseJson(json); - return ReadableNativeMap::newObjectCxxArgs(std::move(dynamicValue)); -} - -JSValueRef ReadableMapToJSValueViaJSON(JSContextRef ctx, NativeMap *map) { - folly::dynamic dynamicValue = map->consume(); - auto json = folly::toJson(dynamicValue); - JSStringRef jsonRef = JSC_JSStringCreateWithUTF8CString(ctx, json.c_str()); - auto value = JSC_JSValueMakeFromJSONString(ctx, jsonRef); - JSC_JSStringRelease(ctx, jsonRef); - return value; -} - -JSValueRef createNode(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef *exception) { - FabricJSCUIManager *managerWrapper = (FabricJSCUIManager *)JSC_JSObjectGetPrivate(useCustomJSC, function); - alias_ref manager = managerWrapper->fabricUiManager; - JSClassRef classRef = managerWrapper->wrapperObjectClassRef; - - static auto createNode = - jni::findClassStatic("com/facebook/react/fabric/FabricUIManager") - ->getMethod(jint, jstring, jint, ReadableNativeMap::javaobject, jlong)>("createNode"); - - int reactTag = (int)JSC_JSValueToNumber(ctx, arguments[0], NULL); - auto viewName = JSValueToJString(ctx, arguments[1]); - int rootTag = (int)JSC_JSValueToNumber(ctx, arguments[2], NULL); - auto props = JSC_JSValueIsNull(ctx, arguments[3]) ? local_ref(nullptr) : - JSValueToReadableMapViaJSON(ctx, arguments[3]);; - auto eventTarget = (void *)arguments[4]; - - auto node = createNode(manager, reactTag, viewName.get(), rootTag, props.get(), (jlong)eventTarget); - - return JSC_JSObjectMake(ctx, classRef, makePlainGlobalRef(node.get())); -} - -JSValueRef cloneNode(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef *exception) { - FabricJSCUIManager *managerWrapper = (FabricJSCUIManager *)JSC_JSObjectGetPrivate(useCustomJSC, function); - alias_ref manager = managerWrapper->fabricUiManager; - JSClassRef classRef = managerWrapper->wrapperObjectClassRef; - - static auto cloneNode = - jni::findClassStatic("com/facebook/react/fabric/FabricUIManager") - ->getMethod(JShadowNode::javaobject)>("cloneNode"); - - auto previousNode = JSValueToJShadowNode(ctx, arguments[0]); - auto newNode = cloneNode(manager, previousNode.get()); - - return JSC_JSObjectMake(ctx, classRef, makePlainGlobalRef(newNode.get())); -} - -JSValueRef cloneNodeWithNewChildren(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef *exception) { - FabricJSCUIManager *managerWrapper = (FabricJSCUIManager *)JSC_JSObjectGetPrivate(useCustomJSC, function); - alias_ref manager = managerWrapper->fabricUiManager; - JSClassRef classRef = managerWrapper->wrapperObjectClassRef; - - static auto cloneNodeWithNewChildren = - jni::findClassStatic("com/facebook/react/fabric/FabricUIManager") - ->getMethod(JShadowNode::javaobject)>("cloneNodeWithNewChildren"); - - auto previousNode = JSValueToJShadowNode(ctx, arguments[0]); - auto newNode = cloneNodeWithNewChildren(manager, previousNode.get()); - - return JSC_JSObjectMake(ctx, classRef, makePlainGlobalRef(newNode.get())); -} - -JSValueRef cloneNodeWithNewProps(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef *exception) { - FabricJSCUIManager *managerWrapper = (FabricJSCUIManager *)JSC_JSObjectGetPrivate(useCustomJSC, function); - alias_ref manager = managerWrapper->fabricUiManager; - JSClassRef classRef = managerWrapper->wrapperObjectClassRef; - - static auto cloneNodeWithNewProps = - jni::findClassStatic("com/facebook/react/fabric/FabricUIManager") - ->getMethod(JShadowNode::javaobject, ReadableNativeMap::javaobject)>("cloneNodeWithNewProps"); - - auto previousNode = JSValueToJShadowNode(ctx, arguments[0]); - auto props = JSValueToReadableMapViaJSON(ctx, arguments[1]); - auto newNode = cloneNodeWithNewProps(manager, previousNode.get(), props.get()); - - return JSC_JSObjectMake(ctx, classRef, makePlainGlobalRef(newNode.get())); -} - -JSValueRef cloneNodeWithNewChildrenAndProps(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef *exception) { - FabricJSCUIManager *managerWrapper = (FabricJSCUIManager *)JSC_JSObjectGetPrivate(useCustomJSC, function); - alias_ref manager = managerWrapper->fabricUiManager; - JSClassRef classRef = managerWrapper->wrapperObjectClassRef; - - static auto cloneNodeWithNewChildrenAndProps = - jni::findClassStatic("com/facebook/react/fabric/FabricUIManager") - ->getMethod(JShadowNode::javaobject, ReadableNativeMap::javaobject)>("cloneNodeWithNewChildrenAndProps"); - - auto previousNode = JSValueToJShadowNode(ctx, arguments[0]); - auto props = JSValueToReadableMapViaJSON(ctx, arguments[1]); - auto newNode = cloneNodeWithNewChildrenAndProps(manager, previousNode.get(), props.get()); - - return JSC_JSObjectMake(ctx, classRef, makePlainGlobalRef(newNode.get())); -} - -JSValueRef appendChild(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef *exception) { - FabricJSCUIManager *managerWrapper = (FabricJSCUIManager *)JSC_JSObjectGetPrivate(useCustomJSC, function); - alias_ref manager = managerWrapper->fabricUiManager; - - static auto appendChild = - jni::findClassStatic("com/facebook/react/fabric/FabricUIManager") - ->getMethod("appendChild"); - - auto parentNode = JSValueToJShadowNode(ctx, arguments[0]); - auto childNode = JSValueToJShadowNode(ctx, arguments[1]); - - appendChild(manager, parentNode.get(), childNode.get()); - - return JSC_JSValueMakeUndefined(ctx); -} - -JSValueRef createChildSet(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef *exception) { - FabricJSCUIManager *managerWrapper = (FabricJSCUIManager *)JSC_JSObjectGetPrivate(useCustomJSC, function); - alias_ref manager = managerWrapper->fabricUiManager; - JSClassRef classRef = managerWrapper->wrapperObjectClassRef; - - static auto createChildSet = - jni::findClassStatic("com/facebook/react/fabric/FabricUIManager") - ->getMethod(jint)>("createChildSet"); - - int rootTag = (int)JSC_JSValueToNumber(ctx, arguments[0], NULL); - auto childSet = createChildSet(manager, rootTag); - - return JSC_JSObjectMake(ctx, classRef, makePlainGlobalRef(childSet.get())); -} - -JSValueRef appendChildToSet(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef *exception) { - FabricJSCUIManager *managerWrapper = (FabricJSCUIManager *)JSC_JSObjectGetPrivate(useCustomJSC, function); - alias_ref manager = managerWrapper->fabricUiManager; - - static auto appendChildToSet = - jni::findClassStatic("com/facebook/react/fabric/FabricUIManager") - ->getMethod("appendChildToSet"); - - auto childSet = JSValueToJList(ctx, arguments[0]); - auto childNode = JSValueToJShadowNode(ctx, arguments[1]); - - appendChildToSet(manager, childSet.get(), childNode.get()); - - return JSC_JSValueMakeUndefined(ctx); -} - -JSValueRef completeRoot(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef *exception) { - FabricJSCUIManager *managerWrapper = (FabricJSCUIManager *)JSC_JSObjectGetPrivate(useCustomJSC, function); - alias_ref manager = managerWrapper->fabricUiManager; - - static auto completeRoot = - jni::findClassStatic("com/facebook/react/fabric/FabricUIManager") - ->getMethod("completeRoot"); - - int rootTag = (int)JSC_JSValueToNumber(ctx, arguments[0], NULL); - auto childSet = JSValueToJList(ctx, arguments[1]); - - completeRoot(manager, rootTag, childSet.get()); - - return JSC_JSValueMakeUndefined(ctx); -} - -JSValueRef registerEventHandler(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef *exception) { - FabricJSCUIManager *managerWrapper = (FabricJSCUIManager *)JSC_JSObjectGetPrivate(useCustomJSC, function); - alias_ref manager = managerWrapper->fabricUiManager; - - static auto registerEventHandler = - jni::findClassStatic("com/facebook/react/fabric/FabricUIManager") - ->getMethod("registerEventHandler"); - - auto eventHandler = arguments[0]; - JSC_JSValueProtect(ctx, eventHandler); - registerEventHandler(manager, (jlong)eventHandler); - - return JSC_JSValueMakeUndefined(ctx); -} - -void finalizeJNIObject(JSObjectRef object) { - // Release whatever global ref object we're storing here. - jobject globalRef = (jobject)JSC_JSObjectGetPrivate(useCustomJSC, object); - Environment::current()->DeleteGlobalRef(globalRef); -} - -void finalizeWrapper(JSObjectRef object) { - FabricJSCUIManager *managerWrapper = (FabricJSCUIManager *)JSC_JSObjectGetPrivate(useCustomJSC, object); - delete managerWrapper; -} - -void addFabricMethod( - JSContextRef context, - jni::alias_ref fabricModule, - JSClassRef nodeClassRef, - JSObjectRef module, - const char *name, - JSObjectCallAsFunctionCallback callback -) { - JSClassDefinition definition = kJSClassDefinitionEmpty; - definition.callAsFunction = callback; - definition.finalize = finalizeWrapper; - JSClassRef classRef = JSC_JSClassCreate(useCustomJSC, &definition); - FabricJSCUIManager *managerWrapper = new FabricJSCUIManager(fabricModule, nodeClassRef, useCustomJSC); - JSObjectRef functionRef = JSC_JSObjectMake(context, classRef, managerWrapper); - JSC_JSClassRelease(useCustomJSC, classRef); - - JSStringRef nameStr = JSC_JSStringCreateWithUTF8CString(context, name); - JSC_JSObjectSetProperty(context, module, nameStr, functionRef, kJSPropertyAttributeNone, NULL); - JSC_JSStringRelease(context, nameStr); -} - -} - -jni::local_ref FabricJSCBinding::initHybrid( - jni::alias_ref) { - return makeCxxInstance(); -} - -void FabricJSCBinding::releaseEventTarget( - jlong jsContextNativePointer, - jlong eventTargetPointer -) { - // This is now a noop. -} - -void FabricJSCBinding::releaseEventHandler( - jlong jsContextNativePointer, - jlong eventHandlerPointer -) { - JSContextRef context = (JSContextRef)jsContextNativePointer; - JSValueRef value = (JSValueRef)((void *)eventHandlerPointer); - // Release this function. - JSC_JSValueUnprotect(context, value); -} - -void FabricJSCBinding::dispatchEventToEmptyTarget( - jlong jsContextNativePointer, - jlong eventHandlerPointer, - std::string type, - NativeMap *payloadMap -) { - JSContextRef context = (JSContextRef)jsContextNativePointer; - JSObjectRef eventHandler = (JSObjectRef)((void *)eventHandlerPointer); - JSValueRef eventTarget = JSC_JSValueMakeNull(context); - - JSObjectRef thisArg = (JSObjectRef)JSC_JSValueMakeUndefined(context); - JSStringRef typeStr = JSC_JSStringCreateWithUTF8CString(context, type.c_str()); - JSValueRef typeRef = JSC_JSValueMakeString(context, typeStr); - JSC_JSStringRelease(context, typeStr); - JSValueRef payloadRef = ReadableMapToJSValueViaJSON(context, payloadMap); - JSValueRef args[] = {eventTarget, typeRef, payloadRef}; - JSValueRef exn; - JSValueRef result = JSC_JSObjectCallAsFunction( - context, - eventHandler, - thisArg, - 3, - args, - &exn - ); - if (!result) { - // TODO: Handle error in exn - } -} - -void FabricJSCBinding::dispatchEventToTarget( - jlong jsContextNativePointer, - jlong eventHandlerPointer, - jlong eventTargetPointer, - std::string type, - NativeMap *payloadMap -) { - JSContextRef context = (JSContextRef)jsContextNativePointer; - JSObjectRef eventHandler = (JSObjectRef)((void *)eventHandlerPointer); - JSObjectRef eventTarget = (JSObjectRef)((void *)eventTargetPointer); - - JSObjectRef thisArg = (JSObjectRef)JSC_JSValueMakeUndefined(context); - JSStringRef typeStr = JSC_JSStringCreateWithUTF8CString(context, type.c_str()); - JSValueRef typeRef = JSC_JSValueMakeString(context, typeStr); - JSC_JSStringRelease(context, typeStr); - JSValueRef payloadRef = ReadableMapToJSValueViaJSON(context, payloadMap); - JSValueRef args[] = {eventTarget, typeRef, payloadRef}; - JSValueRef exn; - JSValueRef result = JSC_JSObjectCallAsFunction( - context, - eventHandler, - thisArg, - 3, - args, - &exn - ); - if (!result) { - // TODO: Handle error in exn - } -} - -void FabricJSCBinding::installFabric(jlong jsContextNativePointer, - jni::alias_ref fabricModule) { - JSContextRef context = (JSContextRef)jsContextNativePointer; - useCustomJSC = facebook::react::isCustomJSCPtr(context); - - JSObjectRef module = JSC_JSObjectMake(context, NULL, NULL); - - // Class definition for wrapper objects around nodes and sets - JSClassDefinition definition = kJSClassDefinitionEmpty; - definition.finalize = finalizeJNIObject; - JSClassRef classRef = JSC_JSClassCreate(useCustomJSC, &definition); - - addFabricMethod(context, fabricModule, classRef, module, "createNode", createNode); - addFabricMethod(context, fabricModule, classRef, module, "cloneNode", cloneNode); - addFabricMethod(context, fabricModule, classRef, module, "cloneNodeWithNewChildren", cloneNodeWithNewChildren); - addFabricMethod(context, fabricModule, classRef, module, "cloneNodeWithNewProps", cloneNodeWithNewProps); - addFabricMethod(context, fabricModule, classRef, module, "cloneNodeWithNewChildrenAndProps", cloneNodeWithNewChildrenAndProps); - - addFabricMethod(context, fabricModule, classRef, module, "appendChild", appendChild); - addFabricMethod(context, fabricModule, classRef, module, "createChildSet", createChildSet); - addFabricMethod(context, fabricModule, classRef, module, "appendChildToSet", appendChildToSet); - addFabricMethod(context, fabricModule, classRef, module, "completeRoot", completeRoot); - - addFabricMethod(context, fabricModule, classRef, module, "registerEventHandler", registerEventHandler); - - JSC_JSClassRelease(useCustomJSC, classRef); - - JSObjectRef globalObject = JSC_JSContextGetGlobalObject(context); - JSStringRef globalName = JSC_JSStringCreateWithUTF8CString(context, "nativeFabricUIManager"); - JSC_JSObjectSetProperty(context, globalObject, globalName, module, kJSPropertyAttributeNone, NULL); - JSC_JSStringRelease(context, globalName); -} - -void FabricJSCBinding::registerNatives() { - registerHybrid({ - makeNativeMethod("initHybrid", FabricJSCBinding::initHybrid), - makeNativeMethod("installFabric", FabricJSCBinding::installFabric), - makeNativeMethod("releaseEventTarget", FabricJSCBinding::releaseEventTarget), - makeNativeMethod("releaseEventHandler", FabricJSCBinding::releaseEventHandler), - makeNativeMethod("dispatchEventToEmptyTarget", FabricJSCBinding::dispatchEventToEmptyTarget), - makeNativeMethod("dispatchEventToTarget", FabricJSCBinding::dispatchEventToTarget), - }); -} - -} -} diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jsc/jni/FabricJSCBinding.h b/ReactAndroid/src/main/java/com/facebook/react/fabric/jsc/jni/FabricJSCBinding.h deleted file mode 100644 index ea5ded688..000000000 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jsc/jni/FabricJSCBinding.h +++ /dev/null @@ -1,54 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -#include -#include -#include - -namespace facebook { -namespace react { - -class Instance; - -class FabricJSCBinding : public jni::HybridClass { -public: - constexpr static const char *const kJavaDescriptor = - "Lcom/facebook/react/fabric/jsc/FabricJSCBinding;"; - - static void registerNatives(); - -private: - - static jni::local_ref initHybrid(jni::alias_ref); - - void releaseEventTarget(jlong jsContextNativePointer, jlong eventTargetPointer); - - void releaseEventHandler(jlong jsContextNativePointer, jlong eventHandlerPointer); - - void dispatchEventToEmptyTarget( - jlong jsContextNativePointer, - jlong eventHandlerPointer, - std::string type, - NativeMap *payload - ); - - void dispatchEventToTarget( - jlong jsContextNativePointer, - jlong eventHandlerPointer, - jlong eventTargetPointer, - std::string type, - NativeMap *payload - ); - - void installFabric(jlong jsContextNativePointer, jni::alias_ref fabricModule); - -}; - -} -} diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jsc/jni/OnLoad.cpp b/ReactAndroid/src/main/java/com/facebook/react/fabric/jsc/jni/OnLoad.cpp deleted file mode 100644 index 7783c8850..000000000 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jsc/jni/OnLoad.cpp +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#include -#include - -#include "FabricJSCBinding.h" - -JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) { - return facebook::xplat::initialize(vm, [] { - facebook::react::FabricJSCBinding::registerNatives(); - }); -} diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/LayoutShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/LayoutShadowNode.java index 5f6a8bd94..1b89228e5 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/LayoutShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/LayoutShadowNode.java @@ -75,16 +75,6 @@ public class LayoutShadowNode extends ReactShadowNodeImpl { mTempYogaValue = new MutableYogaValue(); } - protected LayoutShadowNode(LayoutShadowNode node) { - super(node); - mTempYogaValue = new MutableYogaValue(node.mTempYogaValue); - } - - @Override - protected LayoutShadowNode copy() { - return new LayoutShadowNode(this); - } - @ReactProp(name = ViewProps.WIDTH) public void setWidth(Dynamic width) { if (isVirtual()) { diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNode.java index ec64b8e9f..47c97b11a 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNode.java @@ -68,17 +68,6 @@ public interface ReactShadowNode { */ boolean isYogaLeafNode(); - /** - * @return a mutable copy of the {@link ReactShadowNode} - */ - T mutableCopy(long instanceHandle); - - T mutableCopyWithNewProps(long instanceHandle, @Nullable ReactStylesDiffMap newProps); - - T mutableCopyWithNewChildren(long instanceHandle); - - T mutableCopyWithNewChildrenAndProps(long instanceHandle, @Nullable ReactStylesDiffMap newProps); - String getViewClass(); boolean hasUpdates(); @@ -366,28 +355,5 @@ public interface ReactShadowNode { */ List getChildrenList(); - /** - * @return the {@link ReactShadowNode} that was used during the cloning mechanism to create - * this {@link ReactShadowNode} or null if this object was not created using a clone operation. - */ - @Nullable ReactShadowNode getOriginalReactShadowNode(); - - void setOriginalReactShadowNode(@Nullable ReactShadowNode node); - - long getInstanceHandle(); - - void setInstanceHandle(long instanceHandle); - - /** - * Mark this {@link ReactShadowNode} as sealed. This means that the node was already committed - * and it should not be updated anymore. - */ - void markAsSealed(); - - /** - * @return a {@link boolean} that represents if the {@link ReactShadowNode} is sealed. - */ - boolean isSealed(); - void updateScreenLayout(ReactShadowNode prevNode); } diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNodeImpl.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNodeImpl.java index 5afdbb2dc..2f459eccc 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNodeImpl.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNodeImpl.java @@ -8,14 +8,11 @@ package com.facebook.react.uimanager; import static java.lang.System.arraycopy; -import com.facebook.common.logging.FLog; import com.facebook.debug.holder.PrinterHolder; import com.facebook.debug.tags.ReactDebugOverlayTags; import com.facebook.infer.annotation.Assertions; import com.facebook.react.common.build.ReactBuildConfig; import com.facebook.react.uimanager.annotations.ReactPropertyHolder; -import com.facebook.systrace.Systrace; -import com.facebook.systrace.SystraceMessage; import com.facebook.yoga.YogaAlign; import com.facebook.yoga.YogaBaselineFunction; import com.facebook.yoga.YogaConfig; @@ -27,7 +24,6 @@ import com.facebook.yoga.YogaFlexDirection; import com.facebook.yoga.YogaJustify; import com.facebook.yoga.YogaMeasureFunction; import com.facebook.yoga.YogaNode; -import com.facebook.yoga.YogaNodeCloneFunction; import com.facebook.yoga.YogaOverflow; import com.facebook.yoga.YogaPositionType; import com.facebook.yoga.YogaValue; @@ -67,38 +63,9 @@ public class ReactShadowNodeImpl implements ReactShadowNode private static final boolean DEBUG = ReactBuildConfig.DEBUG || PrinterHolder.getPrinter().shouldDisplayLogMessage(ReactDebugOverlayTags.FABRIC_UI_MANAGER); private static final String TAG = ReactShadowNodeImpl.class.getSimpleName(); private static final YogaConfig sYogaConfig; + static { sYogaConfig = ReactYogaConfigProvider.get(); - sYogaConfig.setOnCloneNode(new YogaNodeCloneFunction() { - @Override - public YogaNode cloneNode(YogaNode oldYogaNode, - YogaNode parent, - int childIndex) { - SystraceMessage.beginSection( - Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, - "FabricReconciler.YogaNodeCloneFunction") - .flush(); - try { - ReactShadowNodeImpl parentReactShadowNode = (ReactShadowNodeImpl) parent.getData(); - Assertions.assertNotNull(parentReactShadowNode); - ReactShadowNodeImpl oldReactShadowNode = (ReactShadowNodeImpl) oldYogaNode.getData(); - Assertions.assertNotNull(oldReactShadowNode); - - if (DEBUG) { - FLog.d( - TAG, - "YogaNode started cloning: oldYogaNode: " + oldReactShadowNode + " - parent: " - + parentReactShadowNode + " index: " + childIndex); - } - - ReactShadowNodeImpl newNode = oldReactShadowNode.mutableCopy(oldReactShadowNode.getInstanceHandle()); - parentReactShadowNode.replaceChild(newNode, childIndex); - return newNode.mYogaNode; - } finally{ - Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE); - } - } - }); } private int mReactTag; @@ -168,94 +135,6 @@ public class ReactShadowNodeImpl implements ReactShadowNode mIsSealed = false; } - private void replaceChild(ReactShadowNodeImpl newNode, int childIndex) { - mChildren.remove(childIndex); - mChildren.add(childIndex, newNode); - newNode.mParent = this; - } - - /** - * @return a copy of this object (no including copy of its children or the underlying yogaNode). - */ - protected ReactShadowNodeImpl copy() { - return new ReactShadowNodeImpl(this); - } - - @Override - public ReactShadowNodeImpl mutableCopy(long instanceHandle) { - ReactShadowNodeImpl copy = copy(); - Assertions.assertCondition( - getClass() == copy.getClass(), - "Copied shadow node must use the same class"); - copy.mInstanceHandle = instanceHandle; - if (mYogaNode != null) { - copy.mYogaNode = mYogaNode.clone(); - copy.mYogaNode.setData(copy); - } else { - // Virtual ReactShadowNode do not have a YogaNode associated - copy.mYogaNode = null; - } - copy.mTotalNativeChildren = mTotalNativeChildren; - copy.mNativeChildren = copyChildren(mNativeChildren); - copy.mChildren = copyChildren(mChildren); - - return copy; - } - - @Nullable - private ArrayList copyChildren(@Nullable List list){ - ArrayList result = list == null ? null : new ArrayList<>(list); - if (result != null) { - for (ReactShadowNodeImpl child : result) { - child.mParent = null; - } - } - return result; - } - - @Override - public ReactShadowNodeImpl mutableCopyWithNewChildren(long instanceHandle) { - ReactShadowNodeImpl copy = copy(); - copy.mInstanceHandle = instanceHandle; - Assertions.assertCondition( - getClass() == copy.getClass(), - "Copied shadow node must use the same class"); - if (mYogaNode != null) { - copy.mYogaNode = mYogaNode.cloneWithNewChildren(); - copy.mYogaNode.setData(copy); - } else { - // Virtual ReactShadowNode do not have a YogaNode associated - copy.mYogaNode = null; - } - copy.mNativeChildren = null; - copy.mChildren = null; - copy.mTotalNativeChildren = 0; - return copy; - } - - @Override - public ReactShadowNodeImpl mutableCopyWithNewProps(long instanceHandle, - @Nullable ReactStylesDiffMap newProps) { - ReactShadowNodeImpl copy = mutableCopy(instanceHandle); - if (newProps != null) { - copy.updateProperties(newProps); - copy.mNewProps = newProps; - } - return copy; - } - - @Override - public ReactShadowNodeImpl mutableCopyWithNewChildrenAndProps(long instanceHandle, - @Nullable ReactStylesDiffMap newProps) { - ReactShadowNodeImpl copy = mutableCopyWithNewChildren(instanceHandle); - if (newProps != null) { - copy.updateProperties(newProps); - copy.mNewProps = newProps; - } - return copy; - } - - /** * Nodes that return {@code true} will be treated as "virtual" nodes. That is, nodes that are not * mapped into native views (e.g. nested text node). By default this method returns {@code false}. @@ -299,7 +178,6 @@ public class ReactShadowNodeImpl implements ReactShadowNode @Override public final void markUpdateSeen() { - assertNotSealed(); mNodeUpdated = false; if (hasNewLayout()) { markLayoutSeen(); @@ -325,7 +203,6 @@ public class ReactShadowNodeImpl implements ReactShadowNode @Override public void dirty() { - assertNotSealed(); if (!isVirtual()) { mYogaNode.dirty(); } @@ -338,7 +215,6 @@ public class ReactShadowNodeImpl implements ReactShadowNode @Override public void addChildAt(ReactShadowNodeImpl child, int i) { - assertNotSealed(); if (mChildren == null) { mChildren = new ArrayList<>(4); } @@ -370,7 +246,6 @@ public class ReactShadowNodeImpl implements ReactShadowNode @Override public ReactShadowNodeImpl removeChildAt(int i) { - assertNotSealed(); if (mChildren == null) { throw new ArrayIndexOutOfBoundsException( "Index " + i + " out of bounds: node has no children"); @@ -543,7 +418,6 @@ public class ReactShadowNodeImpl implements ReactShadowNode @Override public void setReactTag(int reactTag) { - assertNotSealed(); mReactTag = reactTag; } @@ -555,13 +429,11 @@ public class ReactShadowNodeImpl implements ReactShadowNode @Override public final void setRootTag(int rootTag) { - assertNotSealed(); mRootTag = rootTag; } @Override public final void setViewClassName(String viewClassName) { - assertNotSealed(); mViewClassName = viewClassName; } @@ -603,7 +475,6 @@ public class ReactShadowNodeImpl implements ReactShadowNode @Override public final void markLayoutSeen() { - assertNotSealed(); if (mYogaNode != null) { mYogaNode.markLayoutSeen(); } @@ -615,7 +486,6 @@ public class ReactShadowNodeImpl implements ReactShadowNode */ @Override public final void addNativeChildAt(ReactShadowNodeImpl child, int nativeIndex) { - assertNotSealed(); Assertions.assertCondition(!mIsLayoutOnly); Assertions.assertCondition(!child.mIsLayoutOnly); @@ -667,7 +537,6 @@ public class ReactShadowNodeImpl implements ReactShadowNode */ @Override public final void setIsLayoutOnly(boolean isLayoutOnly) { - assertNotSealed(); Assertions.assertCondition(getParent() == null, "Must remove from no opt parent first"); Assertions.assertCondition(mNativeParent == null, "Must remove from native parent first"); Assertions.assertCondition(getNativeChildCount() == 0, "Must remove all native children first"); @@ -816,7 +685,6 @@ public class ReactShadowNodeImpl implements ReactShadowNode @Override public void setLayoutDirection(YogaDirection direction) { - assertNotSealed(); mYogaNode.setDirection(direction); } @@ -827,43 +695,36 @@ public class ReactShadowNodeImpl implements ReactShadowNode @Override public void setStyleWidth(float widthPx) { - assertNotSealed(); mYogaNode.setWidth(widthPx); } @Override public void setStyleWidthPercent(float percent) { - assertNotSealed(); mYogaNode.setWidthPercent(percent); } @Override public void setStyleWidthAuto() { - assertNotSealed(); mYogaNode.setWidthAuto(); } @Override public void setStyleMinWidth(float widthPx) { - assertNotSealed(); mYogaNode.setMinWidth(widthPx); } @Override public void setStyleMinWidthPercent(float percent) { - assertNotSealed(); mYogaNode.setMinWidthPercent(percent); } @Override public void setStyleMaxWidth(float widthPx) { - assertNotSealed(); mYogaNode.setMaxWidth(widthPx); } @Override public void setStyleMaxWidthPercent(float percent) { - assertNotSealed(); mYogaNode.setMaxWidthPercent(percent); } @@ -874,151 +735,126 @@ public class ReactShadowNodeImpl implements ReactShadowNode @Override public void setStyleHeight(float heightPx) { - assertNotSealed(); mYogaNode.setHeight(heightPx); } @Override public void setStyleHeightPercent(float percent) { - assertNotSealed(); mYogaNode.setHeightPercent(percent); } @Override public void setStyleHeightAuto() { - assertNotSealed(); mYogaNode.setHeightAuto(); } @Override public void setStyleMinHeight(float widthPx) { - assertNotSealed(); mYogaNode.setMinHeight(widthPx); } @Override public void setStyleMinHeightPercent(float percent) { - assertNotSealed(); mYogaNode.setMinHeightPercent(percent); } @Override public void setStyleMaxHeight(float widthPx) { - assertNotSealed(); mYogaNode.setMaxHeight(widthPx); } @Override public void setStyleMaxHeightPercent(float percent) { - assertNotSealed(); mYogaNode.setMaxHeightPercent(percent); } @Override public void setFlex(float flex) { - assertNotSealed(); mYogaNode.setFlex(flex); } @Override public void setFlexGrow(float flexGrow) { - assertNotSealed(); mYogaNode.setFlexGrow(flexGrow); } @Override public void setFlexShrink(float flexShrink) { - assertNotSealed(); mYogaNode.setFlexShrink(flexShrink); } @Override public void setFlexBasis(float flexBasis) { - assertNotSealed(); mYogaNode.setFlexBasis(flexBasis); } @Override public void setFlexBasisAuto() { - assertNotSealed(); mYogaNode.setFlexBasisAuto(); } @Override public void setFlexBasisPercent(float percent) { - assertNotSealed(); mYogaNode.setFlexBasisPercent(percent); } @Override public void setStyleAspectRatio(float aspectRatio) { - assertNotSealed(); mYogaNode.setAspectRatio(aspectRatio); } @Override public void setFlexDirection(YogaFlexDirection flexDirection) { - assertNotSealed(); mYogaNode.setFlexDirection(flexDirection); } @Override public void setFlexWrap(YogaWrap wrap) { - assertNotSealed(); mYogaNode.setWrap(wrap); } @Override public void setAlignSelf(YogaAlign alignSelf) { - assertNotSealed(); mYogaNode.setAlignSelf(alignSelf); } @Override public void setAlignItems(YogaAlign alignItems) { - assertNotSealed(); mYogaNode.setAlignItems(alignItems); } @Override public void setAlignContent(YogaAlign alignContent) { - assertNotSealed(); mYogaNode.setAlignContent(alignContent); } @Override public void setJustifyContent(YogaJustify justifyContent) { - assertNotSealed(); mYogaNode.setJustifyContent(justifyContent); } @Override public void setOverflow(YogaOverflow overflow) { - assertNotSealed(); mYogaNode.setOverflow(overflow); } @Override public void setDisplay(YogaDisplay display) { - assertNotSealed(); mYogaNode.setDisplay(display); } @Override public void setMargin(int spacingType, float margin) { - assertNotSealed(); mYogaNode.setMargin(YogaEdge.fromInt(spacingType), margin); } @Override public void setMarginPercent(int spacingType, float percent) { - assertNotSealed(); mYogaNode.setMarginPercent(YogaEdge.fromInt(spacingType), percent); } @Override public void setMarginAuto(int spacingType) { - assertNotSealed(); mYogaNode.setMarginAuto(YogaEdge.fromInt(spacingType)); } @@ -1034,14 +870,12 @@ public class ReactShadowNodeImpl implements ReactShadowNode @Override public void setDefaultPadding(int spacingType, float padding) { - assertNotSealed(); mDefaultPadding.set(spacingType, padding); updatePadding(); } @Override public void setPadding(int spacingType, float padding) { - assertNotSealed(); mPadding[spacingType] = padding; mPaddingIsPercent[spacingType] = false; updatePadding(); @@ -1049,14 +883,12 @@ public class ReactShadowNodeImpl implements ReactShadowNode @Override public void setPaddingPercent(int spacingType, float percent) { - assertNotSealed(); mPadding[spacingType] = percent; mPaddingIsPercent[spacingType] = !YogaConstants.isUndefined(percent); updatePadding(); } private void updatePadding() { - assertNotSealed(); for (int spacingType = Spacing.LEFT; spacingType <= Spacing.ALL; spacingType++) { if (spacingType == Spacing.LEFT || spacingType == Spacing.RIGHT @@ -1092,43 +924,36 @@ public class ReactShadowNodeImpl implements ReactShadowNode @Override public void setBorder(int spacingType, float borderWidth) { - assertNotSealed(); mYogaNode.setBorder(YogaEdge.fromInt(spacingType), borderWidth); } @Override public void setPosition(int spacingType, float position) { - assertNotSealed(); mYogaNode.setPosition(YogaEdge.fromInt(spacingType), position); } @Override public void setPositionPercent(int spacingType, float percent) { - assertNotSealed(); mYogaNode.setPositionPercent(YogaEdge.fromInt(spacingType), percent); } @Override public void setPositionType(YogaPositionType positionType) { - assertNotSealed(); mYogaNode.setPositionType(positionType); } @Override public void setShouldNotifyOnLayout(boolean shouldNotifyOnLayout) { - assertNotSealed(); mShouldNotifyOnLayout = shouldNotifyOnLayout; } @Override public void setBaselineFunction(YogaBaselineFunction baselineFunction) { - assertNotSealed(); mYogaNode.setBaselineFunction(baselineFunction); } @Override public void setMeasureFunction(YogaMeasureFunction measureFunction) { - assertNotSealed(); mYogaNode.setMeasureFunction(measureFunction); } @@ -1184,43 +1009,6 @@ public class ReactShadowNodeImpl implements ReactShadowNode return mChildren == null ? null : Collections.unmodifiableList(mChildren); } - @Override - public ReactShadowNode getOriginalReactShadowNode() { - return mOriginalReactShadowNode; - } - - @Override - public void setOriginalReactShadowNode(ReactShadowNode node) { - mOriginalReactShadowNode = node; - } - - @Override - public long getInstanceHandle() { - return mInstanceHandle; - } - - @Override - public void setInstanceHandle(long instanceHandle) { - assertNotSealed(); - mInstanceHandle = instanceHandle; - } - - @Override - public void markAsSealed() { - mIsSealed = true; - } - - @Override - public boolean isSealed() { - return mIsSealed; - } - - private void assertNotSealed() { - if (mIsSealed) { - throw new IllegalStateException("Can not modify sealed node " + toString()); - } - } - @Override public void updateScreenLayout(ReactShadowNode prevNode) { mScreenHeight = prevNode.getScreenHeight(); diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTGroupShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTGroupShadowNode.java index 7bd25a750..9c97a6127 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTGroupShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTGroupShadowNode.java @@ -28,11 +28,6 @@ public class ARTGroupShadowNode extends ARTVirtualNode { public ARTGroupShadowNode() { } - public ARTGroupShadowNode(ARTGroupShadowNode node) { - super(node); - this.mClipping = new RectF(node.mClipping); - } - @ReactProp(name = "clipping") public void setClipping(@Nullable ReadableArray clippingDims) { float[] clippingData = PropHelper.toFloatArray(clippingDims); @@ -42,11 +37,6 @@ public class ARTGroupShadowNode extends ARTVirtualNode { } } - @Override - protected ReactShadowNodeImpl copy() { - return new ARTGroupShadowNode(this); - } - @Override public boolean isVirtual() { return true; diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTShapeShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTShapeShadowNode.java index cad8b55b7..5cd54338b 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTShapeShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTShapeShadowNode.java @@ -60,22 +60,6 @@ public class ARTShapeShadowNode extends ARTVirtualNode { public ARTShapeShadowNode() { } - public ARTShapeShadowNode(ARTShapeShadowNode node) { - super(node); - mPath = new Path(node.mPath); - mStrokeColor = copyArray(node.mStrokeColor); - mBrushData = copyArray(node.mBrushData); - mStrokeDash = copyArray(node.mStrokeDash); - mStrokeWidth = node.mStrokeWidth; - mStrokeCap = node.mStrokeCap; - mStrokeJoin = node.mStrokeJoin; - } - - @Override - protected ARTShapeShadowNode copy() { - return new ARTShapeShadowNode(this); - } - @ReactProp(name = "d") public void setShapePath(@Nullable ReadableArray shapePath) { float[] pathData = PropHelper.toFloatArray(shapePath); diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTTextShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTTextShadowNode.java index b5b98abcc..c5e60563a 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTTextShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTTextShadowNode.java @@ -42,17 +42,6 @@ public class ARTTextShadowNode extends ARTShapeShadowNode { public ARTTextShadowNode() { } - public ARTTextShadowNode(ARTTextShadowNode node) { - super(node); - mTextAlignment = node.mTextAlignment; - mFrame = node.mFrame; // copy reference as mFrame is already immutable - } - - @Override - protected ARTShapeShadowNode copy() { - return new ARTTextShadowNode(this); - } - @ReactProp(name = "frame") public void setFrame(@Nullable ReadableMap frame) { mFrame = frame; diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTVirtualNode.java b/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTVirtualNode.java index 1a633f58f..cb1a304fe 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTVirtualNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTVirtualNode.java @@ -37,13 +37,6 @@ public abstract class ARTVirtualNode extends ReactShadowNodeImpl { mScale = DisplayMetricsHolder.getWindowDisplayMetrics().density; } - protected ARTVirtualNode(ARTVirtualNode artVirtualNode) { - super(artVirtualNode); - mScale = artVirtualNode.mScale; - mOpacity = artVirtualNode.mOpacity; - mMatrix = new Matrix(artVirtualNode.mMatrix); - } - @Override public boolean isVirtual() { return true; diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/modal/ModalHostShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/views/modal/ModalHostShadowNode.java index c1f4ed2b9..0e0fd429a 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/modal/ModalHostShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/modal/ModalHostShadowNode.java @@ -23,15 +23,6 @@ class ModalHostShadowNode extends LayoutShadowNode { public ModalHostShadowNode() {} - private ModalHostShadowNode(ModalHostShadowNode node) { - super(node); - } - - @Override - protected ModalHostShadowNode copy() { - return new ModalHostShadowNode(this); - } - /** * We need to set the styleWidth and styleHeight of the one child (represented by the * within the in Modal.js. This needs to fill the entire window. diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/progressbar/ProgressBarShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/views/progressbar/ProgressBarShadowNode.java index 79a1b2336..e6cb2adce 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/progressbar/ProgressBarShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/progressbar/ProgressBarShadowNode.java @@ -7,23 +7,19 @@ package com.facebook.react.views.progressbar; -import com.facebook.react.uimanager.ReactShadowNodeImpl; -import javax.annotation.Nullable; - -import java.util.HashSet; -import java.util.Set; - import android.util.SparseIntArray; import android.view.View; import android.view.ViewGroup; import android.widget.ProgressBar; - -import com.facebook.yoga.YogaMeasureMode; -import com.facebook.yoga.YogaMeasureFunction; -import com.facebook.yoga.YogaNode; -import com.facebook.yoga.YogaMeasureOutput; import com.facebook.react.uimanager.LayoutShadowNode; import com.facebook.react.uimanager.annotations.ReactProp; +import com.facebook.yoga.YogaMeasureFunction; +import com.facebook.yoga.YogaMeasureMode; +import com.facebook.yoga.YogaMeasureOutput; +import com.facebook.yoga.YogaNode; +import java.util.HashSet; +import java.util.Set; +import javax.annotation.Nullable; /** * Node responsible for holding the style of the ProgressBar, see under @@ -45,36 +41,10 @@ public class ProgressBarShadowNode extends LayoutShadowNode implements YogaMeasu initMeasureFunction(); } - public ProgressBarShadowNode(ProgressBarShadowNode node) { - super(node); - mWidth = node.mWidth.clone(); - mHeight = node.mHeight.clone(); - mMeasured = new HashSet<>(node.mMeasured); - } - - @Override - public ReactShadowNodeImpl mutableCopyWithNewChildren(long instanceHandle) { - ProgressBarShadowNode node = (ProgressBarShadowNode) super.mutableCopyWithNewChildren(instanceHandle); - node.initMeasureFunction(); - return node; - } - private void initMeasureFunction() { setMeasureFunction(this); } - @Override - public ReactShadowNodeImpl mutableCopy(long instanceHandle) { - ProgressBarShadowNode node = (ProgressBarShadowNode) super.mutableCopy(instanceHandle); - node.initMeasureFunction(); - return node; - } - - @Override - public ProgressBarShadowNode copy() { - return new ProgressBarShadowNode(this); - } - public @Nullable String getStyle() { return mStyle; } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/slider/ReactSliderManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/slider/ReactSliderManager.java index a77386e0c..d4736a17f 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/slider/ReactSliderManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/slider/ReactSliderManager.java @@ -51,36 +51,10 @@ public class ReactSliderManager extends SimpleViewManager { initMeasureFunction(); } - private ReactSliderShadowNode(ReactSliderShadowNode node) { - super(node); - mWidth = node.mWidth; - mHeight = node.mHeight; - mMeasured = node.mMeasured; - } - private void initMeasureFunction() { setMeasureFunction(this); } - @Override - public ReactShadowNodeImpl mutableCopy(long instanceHandle) { - ReactSliderShadowNode reactShadowNode = (ReactSliderShadowNode) super.mutableCopy(instanceHandle); - reactShadowNode.initMeasureFunction(); - return reactShadowNode; - } - - @Override - public ReactShadowNodeImpl mutableCopyWithNewChildren(long instanceHandle) { - ReactSliderShadowNode reactShadowNode = (ReactSliderShadowNode) super.mutableCopyWithNewChildren(instanceHandle); - reactShadowNode.initMeasureFunction(); - return reactShadowNode; - } - - @Override - protected ReactSliderShadowNode copy() { - return new ReactSliderShadowNode(this); - } - @Override public long measure( YogaNode node, diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/switchview/ReactSwitchManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/switchview/ReactSwitchManager.java index 6556fa17d..1f7808c1b 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/switchview/ReactSwitchManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/switchview/ReactSwitchManager.java @@ -44,36 +44,10 @@ public class ReactSwitchManager extends SimpleViewManager { initMeasureFunction(); } - private ReactSwitchShadowNode(ReactSwitchShadowNode node) { - super(node); - mWidth = node.mWidth; - mHeight = node.mHeight; - mMeasured = node.mMeasured; - } - private void initMeasureFunction() { setMeasureFunction(this); } - @Override - public ReactShadowNodeImpl mutableCopy(long instanceHandle) { - ReactSwitchShadowNode reactShadowNode = (ReactSwitchShadowNode) super.mutableCopy(instanceHandle); - reactShadowNode.initMeasureFunction(); - return reactShadowNode; - } - - @Override - public ReactShadowNodeImpl mutableCopyWithNewChildren(long instanceHandle) { - ReactSwitchShadowNode reactShadowNode = (ReactSwitchShadowNode) super.mutableCopyWithNewChildren(instanceHandle); - reactShadowNode.initMeasureFunction(); - return reactShadowNode; - } - - @Override - protected ReactSwitchShadowNode copy() { - return new ReactSwitchShadowNode(this); - } - @Override public long measure( YogaNode node, diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java index deb476b64..b2772a60b 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java @@ -302,38 +302,6 @@ public abstract class ReactBaseTextShadowNode extends LayoutShadowNode { public ReactBaseTextShadowNode() {} - public ReactBaseTextShadowNode(ReactBaseTextShadowNode node) { - super(node); - mLineHeight = node.mLineHeight; - mIsColorSet = node.mIsColorSet; - mAllowFontScaling = node.mAllowFontScaling; - mColor = node.mColor; - mIsBackgroundColorSet = node.mIsBackgroundColorSet; - mBackgroundColor = node.mBackgroundColor; - - mNumberOfLines = node.mNumberOfLines; - mFontSize = node.mFontSize; - mFontSizeInput = node.mFontSizeInput; - mLineHeightInput = node.mLineHeightInput; - mTextAlign = node.mTextAlign; - mTextBreakStrategy = node.mTextBreakStrategy; - mTextTransform = node.mTextTransform; - - mTextShadowOffsetDx = node.mTextShadowOffsetDx; - mTextShadowOffsetDy = node.mTextShadowOffsetDy; - mTextShadowRadius = node.mTextShadowRadius; - mTextShadowColor = node.mTextShadowColor; - - mIsUnderlineTextDecorationSet = node.mIsUnderlineTextDecorationSet; - mIsLineThroughTextDecorationSet = node.mIsLineThroughTextDecorationSet; - mIncludeFontPadding = node.mIncludeFontPadding; - mFontStyle = node.mFontStyle; - mFontWeight = node.mFontWeight; - mFontFamily = node.mFontFamily; - mContainsImages = node.mContainsImages; - mHeightOfTallestInlineImage = node.mHeightOfTallestInlineImage; - } - // Returns a line height which takes into account the requested line height // and the height of the inline images. public float getEffectiveLineHeight() { diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactRawTextShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactRawTextShadowNode.java index 0805e8949..aa389fdcf 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactRawTextShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactRawTextShadowNode.java @@ -24,16 +24,6 @@ public class ReactRawTextShadowNode extends ReactShadowNodeImpl { public ReactRawTextShadowNode() { } - private ReactRawTextShadowNode(ReactRawTextShadowNode node) { - super(node); - this.mText = node.mText; - } - - @Override - protected ReactShadowNodeImpl copy() { - return new ReactRawTextShadowNode(this); - } - @ReactProp(name = PROP_TEXT) public void setText(@Nullable String text) { mText = text; diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextInlineImageShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextInlineImageShadowNode.java index d5666f3ba..83a436c46 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextInlineImageShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextInlineImageShadowNode.java @@ -23,8 +23,4 @@ public abstract class ReactTextInlineImageShadowNode extends LayoutShadowNode { public ReactTextInlineImageShadowNode() {} - protected ReactTextInlineImageShadowNode(ReactTextInlineImageShadowNode node) { - super(node); - } - } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextShadowNode.java index c99a4becc..14855f968 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextShadowNode.java @@ -158,36 +158,12 @@ public class ReactTextShadowNode extends ReactBaseTextShadowNode { initMeasureFunction(); } - private ReactTextShadowNode(ReactTextShadowNode node) { - super(node); - this.mPreparedSpannableText = node.mPreparedSpannableText; - } - private void initMeasureFunction() { if (!isVirtual()) { setMeasureFunction(mTextMeasureFunction); } } - @Override - protected LayoutShadowNode copy() { - return new ReactTextShadowNode(this); - } - - @Override - public ReactShadowNodeImpl mutableCopy(long instanceHandle) { - ReactTextShadowNode copy = (ReactTextShadowNode) super.mutableCopy(instanceHandle); - copy.initMeasureFunction(); - return copy; - } - - @Override - public ReactShadowNodeImpl mutableCopyWithNewChildren(long instanceHandle) { - ReactTextShadowNode copy = (ReactTextShadowNode) super.mutableCopyWithNewChildren(instanceHandle); - copy.initMeasureFunction(); - return copy; - } - // Return text alignment according to LTR or RTL style private int getTextAlign() { int textAlign = mTextAlign; diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactVirtualTextShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactVirtualTextShadowNode.java index 971404ca7..094db58bb 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactVirtualTextShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactVirtualTextShadowNode.java @@ -17,12 +17,4 @@ public class ReactVirtualTextShadowNode extends ReactBaseTextShadowNode { public ReactVirtualTextShadowNode() { } - private ReactVirtualTextShadowNode(ReactVirtualTextShadowNode node) { - super(node); - } - - @Override - protected ReactVirtualTextShadowNode copy() { - return new ReactVirtualTextShadowNode(this); - } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/frescosupport/FrescoBasedReactTextInlineImageShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/frescosupport/FrescoBasedReactTextInlineImageShadowNode.java index dda8eb6f4..9a065eb20 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/frescosupport/FrescoBasedReactTextInlineImageShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/frescosupport/FrescoBasedReactTextInlineImageShadowNode.java @@ -50,22 +50,6 @@ public class FrescoBasedReactTextInlineImageShadowNode extends ReactTextInlineIm mCallerContext = callerContext; } - private FrescoBasedReactTextInlineImageShadowNode(FrescoBasedReactTextInlineImageShadowNode node) { - super(node); - mHeaders = node.mHeaders; // mHeaders is immutable - mWidth = node.mWidth; - mHeight = node.mHeight; - mTintColor = node.mTintColor; - mDraweeControllerBuilder = node.mDraweeControllerBuilder; - mCallerContext = node.mCallerContext; - mUri = node.mUri; - } - - @Override - protected FrescoBasedReactTextInlineImageShadowNode copy() { - return new FrescoBasedReactTextInlineImageShadowNode(this); - } - @ReactProp(name = "src") public void setSource(@Nullable ReadableArray sources) { final String source = diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputShadowNode.java index 3e81e6831..c009dfbcc 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputShadowNode.java @@ -54,44 +54,10 @@ public class ReactTextInputShadowNode extends ReactBaseTextShadowNode initMeasureFunction(); } - private ReactTextInputShadowNode(ReactTextInputShadowNode node) { - super(node); - mMostRecentEventCount = node.mMostRecentEventCount; - mText = node.mText; - mLocalData = node.mLocalData; - } - - @Override - protected ReactTextInputShadowNode copy() { - return new ReactTextInputShadowNode(this); - } - - @Override - public ReactTextInputShadowNode mutableCopy(long instanceHandle) { - ReactTextInputShadowNode node = (ReactTextInputShadowNode) super.mutableCopy(instanceHandle); - node.initMeasureFunction(); - ThemedReactContext themedContext = getThemedContext(); - if (themedContext != null) { - node.setThemedContext(themedContext); - } - return node; - } - private void initMeasureFunction() { setMeasureFunction(this); } - @Override - public ReactTextInputShadowNode mutableCopyWithNewChildren(long instanceHandle) { - ReactTextInputShadowNode node = (ReactTextInputShadowNode) super.mutableCopyWithNewChildren(instanceHandle); - node.initMeasureFunction(); - ThemedReactContext themedContext = getThemedContext(); - if (themedContext != null) { - node.setThemedContext(themedContext); - } - return node; - } - @Override public void setThemedContext(ThemedReactContext themedContext) { super.setThemedContext(themedContext); diff --git a/ReactAndroid/src/test/java/com/facebook/react/fabric/BUCK b/ReactAndroid/src/test/java/com/facebook/react/fabric/BUCK deleted file mode 100644 index 7470610e7..000000000 --- a/ReactAndroid/src/test/java/com/facebook/react/fabric/BUCK +++ /dev/null @@ -1,40 +0,0 @@ -load("//tools/build_defs/oss:rn_defs.bzl", "IS_OSS_BUILD", "react_native_dep", "react_native_target", "react_native_tests_target", "rn_robolectric_test") - -rn_robolectric_test( - name = "fabric", - srcs = glob(["**/*.java"]), - contacts = ["oncall+fbandroid_sheriff@xmail.facebook.com"], - resources = glob([ - "**/*.txt", - "**/*.json", - ]), - visibility = [ - "PUBLIC", - ], - deps = [ - "xplat//yoga/java:java", - react_native_dep("third-party/java/assertj:assertj-core"), - react_native_dep("third-party/java/fest:fest"), - react_native_dep("third-party/java/fest:fest_android"), - react_native_dep("third-party/java/guava:guava"), - react_native_dep("third-party/java/jackson:jackson"), - react_native_dep("third-party/java/jsr-305:jsr-305"), - react_native_dep("third-party/java/jsr-330:jsr-330"), - react_native_dep("third-party/java/junit:junit"), - react_native_dep("third-party/java/mockito:mockito"), - react_native_dep("third-party/java/robolectric3/robolectric:robolectric"), - react_native_dep("libraries/fbcore/src/test/java/com/facebook/powermock:powermock"), - react_native_dep("libraries/soloader/java/com/facebook/soloader:soloader"), - react_native_dep("third-party/android/support/v4:lib-support-v4"), - react_native_target("java/com/facebook/react:react"), - react_native_target("java/com/facebook/react/bridge:bridge"), - react_native_target("java/com/facebook/react/common:common"), - react_native_target("java/com/facebook/react/fabric:fabric"), - react_native_target("java/com/facebook/react/modules/core:core"), - react_native_target("java/com/facebook/react/uimanager:uimanager"), - react_native_target("java/com/facebook/react/views/text:text"), - react_native_target("java/com/facebook/react/views/view:view"), - react_native_target("java/com/facebook/react/views/progressbar:progressbar"), - react_native_tests_target("java/com/facebook/react/bridge:testhelpers"), - ], -) if not IS_OSS_BUILD else None diff --git a/ReactAndroid/src/test/java/com/facebook/react/fabric/FabricReconcilerTest.java b/ReactAndroid/src/test/java/com/facebook/react/fabric/FabricReconcilerTest.java deleted file mode 100644 index 768d8f829..000000000 --- a/ReactAndroid/src/test/java/com/facebook/react/fabric/FabricReconcilerTest.java +++ /dev/null @@ -1,205 +0,0 @@ -// Copyright (c) Facebook, Inc. and its 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; - -import static org.fest.assertions.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; - -import com.facebook.react.bridge.CatalystInstance; -import com.facebook.react.bridge.JavaScriptContextHolder; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.bridge.ReactTestHelper; -import com.facebook.react.uimanager.events.EventDispatcher; -import com.facebook.react.uimanager.NativeViewHierarchyManager; -import com.facebook.react.uimanager.ReactShadowNode; -import com.facebook.react.uimanager.ReactShadowNodeImpl; -import com.facebook.react.uimanager.ThemedReactContext; -import com.facebook.react.uimanager.UIViewOperationQueue; -import com.facebook.react.uimanager.ViewAtIndex; -import com.facebook.react.uimanager.ViewManager; -import com.facebook.react.uimanager.ViewManagerRegistry; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; - -/** Tests {@link FabricReconciler} */ -@RunWith(RobolectricTestRunner.class) -public class FabricReconcilerTest { - - private FabricReconciler mFabricReconciler; - private FabricUIManager mFabricUIManager; - private MockUIViewOperationQueue mMockUIViewOperationQueue; - - @Before - public void setUp() { - CatalystInstance catalystInstance = ReactTestHelper.createMockCatalystInstance(); - ReactApplicationContext reactContext = - new ReactApplicationContext(RuntimeEnvironment.application); - reactContext.initializeWithInstance(catalystInstance); - List viewManagers = new ArrayList<>(); - ViewManagerRegistry viewManagerRegistry = new ViewManagerRegistry(viewManagers); - JavaScriptContextHolder jsContext = mock(JavaScriptContextHolder.class); - EventDispatcher eventDispatcher = mock(EventDispatcher.class); - mFabricUIManager = new FabricUIManager(reactContext, viewManagerRegistry, jsContext, eventDispatcher); - mMockUIViewOperationQueue = new MockUIViewOperationQueue(reactContext); - mFabricReconciler = new FabricReconciler(mMockUIViewOperationQueue); - } - - @Test - public void testSimpleHierarchy() { - ReactShadowNode parent = createNode(0); - ReactShadowNode child1 = createNode(1); - ReactShadowNode child2 = createNode(2); - addChildren(parent, child1, child2); - - ReactShadowNode parentCloned = createNode(0); - ReactShadowNode child3 = createNode(3); - addChildren(parentCloned, child3, child2); - - mFabricReconciler.manageChildren(parent, parentCloned); - - List expectedOperations = new ArrayList<>(); - expectedOperations.add( - new ManageChildrenOperation( - 0, - new int[] {0, 1}, - new ViewAtIndex[] {new ViewAtIndex(3, 0), new ViewAtIndex(2, 1)}, - new int[] {1})); - assertThat(mMockUIViewOperationQueue.getOperations()).isEqualTo(expectedOperations); - } - - @Test - public void testVirtualNodes() { - ReactShadowNode parent = createNode(0); - ReactShadowNode child1 = createVirtualNode(1); - ReactShadowNode child2 = createVirtualNode(2); - ReactShadowNode child3 = createVirtualNode(3); - addChildren(parent, child1, child2, child3); - - ReactShadowNode parentCloned = createNode(0); - ReactShadowNode child4 = createVirtualNode(4); - addChildren(parentCloned, child1, child4, child3); - - mFabricReconciler.manageChildren(parent, parentCloned); - - List expectedOperations = new ArrayList<>(); - assertThat(mMockUIViewOperationQueue.getOperations()).isEqualTo(expectedOperations); - } - - private void addChildren(ReactShadowNode parent, ReactShadowNode... children) { - for (ReactShadowNode child : children) { - mFabricUIManager.appendChild(parent, child); - } - } - - private static ReactShadowNode createNode(int tag) { - return createNode(tag, false); - } - - private static ReactShadowNode createVirtualNode(int tag) { - return createNode(tag, true); - } - - private static ReactShadowNode createNode(int tag, boolean virtual) { - ReactShadowNode node; - if (virtual) { - node = new VirtualReactShadowNode(); - } else { - node = new ReactShadowNodeImpl(); - } - node.setReactTag(tag); - node.setViewClassName("View"); - node.setThemedContext(mock(ThemedReactContext.class)); - return node; - } - - private static class VirtualReactShadowNode extends ReactShadowNodeImpl { - - VirtualReactShadowNode() {} - - VirtualReactShadowNode(VirtualReactShadowNode original) { - super(original); - } - - @Override - public boolean isVirtual() { - return true; - } - - @Override - public ReactShadowNodeImpl copy() { - return new VirtualReactShadowNode(this); - } - } - - private static class ManageChildrenOperation { - private int mTag; - private int[] mIndicesToRemove; - private ViewAtIndex[] mViewsToAdd; - private int[] mTagsToRemove; - - private ManageChildrenOperation( - int tag, int[] indicesToRemove, ViewAtIndex[] viewsToAdd, int[] tagsToRemove) { - mTag = tag; - mIndicesToRemove = indicesToRemove; - mViewsToAdd = viewsToAdd; - mTagsToRemove = tagsToRemove; - } - - @Override - public boolean equals(Object obj) { - if (obj == null || obj.getClass() != getClass()) { - return false; - } - ManageChildrenOperation op = (ManageChildrenOperation) obj; - return mTag == op.mTag - && Arrays.equals(mIndicesToRemove, op.mIndicesToRemove) - && Arrays.equals(mViewsToAdd, op.mViewsToAdd) - && Arrays.equals(mTagsToRemove, op.mTagsToRemove); - } - - @Override - public int hashCode() { - return Arrays.deepHashCode(new Object[] {mTag, mIndicesToRemove, mViewsToAdd, mTagsToRemove}); - } - - @Override - public String toString() { - return "ManageChildrenOperation \n\tindicesToRemove: " - + Arrays.toString(mIndicesToRemove) - + "\n\tviewsToAdd: " - + Arrays.toString(mViewsToAdd) - + "\n\ttagsToRemove: " - + Arrays.toString(mTagsToRemove); - } - } - - private static class MockUIViewOperationQueue extends UIViewOperationQueue { - - private List mOperations; - - private MockUIViewOperationQueue(ReactApplicationContext context) { - super(context, mock(NativeViewHierarchyManager.class), 0); - mOperations = new ArrayList<>(); - } - - @Override - public void enqueueManageChildren( - int reactTag, int[] indicesToRemove, ViewAtIndex[] viewsToAdd, int[] tagsToDelete) { - mOperations.add( - new ManageChildrenOperation(reactTag, indicesToRemove, viewsToAdd, tagsToDelete)); - } - - public List getOperations() { - return Collections.unmodifiableList(mOperations); - } - } -} diff --git a/ReactAndroid/src/test/java/com/facebook/react/fabric/FabricUIManagerTest.java b/ReactAndroid/src/test/java/com/facebook/react/fabric/FabricUIManagerTest.java deleted file mode 100644 index 45c2f749b..000000000 --- a/ReactAndroid/src/test/java/com/facebook/react/fabric/FabricUIManagerTest.java +++ /dev/null @@ -1,336 +0,0 @@ -// Copyright (c) Facebook, Inc. and its 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; - -import static org.fest.assertions.api.Assertions.assertThat; -import static com.facebook.react.bridge.InstanceHandleHelper.randomInstanceHandle; -import static org.mockito.Mockito.mock; - -import com.facebook.react.ReactRootView; -import com.facebook.react.bridge.JavaScriptContextHolder; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.bridge.ReactTestHelper; -import com.facebook.react.bridge.ReadableNativeMap; -import com.facebook.react.uimanager.events.EventDispatcher; -import com.facebook.react.uimanager.ReactShadowNode; -import com.facebook.react.uimanager.ReactShadowNodeImpl; -import com.facebook.react.uimanager.Spacing; -import com.facebook.react.uimanager.ThemedReactContext; -import com.facebook.react.uimanager.ViewManager; -import com.facebook.react.uimanager.ViewManagerRegistry; -import com.facebook.react.views.progressbar.ProgressBarShadowNode; -import com.facebook.react.views.text.ReactRawTextManager; -import com.facebook.react.views.text.ReactRawTextShadowNode; -import com.facebook.react.views.text.ReactTextViewManager; -import com.facebook.react.views.view.ReactViewManager; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import org.fest.assertions.data.Offset; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; - - -/** Tests {@link FabricUIManager} */ -@RunWith(RobolectricTestRunner.class) -public class FabricUIManagerTest { - - private FabricUIManager mFabricUIManager; - private ThemedReactContext mThemedReactContext; - private int mNextReactTag; - - @Before - public void setUp() throws Exception { - mNextReactTag = 2; - ReactApplicationContext reactContext = new ReactApplicationContext(RuntimeEnvironment.application); - reactContext.initializeWithInstance(ReactTestHelper.createMockCatalystInstance()); - mThemedReactContext = new ThemedReactContext(reactContext, reactContext); - - List viewManagers = - Arrays.asList( - new ReactViewManager(), new ReactTextViewManager(), new ReactRawTextManager()); - ViewManagerRegistry viewManagerRegistry = new ViewManagerRegistry(viewManagers); - JavaScriptContextHolder jsContext = mock(JavaScriptContextHolder.class); - EventDispatcher eventDispatcher = mock(EventDispatcher.class); - mFabricUIManager = new FabricUIManager(reactContext, viewManagerRegistry, jsContext, eventDispatcher); - } - - @Test - public void testCreateNode() { - ReactRootView rootView = - new ReactRootView(RuntimeEnvironment.application.getApplicationContext()); - int rootTag = mFabricUIManager.addRootView(rootView); - int reactTag = mNextReactTag++; - String viewClass = ReactViewManager.REACT_CLASS; - ReactShadowNode node = - mFabricUIManager.createNode(reactTag, viewClass, rootTag, null, randomInstanceHandle()); - - assertThat(reactTag).isEqualTo(node.getReactTag()); - assertThat(viewClass).isEqualTo(node.getViewClass()); - assertThat(rootTag).isEqualTo(rootTag); - } - - @Test - public void testCreateMultpleRootViews() { - createAndRenderRootView(); - createAndRenderRootView(); - } - - private int createAndRenderRootView() { - ReactRootView rootView = - new ReactRootView(RuntimeEnvironment.application.getApplicationContext()); - int rootTag = mFabricUIManager.addRootView(rootView); - int reactTag = mNextReactTag++; - String viewClass = ReactViewManager.REACT_CLASS; - ReactShadowNode node = - mFabricUIManager.createNode(reactTag, viewClass, rootTag, null, randomInstanceHandle()); - - List childSet = mFabricUIManager.createChildSet(rootTag); - mFabricUIManager.appendChildToSet(childSet, node); - mFabricUIManager.completeRoot(rootTag, childSet); - - return rootTag; - } - - @Test - public void testCloneNode() { - ReactShadowNode node = createViewNode(); - ReactShadowNode child = createViewNode(); - node.addChildAt(child, 0); - - ReactShadowNode clonedNode = mFabricUIManager.cloneNode(node); - - assertThat(clonedNode).isNotSameAs(node); - assertThat(clonedNode.getOriginalReactShadowNode()).isSameAs(node); - assertSameFields(clonedNode, node); - assertSameChildren(clonedNode, node); - assertThat(clonedNode.getChildAt(0)).isEqualTo(child); - } - - @Test - public void testDefaultSpacingCloning() { - ReactShadowNode node = createViewNode(); - node.setDefaultPadding(Spacing.LEFT, 10); - - ReactShadowNode clonedNode = mFabricUIManager.cloneNode(node); - - node.setDefaultPadding(Spacing.LEFT, 20); - assertThat(clonedNode.getStylePadding(Spacing.LEFT).value).isEqualTo(10f, Offset.offset(0.01f)); - assertThat(node.getStylePadding(Spacing.LEFT).value).isEqualTo(20f, Offset.offset(0.01f)); - } - - @Test - public void testCloneVirtualNode() { - ReactRawTextShadowNode node = new ReactRawTextShadowNode(); - node.setText("test"); - assertThat(node.isVirtual()).isTrue(); - - ReactRawTextShadowNode clonedNode = (ReactRawTextShadowNode) node.mutableCopy(randomInstanceHandle()); - - assertThat(clonedNode.getText()).isEqualTo("test"); - assertThat(clonedNode).isNotEqualTo(node); - } - - @Test - public void testLayoutProgressBarAfterClonning() { - ProgressBarShadowNode node = new ProgressBarShadowNode(); - node.setThemedContext(mThemedReactContext); - ProgressBarShadowNode clone = (ProgressBarShadowNode) node.mutableCopy(randomInstanceHandle()); - clone.calculateLayout(); - } - - @Test - public void testCloneNodeWithNewChildren() { - ReactShadowNode node = createViewNode(); - ReactShadowNode child = createViewNode(); - node.addChildAt(child, 0); - - ReactShadowNode clonedNode = mFabricUIManager.cloneNodeWithNewChildren(node); - - assertThat(clonedNode.getChildCount()).isZero(); - assertSameFields(clonedNode, node); - } - - @Test - public void testCloneNodeWithNewProps() { - ReactShadowNode node = createViewNode(); - ReadableNativeMap props = null; // TODO(ayc): Figure out how to create a Native map from tests. - - ReactShadowNode clonedNode = mFabricUIManager.cloneNodeWithNewProps(node, props); - } - - @Test - public void testCloneNodeWithNewChildrenAndProps() { - ReactShadowNode node = createViewNode(); - ReadableNativeMap props = null; - - ReactShadowNode clonedNode = mFabricUIManager.cloneNodeWithNewChildrenAndProps(node, props); - - assertThat(clonedNode.getChildCount()).isZero(); - } - - @Test - public void testAppendChild() { - ReactShadowNode node = createViewNode(); - ReactShadowNode child = createViewNode(); - - mFabricUIManager.appendChild(node, child); - - assertThat(node.getChildCount()).isEqualTo(1); - assertThat(node.getChildAt(0)).isEqualTo(child); - } - - @Test - public void testCreateChildSet() { - List childSet = mFabricUIManager.createChildSet(0); - - assertThat(childSet).isEmpty(); - } - - @Test - public void testAppendChildToSet() { - ReactShadowNode node = createViewNode(); - List childSet = mFabricUIManager.createChildSet(0); - - mFabricUIManager.appendChildToSet(childSet, node); - - assertThat(childSet).hasSize(1); - assertThat(childSet).contains(node); - } - - @Test(expected = AssertionError.class) - public void testCompleteRootBeforeAddRoot() { - mFabricUIManager.completeRoot(0, new ArrayList()); - } - - @Test - public void testCompleteRoot() { - ReactRootView rootView = - new ReactRootView(RuntimeEnvironment.application.getApplicationContext()); - int rootTag = mFabricUIManager.addRootView(rootView); - List children = mFabricUIManager.createChildSet(rootTag); - - mFabricUIManager.completeRoot(rootTag, children); - } - - @Test - public void testSealReactShadowNode() { - ReactRootView rootView = - new ReactRootView(RuntimeEnvironment.application.getApplicationContext()); - int rootTag = mFabricUIManager.addRootView(rootView); - String viewClass = ReactViewManager.REACT_CLASS; - - ReactShadowNode container = mFabricUIManager.createNode(6, viewClass, rootTag, null, randomInstanceHandle()); - List childSet = mFabricUIManager.createChildSet(rootTag); - mFabricUIManager.appendChildToSet(childSet, container); - - assertThat(container.isSealed()).isFalse(); - - mFabricUIManager.completeRoot(rootTag, childSet); - - assertThat(container.isSealed()).isTrue(); - } - - /** - * Tests that cloned text nodes will not share measure functions - */ - @Test - public void testTextMutableClone() { - ReactRootView rootView = - new ReactRootView(RuntimeEnvironment.application.getApplicationContext()); - int rootTag = mFabricUIManager.addRootView(rootView); - ReactShadowNode text = - mFabricUIManager.createNode(0, ReactTextViewManager.REACT_CLASS, rootTag, null, randomInstanceHandle()); - assertThat(text.isMeasureDefined()).isTrue(); - - ReactShadowNode textCopy = text.mutableCopy(randomInstanceHandle()); - assertThat(textCopy.isMeasureDefined()).isTrue(); - - textCopy.setStyleWidth(200); - text.onBeforeLayout(); - text.calculateLayout(); - textCopy.onBeforeLayout(); - textCopy.calculateLayout(); - - assertThat(text.getLayoutWidth()).isNotEqualTo(textCopy.getLayoutWidth()); - } - - /** - * Verifies that the reconciliation phase will always set the originalNode field of every node in - * the tree to null once completeRoot has finished to prevent memory leaks. - */ - @Test - public void testRemoveOriginalNodeReferences() { - ReactRootView rootView = - new ReactRootView(RuntimeEnvironment.application.getApplicationContext()); - int rootTag = mFabricUIManager.addRootView(rootView); - String viewClass = ReactViewManager.REACT_CLASS; - - ReactShadowNode aa = mFabricUIManager.createNode(2, viewClass, rootTag, null, randomInstanceHandle()); - ReactShadowNode a = mFabricUIManager.createNode(3, viewClass, rootTag, null, randomInstanceHandle()); - mFabricUIManager.appendChild(a, aa); - ReactShadowNode bb = mFabricUIManager.createNode(4, viewClass, rootTag, null, randomInstanceHandle()); - ReactShadowNode b = mFabricUIManager.createNode(5, viewClass, rootTag, null, randomInstanceHandle()); - mFabricUIManager.appendChild(b, bb); - ReactShadowNode container = mFabricUIManager.createNode(6, viewClass, rootTag, null, randomInstanceHandle()); - mFabricUIManager.appendChild(container, a); - mFabricUIManager.appendChild(container, b); - List childSet = mFabricUIManager.createChildSet(rootTag); - mFabricUIManager.appendChildToSet(childSet, container); - mFabricUIManager.completeRoot(rootTag, childSet); - - ReactShadowNode aaClone = mFabricUIManager.cloneNodeWithNewProps(aa, null); - ReactShadowNode aClone = mFabricUIManager.cloneNodeWithNewChildren(a); - mFabricUIManager.appendChild(aClone, aaClone); - ReactShadowNode containerClone = mFabricUIManager.cloneNodeWithNewChildren(container); - mFabricUIManager.appendChild(containerClone, b); - mFabricUIManager.appendChild(containerClone, aClone); - List childSet2 = mFabricUIManager.createChildSet(rootTag); - mFabricUIManager.appendChildToSet(childSet2, containerClone); - mFabricUIManager.completeRoot(rootTag, childSet2); - - ReactShadowNode[] nodes = - new ReactShadowNode[] {aa, a, bb, b, container, aaClone, aClone, containerClone}; - - for (ReactShadowNode node : nodes) { - assertThat(node.getOriginalReactShadowNode()).isNull(); - } - } - - private void assertSameChildren(ReactShadowNode node1, ReactShadowNode node2) { - assertThat(node1.getChildCount()).isEqualTo(node2.getChildCount()); - for (int i = 0; i < node1.getChildCount(); i++) { - assertThat(node1.getChildAt(i)).isEqualTo(node2.getChildAt(i)); - } - } - - private void assertSameFields(ReactShadowNode node1, ReactShadowNode node2) { - assertThat(node1.getReactTag()).isEqualTo(node2.getReactTag()); - assertThat(node1.getViewClass()).isEqualTo(node2.getViewClass()); - assertThat(node2.getParent()).isNull(); - assertThat(node1.getThemedContext()).isEqualTo(node2.getThemedContext()); - assertThat(node1.isVirtual()).isEqualTo(node2.isVirtual()); - assertThat(node1.getLayoutDirection()).isEqualTo(node2.getLayoutDirection()); - assertThat(node1.getLayoutHeight()).isEqualTo(node2.getLayoutHeight()); - assertThat(node1.getLayoutWidth()).isEqualTo(node2.getLayoutWidth()); - assertThat(node1.getLayoutX()).isEqualTo(node2.getLayoutX()); - assertThat(node1.getLayoutY()).isEqualTo(node2.getLayoutY()); - for (int spacingType = Spacing.LEFT; spacingType <= Spacing.ALL; spacingType++) { - assertThat(node1.getStylePadding(spacingType)).isEqualTo(node2.getStylePadding(spacingType)); - } - assertThat(node1.getStyleWidth()).isEqualTo(node2.getStyleWidth()); - assertThat(node1.getStyleHeight()).isEqualTo(node2.getStyleHeight()); - } - - private ReactShadowNode createViewNode() { - ReactShadowNode node = new ReactShadowNodeImpl(); - node.setViewClassName(ReactViewManager.REACT_CLASS); - node.setThemedContext(mThemedReactContext); - return node; - } -} diff --git a/ReactAndroid/src/test/java/com/facebook/react/fabric/ReactShadowNodeTest.java b/ReactAndroid/src/test/java/com/facebook/react/fabric/ReactShadowNodeTest.java deleted file mode 100644 index 98d9d7faa..000000000 --- a/ReactAndroid/src/test/java/com/facebook/react/fabric/ReactShadowNodeTest.java +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) Facebook, Inc. and its 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; - -import com.facebook.react.uimanager.ReactShadowNodeImpl; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; - -/** Tests {@link ReactShadowNode} */ -@RunWith(RobolectricTestRunner.class) -public class ReactShadowNodeTest { - - @Test(expected = AssertionError.class) - public void testClonedInstance() { - TestReactShadowNode node = new TestReactShadowNode(); - node.mutableCopy(node.getInstanceHandle()); - } - - private static class TestReactShadowNode extends ReactShadowNodeImpl {} -}