Status Update
Comments
ga...@google.com <ga...@google.com> #2
Thank you for reporting this issue. For us to further investigate this issue, please provide the following additional information:
Please mention the steps to be followed for reproducing the issue with the given sample apk.
Android full bug report capturing
After reproducing the issue, press the volume up, volume down, and power button simultaneously. This will capture a bug report on your device in the “bug reports” directory.
Alternate method
Navigate to “Developer options”, ensure “USB debugging” is enabled, then enable “Bug report shortcut”. Capture bug report by holding the power button and selecting the “Take bug report” option.
Screen record of the issue, for clarity
Please capture screen record or video of the issue using the following steps:
adb shell screenrecord /sdcard/video.mp4
Subsequently use following command to pull the recorded file:
adb pull /sdcard/video.mp4\
Note: Please upload the files to google drive and share the folder to
ga...@google.com <ga...@google.com> #3
Error: The intent action com.example.action (used to send a broadcast) matches the intent filter of a non-exported receiver, registered via a call to Context.registerReceiver, or similar. If you are trying to invoke this specific receiver via the action then you should use Intent.setPackage(<APPLICATION_ID>). [UnsafeImplicitIntentLaunch]
Button(onClick = { context.sendBroadcast(Intent("com.example.action")) }) {}
I wasn't aware that the explicit intent requirements from API 34 applied to broadcasts as well. I do think it would be beneficial to display this error when building the app for development, not just during the build task to produce an APK. Either way, the issue isn't an issue after all.
ga...@google.com <ga...@google.com> #4
Thanks.
ga...@google.com <ga...@google.com> #5
* Dynamically registered receiver with RECEIVER_EXPORTED flag: Can get broadcast with custom action sent from the same app using `Context#sendBroadcast()` API.
* Dynamically registered receiver with RECEIVER_NOT_EXPORTED flag: Cannot get broadcast with custom action sent from the same app using `Context#sendBroadcast()` API.
sl...@gmail.com <sl...@gmail.com> #6
Thank you for reporting this issue. We have shared this with our product and engineering team and will update this issue with more information as it becomes available.
az...@gmail.com <az...@gmail.com> #7
Our engineering team responded :
It is indeed related to the changes applied for Safer Implicit Intents, this is the intended behaviour.
To fix this issue, the developer will need to make the intent explicit (either explicit by package or explicit by component), the following change will fix it:
@Composable
fun Greeting(name: String, modifier: Modifier = Modifier, context: Context) {
Button(onClick = { context.sendBroadcast(Intent("com.example.action")) }) {}
}
should become something like:
@Composable
fun Greeting(name: String, modifier: Modifier = Modifier, context: Context) {
val intent = Intent("com.example.action")
intent.setPackage(context.getPackageName())
Button(onClick = { context.sendBroadcast(intent) }) {}
}
sl...@gmail.com <sl...@gmail.com> #8
vd...@gmail.com <vd...@gmail.com> #9
jo...@gmail.com <jo...@gmail.com> #10
We’ll be closing this issue due to not having enough actionable information. If you continue to have this issue, please open a new issue and add the relevant information along with a reference link to the earlier issue.
tr...@gmail.com <tr...@gmail.com> #11
sl...@google.com <sl...@google.com>
ch...@gmail.com <ch...@gmail.com> #12
fr...@gmail.com <fr...@gmail.com> #13
I have registered the receiver with a custom action.
Sending like this:
Intent intent = new Intent("com.gt-broadcast-refresh");
requireActivity().sendBroadcast(intent);
Receiving like this:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
requireActivity().registerReceiver(refreshUIReceiver, new IntentFilter("com.gt-broadcast-refresh"), Context.RECEIVER_NOT_EXPORTED);
} else {
requireActivity().registerReceiver(refreshUIReceiver, new IntentFilter("com.gt-broadcast-refresh"));
}
It will work in the emulator with an Android 14 device, but it will not work on a real device, such as the Google Pixel 8 Pro, because it will not listen to the action. I have configured the registration based on the Google documentation for Android 14.
should I need to add any extra flag or permission while sending the custom action?
ma...@gmail.com <ma...@gmail.com> #14
All, I found the solution for all requireActivity().registerReceiver()
calls. They will only listen for the action if the action is sent with the package name of the application. So whenever we send a broadcast, we should also set the package with the intent using intent.setPackage(getPackageName())
. Then, the registered receiver will be able to listen for the action.
Reference link:
[Deleted User] <[Deleted User]> #15
Unbelievable, 9 months later this is still not in the docs.
hu...@google.com <hu...@google.com> #16
[Deleted User] <[Deleted User]> #17
sa...@gmail.com <sa...@gmail.com> #18
ni...@gmail.com <ni...@gmail.com> #19
ni...@gmail.com <ni...@gmail.com> #20
ma...@gmail.com <ma...@gmail.com> #21
No coverage is generated in the expected filepath when using clearPackageData: 'true'
ch...@gmail.com <ch...@gmail.com> #22
This should not be this difficult to get an understandable answer on such a long running issue. We are all wasting our time whenever we experiment with your vague "fixes."
Someone from Google please post an example gradle file and link a project that is actually properly making use of this coverage feature as described in this issue.
ma...@gmail.com <ma...@gmail.com> #23
sc...@gmail.com <sc...@gmail.com> #24
hu...@google.com <hu...@google.com>
hu...@google.com <hu...@google.com>
hu...@google.com <hu...@google.com> #25
Thank you very much for reporting the issue and waiting for us to address it. We've reinvestigated it and found some more issues. We've fixed it on the head of our development branch. That fix should be included in the next release of the canary version of the Android Gradle plugin, however there will be some limitations.
When you use "clearPackageData" option along with the test coverage enabled, the Android test orchestrator calls "pm clear" to delete all data of your application being tested before each test case. Thus, you have to save your test coverage file in somewhere outside of your application package private storage, '/storage/emulated/0/coverage' for example. It requires you to declare WRITE_EXTERNAL_STORAGE permission in your AndroidManifest.xml file. In addition, you have to grant WRITE_EXTERNAL_STORAGE permission at runtime. Because "pm clear" revokes all the granted permissions, installing the app with "-g" option doesn't help. An easy way to do this is to use GrantPermissionRule.grant(Manifest.permission.WRITE_EXTERNAL_STORAGE), or you can manually grant this permission in your test's teardown if you don't want to grant this permission during the test.
Here's a small working example:
// build.gradle
android {
defaultConfig {
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
testInstrumentationRunnerArguments clearPackageData: 'true'
testInstrumentationRunnerArguments coverageFilePath: '/storage/emulated/0/coverage'
}
buildTypes {
debug {
testCoverageEnabled = true
}
}
testOptions {
execution 'ANDROIDX_TEST_ORCHESTRATOR'
}
dependencies {
androidTestImplementation 'androidx.test:core:1.3.1-alpha02'
androidTestImplementation 'androidx.test.ext:junit:1.1.3-alpha02'
androidTestImplementation 'androidx.test:monitor:1.3.1-alpha02'
androidTestImplementation 'androidx.test:rules:1.3.1-alpha02'
androidTestImplementation 'androidx.test:runner:1.3.1-alpha02'
androidTestImplementation 'androidx.test.services:test-services:1.3.1-alpha02'
androidTestUtil 'androidx.test:orchestrator:1.3.1-alpha02'
}
}
// ExampleInstrumentedTest.kt
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.rule.GrantPermissionRule
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@get:Rule
var mRuntimePermissionRule: GrantPermissionRule =
GrantPermissionRule.grant(Manifest.permission.WRITE_EXTERNAL_STORAGE)
@Test
fun test1() {
}
}
<!-- AndroidManifest.xml -->
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.orchestratorexample">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
</manifest>
We're aware of that the requirement of WRITE_EXTERNAL_STORAGE permission in the tested application is not ideal and we're working on the better solution from the test services APK side. I filed a separate bug
ma...@gmail.com <ma...@gmail.com> #26
ma...@gmail.com <ma...@gmail.com> #27
AGP version: 4.2.0-beta03 (the latest at this moment in time)
Gradle version: 6.7.1
Test dependencies:
androidTestImplementation 'androidx.test:core:1.3.1-alpha02'
androidTestImplementation 'androidx.test.ext:junit:1.1.3-alpha02'
androidTestImplementation 'androidx.test:monitor:1.3.1-alpha02'
androidTestImplementation 'androidx.test:rules:1.3.1-alpha02'
androidTestImplementation 'androidx.test:runner:1.3.1-alpha02'
androidTestImplementation 'androidx.test.services:test-services:1.3.1-alpha02'
androidTestUtil 'androidx.test:orchestrator:1.3.1-alpha02'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0-alpha02'
androidTestImplementation 'androidx.test.espresso:espresso-intents:3.4.0-alpha02'
androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.4.0-alpha02'
androidTestImplementation 'androidx.test.espresso:espresso-idling-resource:3.4.0-alpha02'
androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0'
buildToolsVersion: 30.0.3
targetSDKVersion: 29 (it would fail to grant WRITE_EXTERNAL_STORAGE permissions, if the target SDK would be 30, as you probably know, Google engineers)
I have tried everything for 3 whole days: nothing works; it's incredible how something so important for testing fails so miserably.
ma...@gmail.com <ma...@gmail.com> #28
ma...@gmail.com <ma...@gmail.com> #29
pa...@willowtreeapps.com <pa...@willowtreeapps.com> #30
Using AGP 7.0.0-alpha14, I'm seeing it put the file in the correct place, however my file is empty and I'm seeing java.lang.IllegalStateException: JaCoCo agent not started
, though that may not be related. Currently digging into that, but for those that are saying the testInstrumentationRunnerArguments coverageFilePath:
attribute is ignored, that isn't true on the latest alpha AGP.
pa...@willowtreeapps.com <pa...@willowtreeapps.com> #31
Alright so the issue I see now with AGP 7.0.0-alpha14 is that the coverage files are stored in an external location on the device, however they're not pulled into the build directory for generating the report, resulting in java.io.IOException: No coverage data to process in directories...
Is there another step I'm missing, or is this a current oversight in the alpha plugin?
ar...@google.com <ar...@google.com>
ch...@gmail.com <ch...@gmail.com> #32
I understand that it takes time to get someone to work on this each cycle but we at least need to be honest here about the status. Theoretical fixes are not complete and ready for the public. We need a working example; which you should also need to create anyway to prove it all works!
lu...@gmail.com <lu...@gmail.com> #33
I found this stacktrace in logcat
2021-04-16 10:33:38.447 12402-12459/com.example.test.dev E/CoverageListener: Failed to generate Emma/JaCoCo coverage.
java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at androidx.test.internal.runner.listener.CoverageListener.generateCoverageReport(CoverageListener.java:101)
at androidx.test.internal.runner.listener.CoverageListener.instrumentationRunFinished(CoverageListener.java:70)
at androidx.test.internal.runner.TestExecutor.reportRunEnded(TestExecutor.java:92)
at androidx.test.internal.runner.TestExecutor.execute(TestExecutor.java:65)
at androidx.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:392)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:2189)
Caused by: java.io.FileNotFoundException: /data/data/com.example.test.dev/coverage_data/com.example.test.DepartureListFragmentTest#show_error_no_internet.ec: open failed: ENOENT (No such file or directory)
at libcore.io.IoBridge.open(IoBridge.java:496)
at java.io.FileOutputStream.<init>(FileOutputStream.java:235)
at com.vladium.emma.rt.RT.dumpCoverageData(RT.java:50)
at java.lang.reflect.Method.invoke(Native Method)
at androidx.test.internal.runner.listener.CoverageListener.generateCoverageReport(CoverageListener.java:101)
at androidx.test.internal.runner.listener.CoverageListener.instrumentationRunFinished(CoverageListener.java:70)
at androidx.test.internal.runner.TestExecutor.reportRunEnded(TestExecutor.java:92)
at androidx.test.internal.runner.TestExecutor.execute(TestExecutor.java:65)
at androidx.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:392)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:2189)
Caused by: android.system.ErrnoException: open failed: ENOENT (No such file or directory)
at libcore.io.Linux.open(Native Method)
at libcore.io.ForwardingOs.open(ForwardingOs.java:167)
at libcore.io.BlockGuardOs.open(BlockGuardOs.java:252)
at libcore.io.ForwardingOs.open(ForwardingOs.java:167)
at android.app.ActivityThread$AndroidOs.open(ActivityThread.java:7255)
at libcore.io.IoBridge.open(IoBridge.java:482)
at java.io.FileOutputStream.<init>(FileOutputStream.java:235)
at com.vladium.emma.rt.RT.dumpCoverageData(RT.java:50)
at java.lang.reflect.Method.invoke(Native Method)
at androidx.test.internal.runner.listener.CoverageListener.generateCoverageReport(CoverageListener.java:101)
at androidx.test.internal.runner.listener.CoverageListener.instrumentationRunFinished(CoverageListener.java:70)
at androidx.test.internal.runner.TestExecutor.reportRunEnded(TestExecutor.java:92)
at androidx.test.internal.runner.TestExecutor.execute(TestExecutor.java:65)
at androidx.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:392)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:2189)
It seem like CoverageListener.generateCoverageReport
run when a new test being executed, at this time app data was cleared by clearPackageData
is true. So, no .ec
file is copied to external storage.
wb...@gmail.com <wb...@gmail.com> #34
hu...@google.com <hu...@google.com>
ma...@jackpocket.com <ma...@jackpocket.com> #35
If it is still blocked, should #175426813 be escalated to P1 to match the severity of this issue? It is unassigned and hasn't been updated since late 2020.
hu...@google.com <hu...@google.com> #36
No, this issue has been fixed already but missing an example project. I'll create an example and add it to
hu...@google.com <hu...@google.com> #37
gr...@gmail.com <gr...@gmail.com> #38
By sheer coincidence, I was making my own test sample mostly so that I could make sure that coverage continued to work through future SDK / AGP versions. I've hosted it at
I'll do some updates so that it makes use of the right dependencies and settings so that it can use the test service and hopefully work on 30+.
[Deleted User] <[Deleted User]> #39
gr...@gmail.com <gr...@gmail.com> #40
You need AGP>7.1 (still in beta), but it does work when using the test services util on devices >=30. I updated my repo to show.
ma...@jackpocket.com <ma...@jackpocket.com> #42
Experiencing the same issues as
2022-01-27T11:25:07.254-0800 [INFO] [com.android.build.gradle.internal.testing.utp.worker.RunUtpWorkAction] 11:25:01 E/Device: Error during Sync: Remote object doesn't exist!
2022-01-27T11:25:07.254-0800 [ERROR] [com.android.build.gradle.internal.testing.utp.worker.RunUtpWorkAction] Jan 27, 2022 11:25:01 AM com.android.tools.utp.plugins.host.additionaltestoutput.AndroidAdditionalTestOutputPlugin deviceShellAndCheckSuccess
WARNING: Shell command failed (1): ls "/sdcard/Android/media/***/additional_test_output"
ls: /sdcard/Android/media/***/additional_test_output: No such file or directory
Jan 27, 2022 11:25:01 AM com.android.tools.utp.plugins.host.additionaltestoutput.AndroidAdditionalTestOutputPlugin afterAll
WARNING: Failed to retrieve additional test outputs from device.
com.android.ddmlib.SyncException: Remote object doesn't exist!
at com.android.ddmlib.SyncService.pullFile(SyncService.java:341)
...
.ec
files appear to be generated for each test, but also seem to be unusable -- a report could not be generated from them directly.
ma...@jackpocket.com <ma...@jackpocket.com> #43
Same behavior in 7.1.2. Is there any update on this ticket?
ro...@gmail.com <ro...@gmail.com> #45
Are there any solutions to this problem?
WARNING: Failed to retrieve additional test outputs from device.
com.android.ddmlib.SyncException: Remote object doesn't exist!
hu...@google.com <hu...@google.com> #46
It should work in AGP version 7.1.0-alpha12 and above but could you try using the latest AGP version might show you a better warning message? The test coverage data is stored in the additional test outputs directory using the test storage service API. The error message; "WARNING: Failed to retrieve additional test outputs from device. com.android.ddmlib.SyncException: Remote object doesn't exist!", sounds like AGP couldn't create the directory for your testing device.
Please also make sure that you enable "useTestStorageService" and add the dependency in your build.gradle file.
android {
defaultConfig {
testInstrumentationRunnerArguments useTestStorageService: 'true'
}
}
dependencies {
androidTestUtil 'androidx.test.services:test-services:' + rootProject.testServicesVersion
}
ma...@gmail.com <ma...@gmail.com> #47
ja...@drivedominion.com <ja...@drivedominion.com> #48
ed...@gmail.com <ed...@gmail.com> #49
This works
> Task :app:createDebugAndroidTestCoverageReport FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:createDebugAndroidTestCoverageReport'.
> A failure occurred while executing com.android.build.gradle.internal.coverage.JacocoReportTask$JacocoReportWorkerAction
> Unable to generate Jacoco report
Caused by: java.io.IOException: Unknown block type 6.
at org.jacoco.core.data.ExecutionDataReader.readBlock(ExecutionDataReader.java:119)
at org.jacoco.core.data.ExecutionDataReader.read(ExecutionDataReader.java:93)
at org.jacoco.core.tools.ExecFileLoader.load(ExecFileLoader.java:60)
at org.jacoco.core.tools.ExecFileLoader.load(ExecFileLoader.java:74)
at com.android.build.gradle.internal.coverage.JacocoReportTask$JacocoReportWorkerAction$Companion.generateReport(JacocoReportTask.kt:303)
at com.android.build.gradle.internal.coverage.JacocoReportTask$JacocoReportWorkerAction.execute(JacocoReportTask.kt:269)
... 32 more
ed...@gmail.com <ed...@gmail.com> #50
Please ignore
coreVersion = "1.6.0-alpha05"
Description
Not really as its the project at the company where I work. Its a huge project so not small task to maintain - hence the need for test coverage...
I've tried trouble shooting most of the day and so far no luck. I really have no idea where to start looking.
Not sure if it will help but the complete output when running ./gradlew createWorldDebugCoverageReport is attached.
I've tried against an emulator (genymotion) as well as a real device - same result.
I guess the next logical step is to setup a basic project and see if that has the same problem...