Add support for View Manager commands in Fabric
Reviewed By: achen1 Differential Revision: D7879104 fbshipit-source-id: fd89acb3941bb03364d18ddedf68a081aef934a0
This commit is contained in:
parent
398f1d8ddd
commit
3ac914478d
|
@ -79,7 +79,7 @@ import com.facebook.react.modules.debug.interfaces.DeveloperSettings;
|
||||||
import com.facebook.react.modules.fabric.ReactFabric;
|
import com.facebook.react.modules.fabric.ReactFabric;
|
||||||
import com.facebook.react.uimanager.DisplayMetricsHolder;
|
import com.facebook.react.uimanager.DisplayMetricsHolder;
|
||||||
import com.facebook.react.uimanager.UIImplementationProvider;
|
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.uimanager.ViewManager;
|
||||||
import com.facebook.react.views.imagehelper.ResourceDrawableIdHelper;
|
import com.facebook.react.views.imagehelper.ResourceDrawableIdHelper;
|
||||||
import com.facebook.soloader.SoLoader;
|
import com.facebook.soloader.SoLoader;
|
||||||
|
@ -1011,7 +1011,7 @@ public class ReactInstanceManager {
|
||||||
CatalystInstance catalystInstance) {
|
CatalystInstance catalystInstance) {
|
||||||
Log.d(ReactConstants.TAG, "ReactInstanceManager.attachRootViewToInstance()");
|
Log.d(ReactConstants.TAG, "ReactInstanceManager.attachRootViewToInstance()");
|
||||||
Systrace.beginSection(TRACE_TAG_REACT_JAVA_BRIDGE, "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);
|
final int rootTag = uiManagerModule.addRootView(rootView);
|
||||||
rootView.setRootViewTag(rootTag);
|
rootView.setRootViewTag(rootTag);
|
||||||
rootView.invokeJSEntryPoint();
|
rootView.invokeJSEntryPoint();
|
||||||
|
|
|
@ -44,6 +44,7 @@ import com.facebook.react.uimanager.IllegalViewOperationException;
|
||||||
import com.facebook.react.uimanager.JSTouchDispatcher;
|
import com.facebook.react.uimanager.JSTouchDispatcher;
|
||||||
import com.facebook.react.uimanager.PixelUtil;
|
import com.facebook.react.uimanager.PixelUtil;
|
||||||
import com.facebook.react.uimanager.RootView;
|
import com.facebook.react.uimanager.RootView;
|
||||||
|
import com.facebook.react.uimanager.UIManagerHelper;
|
||||||
import com.facebook.react.uimanager.UIManagerModule;
|
import com.facebook.react.uimanager.UIManagerModule;
|
||||||
import com.facebook.react.uimanager.common.MeasureSpecProvider;
|
import com.facebook.react.uimanager.common.MeasureSpecProvider;
|
||||||
import com.facebook.react.uimanager.common.SizeMonitoringFrameLayout;
|
import com.facebook.react.uimanager.common.SizeMonitoringFrameLayout;
|
||||||
|
@ -402,10 +403,9 @@ public class ReactRootView extends SizeMonitoringFrameLayout
|
||||||
new GuardedRunnable(reactApplicationContext) {
|
new GuardedRunnable(reactApplicationContext) {
|
||||||
@Override
|
@Override
|
||||||
public void runGuarded() {
|
public void runGuarded() {
|
||||||
reactApplicationContext
|
UIManagerHelper
|
||||||
.getCatalystInstance()
|
.getUIManager(reactApplicationContext, isFabric())
|
||||||
.getNativeModule(UIManagerModule.class)
|
.updateRootLayoutSpecs(getRootViewTag(), widthMeasureSpec, heightMeasureSpec);
|
||||||
.updateRootLayoutSpecs(getRootViewTag(), widthMeasureSpec, heightMeasureSpec);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,8 @@ package com.facebook.react.bridge;
|
||||||
import com.facebook.react.uimanager.common.MeasureSpecProvider;
|
import com.facebook.react.uimanager.common.MeasureSpecProvider;
|
||||||
import com.facebook.react.uimanager.common.SizeMonitoringFrameLayout;
|
import com.facebook.react.uimanager.common.SizeMonitoringFrameLayout;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public interface UIManager extends JSIModule {
|
public interface UIManager extends JSIModule {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -10,4 +12,19 @@ public interface UIManager extends JSIModule {
|
||||||
*/
|
*/
|
||||||
<T extends SizeMonitoringFrameLayout & MeasureSpecProvider> int addRootView(final T rootView);
|
<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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ import android.view.View;
|
||||||
import com.facebook.infer.annotation.Assertions;
|
import com.facebook.infer.annotation.Assertions;
|
||||||
import com.facebook.react.bridge.GuardedRunnable;
|
import com.facebook.react.bridge.GuardedRunnable;
|
||||||
import com.facebook.react.bridge.ReactApplicationContext;
|
import com.facebook.react.bridge.ReactApplicationContext;
|
||||||
|
import com.facebook.react.bridge.ReadableArray;
|
||||||
import com.facebook.react.bridge.ReadableMap;
|
import com.facebook.react.bridge.ReadableMap;
|
||||||
import com.facebook.react.bridge.ReadableNativeMap;
|
import com.facebook.react.bridge.ReadableNativeMap;
|
||||||
import com.facebook.react.bridge.UIManager;
|
import com.facebook.react.bridge.UIManager;
|
||||||
|
@ -35,8 +36,10 @@ import com.facebook.react.uimanager.ViewManagerRegistry;
|
||||||
import com.facebook.react.uimanager.common.MeasureSpecProvider;
|
import com.facebook.react.uimanager.common.MeasureSpecProvider;
|
||||||
import com.facebook.react.uimanager.common.SizeMonitoringFrameLayout;
|
import com.facebook.react.uimanager.common.SizeMonitoringFrameLayout;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -280,6 +283,11 @@ public class FabricUIManager implements UIManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public void dispatchViewManagerCommand(int reactTag, int commandId, @Nullable ReadableArray commandArgs) {
|
||||||
|
mUIViewOperationQueue.enqueueDispatchCommand(reactTag, commandId, commandArgs);
|
||||||
|
}
|
||||||
|
|
||||||
private void notifyOnBeforeLayoutRecursive(ReactShadowNode node) {
|
private void notifyOnBeforeLayoutRecursive(ReactShadowNode node) {
|
||||||
if (!node.hasUpdates()) {
|
if (!node.hasUpdates()) {
|
||||||
return;
|
return;
|
||||||
|
@ -367,6 +375,16 @@ public class FabricUIManager implements UIManager {
|
||||||
return rootTag;
|
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.
|
* Updates the root view size and re-render the RN surface.
|
||||||
*
|
*
|
||||||
|
|
|
@ -788,7 +788,7 @@ public class UIImplementation {
|
||||||
mOperationsQueue.enqueueClearJSResponder();
|
mOperationsQueue.enqueueClearJSResponder();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void dispatchViewManagerCommand(int reactTag, int commandId, ReadableArray commandArgs) {
|
public void dispatchViewManagerCommand(int reactTag, int commandId, @Nullable ReadableArray commandArgs) {
|
||||||
assertViewExists(reactTag, "dispatchViewManagerCommand");
|
assertViewExists(reactTag, "dispatchViewManagerCommand");
|
||||||
mOperationsQueue.enqueueDispatchCommand(reactTag, commandId, commandArgs);
|
mOperationsQueue.enqueueDispatchCommand(reactTag, commandId, commandArgs);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -10,6 +10,9 @@ package com.facebook.react.uimanager;
|
||||||
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_END;
|
||||||
import static com.facebook.react.bridge.ReactMarkerConstants.CREATE_UI_MANAGER_MODULE_CONSTANTS_START;
|
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.ComponentCallbacks2;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
@ -37,6 +40,7 @@ import com.facebook.react.common.ReactConstants;
|
||||||
import com.facebook.react.module.annotations.ReactModule;
|
import com.facebook.react.module.annotations.ReactModule;
|
||||||
import com.facebook.react.uimanager.common.MeasureSpecProvider;
|
import com.facebook.react.uimanager.common.MeasureSpecProvider;
|
||||||
import com.facebook.react.uimanager.common.SizeMonitoringFrameLayout;
|
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.debug.NotThreadSafeViewHierarchyUpdateDebugListener;
|
||||||
import com.facebook.react.uimanager.events.EventDispatcher;
|
import com.facebook.react.uimanager.events.EventDispatcher;
|
||||||
import com.facebook.systrace.Systrace;
|
import com.facebook.systrace.Systrace;
|
||||||
|
@ -582,9 +586,17 @@ public class UIManagerModule extends ReactContextBaseJavaModule implements
|
||||||
mUIImplementation.clearJSResponder();
|
mUIImplementation.clearJSResponder();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
@ReactMethod
|
@ReactMethod
|
||||||
public void dispatchViewManagerCommand(int reactTag, int commandId, ReadableArray commandArgs) {
|
public void dispatchViewManagerCommand(int reactTag, int commandId, @Nullable ReadableArray commandArgs) {
|
||||||
mUIImplementation.dispatchViewManagerCommand(reactTag, commandId, 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
|
@ReactMethod
|
||||||
|
|
|
@ -647,7 +647,7 @@ public class UIViewOperationQueue {
|
||||||
public void enqueueDispatchCommand(
|
public void enqueueDispatchCommand(
|
||||||
int reactTag,
|
int reactTag,
|
||||||
int commandId,
|
int commandId,
|
||||||
ReadableArray commandArgs) {
|
@Nullable ReadableArray commandArgs) {
|
||||||
mOperations.add(new DispatchCommandOperation(reactTag, commandId, commandArgs));
|
mOperations.add(new DispatchCommandOperation(reactTag, commandId, commandArgs));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue