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

App crash : 'Resource leak' and 'HardwareBuffer.close not called ' issue while using getScreenshotAs method of appium android driver #654

Open
Ganesha-Deshmukh opened this issue Jul 5, 2024 · 3 comments

Comments

@Ganesha-Deshmukh
Copy link

Problem statement
I'm doing the UI automation using the appium-uiautomator2-server-v4.27.0.apk apk's Or appium-uiautomator2-server-v7.0.14.apk.
I'm calling the interface "((TakesScreenshot)session).getScreenshotAs(OutputType.FILE)" using the appium Android driver session.
After calling this method, I have observed following exception in logcat
Log
W System : A resource was acquired at attached stack trace but never released. See java.io.Closeable for information on avoiding resource leaks.
W System : java.lang.Throwable: Explicit termination method 'HardwareBuffer.close' not called
W System : at dalvik.system.CloseGuard.openWithCallSite(CloseGuard.java:288)
W System : at dalvik.system.CloseGuard.open(CloseGuard.java:257)
W System : at android.hardware.HardwareBuffer.(HardwareBuffer.java:272)

Overall impact
Its start crashing the application after sometimes.
Primary Root cause analysis
After looking into the [appium-uiautomator2-server apk source code I observed that the method "takeDeviceScreenshot" of a class ScreenshotHelper get called.
After doing debug on it, its observed that the condition "if (metrics.densityDpi != DENSITY_DEFAULT && Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) " is not met because the express 'metrics.densityDpi != DENSITY_DEFAULT' value is false.
So it invokes the method "screenshot = automation.takeScreenshot();" .After calling this method it take the screenshot but throws exception of resource leak shown as above.

Display metrics: DisplayMetrics{density=1.0, width=1744, height=720, scaledDensity=1.0, xdpi=167.013, ydpi=167.779}
Log value print for the expression "metrics.densityDpi != DENSITY_DEFAULT && Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1" are as follows:
metrics.densityDpi: 160
DENSITY_DEFAULT: 160
Build.VERSION.SDK_INT: 33
Build.VERSION_CODES.LOLLIPOP_MR1: 22

Observation
On commenting the expression "metrics.densityDpi != DENSITY_DEFAULT " no issue occurred
Overall, the call of "automation.executeShellCommand("screencap -p") " is working on android 8,10,12,13 but the call "automation.takeScreenshot()" is not working on Android 12 and 13.

Note
Issue occurred on the device which is using Android Automotive OS of android version 12 and 13. Same issue is no occurring for android version 8 and 10. Difference between these 2 is only metrics.densityDpi.

@mykola-mokhnach
Copy link
Contributor

Thanks for the investigation @Ganesha-Deshmukh

The above automation.takeScreenshot() method belongs to the UiAutomator API and we don't have any control over it.
I have double checked that the returned Bitmap instance is recycled after it is used, otherwise there is nothing else to close in this API from the client side.

Please report the issue to Google.

@Ganesha-Deshmukh
Copy link
Author

Thank you for your quick response @mykola-mokhnach
I have reported this issue to google and sharing its tracker id
https://issuetracker.google.com/issues/351092760

It will be helpful if you provide the information about the need of expression "metrics.densityDpi != DENSITY_DEFAULT" in statement "if (metrics.densityDpi != DENSITY_DEFAULT && Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) {"
in method "takeDeviceScreenshot(Class outputType)" of class "ScreenshotHelper"
There is one comment but not sure does this expression of android 5 .

@mykola-mokhnach
Copy link
Contributor

The original reason why the screencap workaround has been added was another bug in the UiAutomator where the retrieved bitmap was wrong for non-default DPIs. See #248 for more details.

The main path still uses the UiAutomator call because it's more performant in comparison to the screencap workaround, e.g. enabling it by default would slow down customer scenarios.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants