From 40c724834578d2a2db217039b01cb8f8e9849585 Mon Sep 17 00:00:00 2001 From: David Vacca Date: Wed, 30 May 2018 21:49:10 -0700 Subject: [PATCH] store / retrieve instanceHandle from View Reviewed By: shergin, achen1 Differential Revision: D8074014 fbshipit-source-id: aee0d41e0e9da44e8748f47da04dcd76dbe96d8d --- .../react/fabric/FabricReconciler.java | 14 +++---- .../react/fabric/FabricUIManager.java | 20 +++++++++- .../uimanager/NativeViewHierarchyManager.java | 40 ++++++++++++++++++- .../react/uimanager/UIViewOperationQueue.java | 20 ++++++++++ .../main/res/views/uimanager/values/ids.xml | 3 ++ .../react/fabric/FabricReconcilerTest.java | 1 + 6 files changed, 88 insertions(+), 10 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricReconciler.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricReconciler.java index ddd3a386fc..5f61d943fe 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricReconciler.java +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricReconciler.java @@ -8,7 +8,6 @@ package com.facebook.react.fabric; import android.util.Log; -import android.util.SparseArray; import com.facebook.react.common.ArrayUtils; import com.facebook.react.uimanager.ReactShadowNode; import com.facebook.react.uimanager.UIViewOperationQueue; @@ -118,19 +117,20 @@ public class FabricReconciler { } private void enqueueUpdateProperties(ReactShadowNode node) { - if (node.getNewProps() == null) { - return; - } + int reactTag = node.getReactTag(); if (DEBUG) { Log.d( TAG, "manageChildren.enqueueUpdateProperties " + - "\n\ttag: " + node.getReactTag() + + "\n\ttag: " + reactTag + "\n\tviewClass: " + node.getViewClass() + "\n\tnewProps: " + node.getNewProps()); } - uiViewOperationQueue.enqueueUpdateProperties( - node.getReactTag(), node.getViewClass(), node.getNewProps()); + + if (node.getNewProps() != null) { + uiViewOperationQueue.enqueueUpdateProperties( + reactTag, node.getViewClass(), node.getNewProps()); + } } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java index a565012e52..7021c78310 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java @@ -15,6 +15,7 @@ import android.util.Log; import android.view.View; import com.facebook.infer.annotation.Assertions; import com.facebook.react.bridge.GuardedRunnable; +import com.facebook.react.bridge.JavaScriptContextHolder; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableMap; @@ -58,17 +59,22 @@ public class FabricUIManager implements UIManager, JSHandler { private final ReactApplicationContext mReactApplicationContext; private final ViewManagerRegistry mViewManagerRegistry; private final UIViewOperationQueue mUIViewOperationQueue; + private final NativeViewHierarchyManager mNativeViewHierarchyManager; private volatile int mCurrentBatch = 0; - private FabricReconciler mFabricReconciler; + private final FabricReconciler mFabricReconciler; + // TODO: Initialize new Binding (waiting for C++ implemenation to be landed) + private FabricBinding mBinding; + private JavaScriptContextHolder mContext; public FabricUIManager( ReactApplicationContext reactContext, ViewManagerRegistry viewManagerRegistry) { DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(reactContext); mReactApplicationContext = reactContext; mViewManagerRegistry = viewManagerRegistry; + mNativeViewHierarchyManager = new NativeViewHierarchyManager(viewManagerRegistry); mUIViewOperationQueue = new UIViewOperationQueue( - reactContext, new NativeViewHierarchyManager(viewManagerRegistry), 0); + reactContext, mNativeViewHierarchyManager, 0); mFabricReconciler = new FabricReconciler(mUIViewOperationQueue); } @@ -483,4 +489,14 @@ public class FabricUIManager implements UIManager, JSHandler { // -> call to C++ } + public long createEventTarget(int targetTag) throws IllegalStateException { + long instanceHandle = mNativeViewHierarchyManager.getInstanceHandle(targetTag); + if (instanceHandle == 0) { + throw new IllegalStateException("View with targetTag " + targetTag + " does not exist."); + } + + // TODO: uncomment after diff including Binding is landed + // return mBinding.createEventTarget(mContext.get(), instanceHandle); + return 0; + } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java index a57205b861..7a59df26f6 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java @@ -7,7 +7,9 @@ package com.facebook.react.uimanager; +import android.annotation.TargetApi; import android.content.res.Resources; +import android.os.Build; import android.util.Log; import android.util.SparseArray; import android.util.SparseBooleanArray; @@ -17,6 +19,7 @@ import android.view.View; import android.view.ViewGroup; import android.view.ViewParent; import android.widget.PopupMenu; +import com.facebook.react.R; import com.facebook.infer.annotation.Assertions; import com.facebook.react.animation.Animation; import com.facebook.react.animation.AnimationListener; @@ -114,13 +117,26 @@ public class NativeViewHierarchyManager { mLayoutAnimationEnabled = enabled; } + public synchronized void updateInstanceHandle(int tag, long instanceHandle) { + UiThreadUtil.assertOnUiThread(); + + try { + updateInstanceHandle(resolveView(tag), instanceHandle); + } catch (IllegalViewOperationException e) { + Log.e(TAG, "Unable to update properties for view tag " + tag, e); + } + } + public synchronized void updateProperties(int tag, ReactStylesDiffMap props) { UiThreadUtil.assertOnUiThread(); try { ViewManager viewManager = resolveViewManager(tag); View viewToUpdate = resolveView(tag); - viewManager.updateProperties(viewToUpdate, props); + + if (props != null) { + viewManager.updateProperties(viewToUpdate, props); + } } catch (IllegalViewOperationException e) { Log.e(TAG, "Unable to update properties for view tag " + tag, e); } @@ -197,6 +213,28 @@ public class NativeViewHierarchyManager { } } + @TargetApi(Build.VERSION_CODES.DONUT) + private void updateInstanceHandle(View viewToUpdate, long instanceHandle) { + UiThreadUtil.assertOnUiThread(); + viewToUpdate.setTag(R.id.view_tag_instance_handle, instanceHandle); + } + + @Nullable + @TargetApi(Build.VERSION_CODES.DONUT) + public long getInstanceHandle(int targetTag) { + UiThreadUtil.assertOnUiThread(); + + View view = mTagsToViews.get(targetTag); + if (view == null) { + throw new IllegalArgumentException("Unable to find view for tag: " + targetTag); + } + Long tag = (Long) view.getTag(R.id.view_tag_instance_handle); + if (tag == null) { + throw new IllegalArgumentException("Unable to find instanceHandle for tag: " + targetTag); + } + return tag; + } + private void updateLayout(View viewToUpdate, int x, int y, int width, int height) { if (mLayoutAnimationEnabled && mLayoutAnimator.shouldAnimateLayout(viewToUpdate)) { diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIViewOperationQueue.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIViewOperationQueue.java index 183fcf436a..90e4d82bb9 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIViewOperationQueue.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIViewOperationQueue.java @@ -96,6 +96,22 @@ public class UIViewOperationQueue { } } + + private final class UpdateInstanceHandleOperation extends ViewOperation { + + private final long mInstanceHandle; + + private UpdateInstanceHandleOperation(int tag, long instanceHandle) { + super(tag); + mInstanceHandle = instanceHandle; + } + + @Override + public void execute() { + mNativeViewHierarchyManager.updateInstanceHandle(mTag, mInstanceHandle); + } + } + /** * Operation for updating native view's position and size. The operation is not created directly * by a {@link UIManagerModule} call from JS. Instead it gets inflated using computed position @@ -682,6 +698,10 @@ public class UIViewOperationQueue { } } + public void enqueueUpdateInstanceHandle(int reactTag, long instanceHandle) { + mOperations.add(new UpdateInstanceHandleOperation(reactTag, instanceHandle)); + } + public void enqueueUpdateProperties(int reactTag, String className, ReactStylesDiffMap props) { mOperations.add(new UpdatePropertiesOperation(reactTag, props)); } diff --git a/ReactAndroid/src/main/res/views/uimanager/values/ids.xml b/ReactAndroid/src/main/res/views/uimanager/values/ids.xml index 75ac81d171..8ccd44d4b6 100644 --- a/ReactAndroid/src/main/res/views/uimanager/values/ids.xml +++ b/ReactAndroid/src/main/res/views/uimanager/values/ids.xml @@ -5,4 +5,7 @@ + + + diff --git a/ReactAndroid/src/test/java/com/facebook/react/fabric/FabricReconcilerTest.java b/ReactAndroid/src/test/java/com/facebook/react/fabric/FabricReconcilerTest.java index 2cb680067c..bf4d69dffa 100644 --- a/ReactAndroid/src/test/java/com/facebook/react/fabric/FabricReconcilerTest.java +++ b/ReactAndroid/src/test/java/com/facebook/react/fabric/FabricReconcilerTest.java @@ -109,6 +109,7 @@ public class FabricReconcilerTest { node = new ReactShadowNodeImpl(); } node.setReactTag(tag); + node.setViewClassName("View"); node.setThemedContext(mock(ThemedReactContext.class)); return node; }