The ART '<Surface>' becomes invisible in Android (#22624)

Summary:
Hello Everyone, this series of commits helps to fix problems related to ART on Android. The main problem in here is that the ART components would disappear if the user turns off the screen and then turn it on again.  It's important to note that this behaviour only occurs after Android N (7.1 or higher).
Pull Request resolved: https://github.com/facebook/react-native/pull/22624

Differential Revision: D15122573

Pulled By: cpojer

fbshipit-source-id: e7fb8b9280b4c52562e3d0c1a89759d4d31cd53d
This commit is contained in:
Guilherme Iscaro 2019-04-29 09:25:18 -07:00 коммит произвёл Facebook Github Bot
Родитель 110a382b59
Коммит 20b09e4c45
2 изменённых файлов: 51 добавлений и 8 удалений

Просмотреть файл

@ -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

Просмотреть файл

@ -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;
}