diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTSurfaceViewManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTSurfaceViewManager.java index 351e96284..e7cc4c652 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTSurfaceViewManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTSurfaceViewManager.java @@ -60,7 +60,8 @@ public class ARTSurfaceViewManager extends @Override public void updateExtraData(ARTSurfaceView root, Object extraData) { - root.setSurfaceTextureListener((ARTSurfaceViewShadowNode) extraData); + ARTSurfaceViewShadowNode shadowNode = (ARTSurfaceViewShadowNode) extraData; + shadowNode.setupSurfaceTextureListener(root); } @Override diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTSurfaceViewShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTSurfaceViewShadowNode.java index 7e20931a8..b154c0c4d 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTSurfaceViewShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTSurfaceViewShadowNode.java @@ -16,6 +16,7 @@ import android.view.Surface; import android.graphics.PorterDuff; import android.graphics.SurfaceTexture; import android.view.TextureView; +import android.os.Build; import com.facebook.common.logging.FLog; import com.facebook.react.common.ReactConstants; @@ -23,13 +24,15 @@ import com.facebook.react.uimanager.LayoutShadowNode; import com.facebook.react.uimanager.UIViewOperationQueue; import com.facebook.react.uimanager.ReactShadowNode; import com.facebook.react.uimanager.ViewProps; +import com.facebook.react.uimanager.ThemedReactContext; import com.facebook.react.uimanager.annotations.ReactProp; +import com.facebook.react.bridge.LifecycleEventListener; /** * Shadow node for ART virtual tree root - ARTSurfaceView */ public class ARTSurfaceViewShadowNode extends LayoutShadowNode - implements TextureView.SurfaceTextureListener { + implements TextureView.SurfaceTextureListener, LifecycleEventListener { private @Nullable Surface mSurface; @@ -54,11 +57,11 @@ public class ARTSurfaceViewShadowNode extends LayoutShadowNode @Override public void onCollectExtraUpdates(UIViewOperationQueue uiUpdater) { super.onCollectExtraUpdates(uiUpdater); - drawOutput(); + drawOutput(false); uiUpdater.enqueueUpdateExtraData(getReactTag(), this); } - private void drawOutput() { + private void drawOutput(boolean markAsUpdated) { if (mSurface == null || !mSurface.isValid()) { markChildrenUpdatesSeen(this); return; @@ -75,19 +78,31 @@ public class ARTSurfaceViewShadowNode extends LayoutShadowNode for (int i = 0; i < getChildCount(); i++) { ARTVirtualNode child = (ARTVirtualNode) getChildAt(i); child.draw(canvas, paint, 1f); - child.markUpdateSeen(); + if (markAsUpdated) { + child.markUpdated(); + } else { + child.markUpdateSeen(); + } } if (mSurface == null) { return; } - mSurface.unlockCanvasAndPost(canvas); } catch (IllegalArgumentException | IllegalStateException e) { FLog.e(ReactConstants.TAG, e.getClass().getSimpleName() + " in Surface.unlockCanvasAndPost"); } } + public void setupSurfaceTextureListener(ARTSurfaceView surfaceView) { + SurfaceTexture surface = surfaceView.getSurfaceTexture(); + surfaceView.setSurfaceTextureListener(this); + if (surface != null && mSurface == null) { + mSurface = new Surface(surface); + drawOutput(true); + } + } + private void markChildrenUpdatesSeen(ReactShadowNode shadowNode) { for (int i = 0; i < shadowNode.getChildCount(); i++) { ReactShadowNode child = shadowNode.getChildAt(i); @@ -96,15 +111,42 @@ public class ARTSurfaceViewShadowNode extends LayoutShadowNode } } + @Override + public void setThemedContext(ThemedReactContext themedContext) { + super.setThemedContext(themedContext); + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N) { + themedContext.addLifecycleEventListener(this); + } + } + + @Override + public void dispose() { + super.dispose(); + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N) { + getThemedContext().removeLifecycleEventListener(this); + } + } + + @Override + public void onHostResume() { + drawOutput(false); + } + + @Override + public void onHostPause() {} + + @Override + public void onHostDestroy() {} + @Override public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { mSurface = new Surface(surface); - drawOutput(); + drawOutput(false); } @Override public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { - surface.release(); + mSurface.release(); mSurface = null; return true; }