Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FIX][Android]: The ART '<Surface>' becomes invisible in Android #22624

Closed
wants to merge 3 commits into from

Conversation

cabelitos
Copy link
Contributor

@cabelitos cabelitos commented Dec 12, 2018

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).

Test Plan:

  • Open the Android emulator using API level 25 or higher (Android 7.1 or higher)
  • Create an react-native-app with the following code:
import React, { Component } from 'react';
import { Platform, StyleSheet, Text, View, ART } from "react-native";


const path = ART.Path();

path.moveTo(0, 0);
path.lineTo(10, 10);

type Props = {};
export default class App extends Component<Props> {
  render() {
    return (
      <View style={styles.container}>
        <ART.Surface width={300} height={300}>
          <ART.Shape d="M150 0 L75 200 L225 200 Z" fill="#ff0000"/>
        </ART.Surface>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
});
  • After the App is running, turn off the screen
  • Wait some seconds and turn it on again
  • Expected result: The triangle should be visible
  • Unexpected result ( without this patch series): The triangle will not be visible

Changelog:

[Android] [BUGFIX] [ARTSurfaceViewShadowNode] - Properly release mSurface
[Android] [BUGFIX] [ARTSurfaceViewShadowNode] - Fix Surface becoming invisible in Android
[Android] [BUGFIX] [ARTSurfaceViewShadowNode] - Fix surface not being drawed on app startup

Fixes #17565

@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Dec 12, 2018
@pull-bot
Copy link

Warnings
⚠️

📋 Changelog - This PR may have incorrectly formatted Changelog.

Generated by 🚫 dangerJS

@cabelitos cabelitos changed the title Fix: The ART '<Surface>' becomes invisible in Android [FIX][Android]: The ART '<Surface>' becomes invisible in Android Dec 12, 2018
@cabelitos
Copy link
Contributor Author

cabelitos commented Dec 12, 2018

I'm not sure why test_objc/test_detox_end_to_end are failing for two reasons:

  • I did not touch on iOS code
  • I did no changes on the switch.js (also detox uses iOS, which I did not touch as well)
    😔
    By the way, how can I trigger the change log bot to parse the change log again?

@react-native-bot react-native-bot added the Platform: Android Android applications. label Dec 12, 2018
@Winglonelion
Copy link

@cabelitos i tried your codes but it not work.

More info: qemu (Nexus 5x android 7.0) in android studio.

screenshot_1545123809
screenshot_1545123824

@cabelitos
Copy link
Contributor Author

cabelitos commented Dec 18, 2018

Hello @Winglonelion, it's kinda difficult to know what's happening by only looking at your screenshot.
Is your app open source? can I take a look into it so I can debug it? or even better, can you isolate the problem? Did you try the test case that I provided in the PR summary?

@fnuttens
Copy link

Hello @cabelitos, I'm also trying to test your fix as I encountered the ART issue in one of my company's projects. I created a new project using your test plan, and then I directly applied your patch on React native's code (from the node_modules directory). It didn't change anything but maybe I need to build a fork of React native using your code?

@cabelitos
Copy link
Contributor Author

@fnuttens for android there's an specific build steps. Only applaying the patch will not solve the problem. You can follow this tutorial: https://facebook.github.io/react-native/docs/building-from-source
Keep in mind that you need to apply my patch before compiling

Since onSurfaceTextureDestroyed() returns true, the SurfaceTexture object will be released
by the Android automatically so there's no need to call release on it. However,
the node should release its refereces to the Surface object.
…tion

Starting on API level 25, Android will destroy the TextureView's TextureLayer when the
an app is sent to the background and automatically create a new one once the TextureView is
drawed again. This causes a problem for ARTSurfaceView, because this component does not draw itself
and the Android API explicitly forbids to do such action. Since there's no listeners available to know
when the new TextureLayer was created, the ARTSufurfaceViewShadowNode will listen for life cycle events
and redraw its children once the activity is resumed.

It's was also discussed that ARTSurfaceView should extends SurfaceView and not TextureView, however
this may introduce two problems:

* SurfaceView is not hardware accelerated, which may cause impact on performance
* SurfaceView does not support opacity, so it will be impossible to set the ARTSufraceView as
transparent

With this problems in mind, this commit keeps the ARTSurfaceView extending TextureView.

Fixes facebook#17565
Calls updateExtraData(), which registers the surface texture listener may arrive too late,
thus the SurfaceTexture may already have been created which will case onSurfaceTextureAvailable()
to never be called, ultimatilly causing the surface to not be drawed.

As a fix this patch checks if the SurfaceTexture is ready to use and if so draw the surface right away.
@Winglonelion
Copy link

Winglonelion commented Dec 19, 2018

@cabelitos my implement steps same as @fnuttens. But i clean and re-compile project after changes codes.

I think if it is a change in native codes, it would be affected when compile ?

this is completed screen record after i affect your changes and rebuild:

https://youtu.be/QBZG6VFOi0g

@cabelitos
Copy link
Contributor Author

cabelitos commented Dec 19, 2018

Hey @Winglonelion, thanks for the video. What's the android version that you're using it? From the emulator window at least it says you're running under API 24. In my code I only enable the new ART behavior if you're at API 25 and beyond. You could try changing the code to:

    // ReactAndroid/src/main/java/com/facebook/react/views/art/ARTSurfaceViewShadowNode.java
  @Override
  public void setThemedContext(ThemedReactContext themedContext) {
    super.setThemedContext(themedContext);
     // CHANGE HERE TO '>=' JUST LIKE THE CODE BELOW
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
      themedContext.addLifecycleEventListener(this);
    }
  }

Or you can complete remove the if and keep themedContext.addLifecycleEventListener(this);, like this:

    // ReactAndroid/src/main/java/com/facebook/react/views/art/ARTSurfaceViewShadowNode.java
  @Override
  public void setThemedContext(ThemedReactContext themedContext) {
    super.setThemedContext(themedContext);
    themedContext.addLifecycleEventListener(this);
  }

@Winglonelion
Copy link

@cabelitos Yes, as i mentioned, my simulator run as API 24.

Sorry because i didn't review your code more particullary.

What is the reason for specific behavior in 25 and larger API ?

I will test it in both API 24, 25 and reply soon

@cabelitos
Copy link
Contributor Author

@Winglonelion, ok I'll wait

roana0229 added a commit to roana0229/react-native that referenced this pull request Jan 27, 2019
roana0229 added a commit to roana0229/react-native that referenced this pull request Jan 27, 2019
roana0229 added a commit to roana0229/react-native that referenced this pull request Jan 27, 2019
@andrewmarmion
Copy link

Any update on this?

@cabelitos
Copy link
Contributor Author

@andrewmarmion I really wanted that the facebook folks could review this. :/

@cpojer
Copy link
Contributor

cpojer commented Apr 9, 2019

I tried this out on a real Galaxy S8 on Android 9 and cannot reproduce the issue you are describing in your original PR. Is there anything specific I am missing?

@danilobuerger
Copy link
Contributor

@cpojer I was able to reproduce the issue on my Pixel 3 with Android 9, RN 0.59. Don't know why it does not work for you.

@cpojer
Copy link
Contributor

cpojer commented Apr 16, 2019

Could you try to repro this on master using RNTester and sharing your code example (fork of RN?) with me with instructions on how to repro? As said, it didn’t repro for me and I’m inclined to close this PR unless somebody can prove this change is necessary.

@cabelitos
Copy link
Contributor Author

Sorry for the delay guys. Tomorrow I'll with my s8

@danilobuerger
Copy link
Contributor

@cabelitos Did you get around to testing it?

@cabelitos
Copy link
Contributor Author

Hey guys, I was not able to test on the s8, however the problem still happens on an Android Pie emulator. Here's a video: https://youtu.be/SIFRksrWX4Y

I'm using react-native latest version (0.59)

Copy link
Contributor

@cpojer cpojer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright, let's give it a try.

Copy link
Contributor

@facebook-github-bot facebook-github-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cpojer is landing this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@react-native-bot
Copy link
Collaborator

This pull request was successfully merged by @cabelitos in 20b09e4.

When will my fix make it into a release? | Upcoming Releases

@react-native-bot react-native-bot added the Merged This PR has been merged. label Apr 29, 2019
@cabelitos
Copy link
Contributor Author

cabelitos commented May 1, 2019

thank you guys!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Merged This PR has been merged. Platform: Android Android applications.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

The ART '<Surface>' becomes invisible in Android
10 participants