Skip to content

Commit

Permalink
Add support for View Manager commands in Fabric
Browse files Browse the repository at this point in the history
Reviewed By: achen1

Differential Revision: D7879104

fbshipit-source-id: fd89acb3941bb03364d18ddedf68a081aef934a0
  • Loading branch information
mdvacca authored and macdoum1 committed Jun 28, 2018
1 parent 8077b85 commit 15abee5
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
import com.facebook.react.modules.fabric.ReactFabric;
import com.facebook.react.uimanager.DisplayMetricsHolder;
import com.facebook.react.uimanager.UIImplementationProvider;
import com.facebook.react.uimanager.UIManagerModule;
import com.facebook.react.uimanager.UIManagerHelper;
import com.facebook.react.uimanager.ViewManager;
import com.facebook.react.views.imagehelper.ResourceDrawableIdHelper;
import com.facebook.soloader.SoLoader;
Expand Down Expand Up @@ -1011,7 +1011,7 @@ private void attachRootViewToInstance(
CatalystInstance catalystInstance) {
Log.d(ReactConstants.TAG, "ReactInstanceManager.attachRootViewToInstance()");
Systrace.beginSection(TRACE_TAG_REACT_JAVA_BRIDGE, "attachRootViewToInstance");
UIManager uiManagerModule = rootView.isFabric() ? catalystInstance.getJSIModule(UIManager.class) : catalystInstance.getNativeModule(UIManagerModule.class);
UIManager uiManagerModule = UIManagerHelper.getUIManager(mCurrentReactContext, rootView.isFabric());
final int rootTag = uiManagerModule.addRootView(rootView);
rootView.setRootViewTag(rootTag);
rootView.invokeJSEntryPoint();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import com.facebook.react.uimanager.JSTouchDispatcher;
import com.facebook.react.uimanager.PixelUtil;
import com.facebook.react.uimanager.RootView;
import com.facebook.react.uimanager.UIManagerHelper;
import com.facebook.react.uimanager.UIManagerModule;
import com.facebook.react.uimanager.common.MeasureSpecProvider;
import com.facebook.react.uimanager.common.SizeMonitoringFrameLayout;
Expand Down Expand Up @@ -402,10 +403,9 @@ private void updateRootLayoutSpecs(final int widthMeasureSpec, final int heightM
new GuardedRunnable(reactApplicationContext) {
@Override
public void runGuarded() {
reactApplicationContext
.getCatalystInstance()
.getNativeModule(UIManagerModule.class)
.updateRootLayoutSpecs(getRootViewTag(), widthMeasureSpec, heightMeasureSpec);
UIManagerHelper
.getUIManager(reactApplicationContext, isFabric())
.updateRootLayoutSpecs(getRootViewTag(), widthMeasureSpec, heightMeasureSpec);
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,28 @@
import com.facebook.react.uimanager.common.MeasureSpecProvider;
import com.facebook.react.uimanager.common.SizeMonitoringFrameLayout;

import javax.annotation.Nullable;

public interface UIManager extends JSIModule {

/**
* Registers a new root view.
*/
<T extends SizeMonitoringFrameLayout & MeasureSpecProvider> int addRootView(final T rootView);

/**
* Updates the layout specs of the RootShadowNode based on the Measure specs received by
* parameters.
*/
void updateRootLayoutSpecs(int rootTag, int widthMeasureSpec, int heightMeasureSpec);

/**
* Dispatches the commandId received by parameter to the view associated with the reactTag.
* The command will be processed in the UIThread.
*
* @param reactTag {@link int} that identifies the view that will receive this command
* @param commandId {@link int} command id
* @param commandArgs {@link ReadableArray} parameters associated with the command
*/
void dispatchViewManagerCommand(int reactTag, int commandId, @Nullable ReadableArray commandArgs);
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import com.facebook.infer.annotation.Assertions;
import com.facebook.react.bridge.GuardedRunnable;
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;
Expand All @@ -35,8 +36,10 @@
import com.facebook.react.uimanager.common.MeasureSpecProvider;
import com.facebook.react.uimanager.common.SizeMonitoringFrameLayout;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import javax.annotation.Nullable;

/**
Expand Down Expand Up @@ -280,6 +283,11 @@ public synchronized void completeRoot(int rootTag, @Nullable List<ReactShadowNod
}
}

@Deprecated
public void dispatchViewManagerCommand(int reactTag, int commandId, @Nullable ReadableArray commandArgs) {
mUIViewOperationQueue.enqueueDispatchCommand(reactTag, commandId, commandArgs);
}

private void notifyOnBeforeLayoutRecursive(ReactShadowNode node) {
if (!node.hasUpdates()) {
return;
Expand Down Expand Up @@ -367,6 +375,16 @@ public void onSizeChanged(final int width, final int height, int oldW, int oldH)
return rootTag;
}

@Override
public void updateRootLayoutSpecs(int rootViewTag, int widthMeasureSpec, int heightMeasureSpec) {
ReactShadowNode rootNode = mRootShadowNodeRegistry.getNode(rootViewTag);
if (rootNode == null) {
Log.w(ReactConstants.TAG, "Tried to update non-existent root tag: " + rootViewTag);
return;
}
updateRootView(rootNode, widthMeasureSpec, heightMeasureSpec);
}

/**
* Updates the root view size and re-render the RN surface.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -788,7 +788,7 @@ public void clearJSResponder() {
mOperationsQueue.enqueueClearJSResponder();
}

public void dispatchViewManagerCommand(int reactTag, int commandId, ReadableArray commandArgs) {
public void dispatchViewManagerCommand(int reactTag, int commandId, @Nullable ReadableArray commandArgs) {
assertViewExists(reactTag, "dispatchViewManagerCommand");
mOperationsQueue.enqueueDispatchCommand(reactTag, commandId, commandArgs);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.facebook.react.uimanager;

import static com.facebook.react.uimanager.common.ViewType.FABRIC;
import static com.facebook.react.uimanager.common.ViewUtil.getViewType;

import com.facebook.react.bridge.CatalystInstance;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.UIManager;

/**
* Helper class for {@link UIManager}.
*/
public class UIManagerHelper {

/**
* @return a {@link UIManager} that can handle the react tag received by parameter.
*/
public static UIManager getUIManager(ReactContext context, int reactTag) {
return getUIManager(context, getViewType(reactTag) == FABRIC);
}

/**
* @return a {@link UIManager} that can handle the react tag received by parameter.
*/
public static UIManager getUIManager(ReactContext context, boolean isFabric) {
CatalystInstance catalystInstance = context.getCatalystInstance();
return isFabric ?
catalystInstance.getJSIModule(UIManager.class) :
catalystInstance.getNativeModule(UIManagerModule.class);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
import static com.facebook.react.bridge.ReactMarkerConstants.CREATE_UI_MANAGER_MODULE_CONSTANTS_END;
import static com.facebook.react.bridge.ReactMarkerConstants.CREATE_UI_MANAGER_MODULE_CONSTANTS_START;

import static com.facebook.react.uimanager.common.ViewType.FABRIC;
import static com.facebook.react.uimanager.common.ViewType.PAPER;

import android.content.ComponentCallbacks2;
import android.content.res.Configuration;
import android.content.Context;
Expand Down Expand Up @@ -37,6 +40,7 @@
import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.uimanager.common.MeasureSpecProvider;
import com.facebook.react.uimanager.common.SizeMonitoringFrameLayout;
import com.facebook.react.uimanager.common.ViewUtil;
import com.facebook.react.uimanager.debug.NotThreadSafeViewHierarchyUpdateDebugListener;
import com.facebook.react.uimanager.events.EventDispatcher;
import com.facebook.systrace.Systrace;
Expand Down Expand Up @@ -582,9 +586,17 @@ public void clearJSResponder() {
mUIImplementation.clearJSResponder();
}

@Override
@ReactMethod
public void dispatchViewManagerCommand(int reactTag, int commandId, ReadableArray commandArgs) {
mUIImplementation.dispatchViewManagerCommand(reactTag, commandId, commandArgs);
public void dispatchViewManagerCommand(int reactTag, int commandId, @Nullable ReadableArray commandArgs) {
//TODO: this is a temporary approach to support ViewManagerCommands in Fabric until
// the dispatchViewManagerCommand() method is supported by Fabric JS API.
if (ViewUtil.getViewType(reactTag) == FABRIC) {
UIManagerHelper.getUIManager(getReactApplicationContext(), true)
.dispatchViewManagerCommand(reactTag, commandId, commandArgs);
} else {
mUIImplementation.dispatchViewManagerCommand(reactTag, commandId, commandArgs);
}
}

@ReactMethod
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -647,7 +647,7 @@ public void enqueueClearJSResponder() {
public void enqueueDispatchCommand(
int reactTag,
int commandId,
ReadableArray commandArgs) {
@Nullable ReadableArray commandArgs) {
mOperations.add(new DispatchCommandOperation(reactTag, commandId, commandArgs));
}

Expand Down

0 comments on commit 15abee5

Please sign in to comment.