Status Update
Comments
da...@google.com <da...@google.com>
sp...@google.com <sp...@google.com> #2
It seems the print is benign so I'll remove it; Could be worth it to find out how the message carrying information about "cb 0" (0 is not a valid color buffer handle) ever arrives to that line though
da...@google.com <da...@google.com> #3
sp...@google.com <sp...@google.com> #4
I agree with Sergey -- while I think it's fine to remove some logging messages that aren't necessary, the root problem here is that Studio shows everything emitted as if they are errors, with one notification bubble per message. We don't do that for other tools that Studio launches, and in particular, this isn't specific to the "cb 0" message I showed here; there were earlier (different) error messages during the boot as well.
da...@google.com <da...@google.com> #5
This behavior was requested specifically by the emulator team (vharron@ iirc, so at least 3-4 years ago). Let me see if I have any more details on why this was requested.
sp...@google.com <sp...@google.com> #6
I couldn't find any relevant threads. IIRC, the main concern at that time was that warnings at startup (e.g. missing acceleration) really needed to be bubbled up to the users. If that is not an issue anymore, and the emulator team only wants errors to be visible, then the proposed change SGTM.
da...@google.com <da...@google.com> #7
Yes, I vaguely remember that in some cases, you'd hit run, and then the emulator would fail to start (for example aborting because of some missing thing it needed), so we needed a way to surface these reasons. I don't know if there are any fatal startup errors like this. It seems like there are several things we could do here:
(1) Simplest: just reroute the errors into the log, and if emulator fails to start, that's where people can look. (I think that's what Sergey has already implemented?)
(2) If emulator could update itself to prefix truly fatal error messages in some way (such as error:) and use that for only fatal/exit(-1) reasons, then we could multiplex the output -- errors are shown in notifications as today, everything else is silently dumped to the log
(3) Hold on to the emulator output, and if there's a problem starting the emulator (say if it exits within a few seconds), then show all the emulator output.
sp...@google.com <sp...@google.com> #8
(2) More discipline in the emulator's messages would definitely help. Right now they don't seem to follow any simple set of rules (the "Emulator: " prefix is added by Studio):
2020-05-06 11:07:04,587 [ 38858] INFO - manager.EmulatorProcessHandler - Emulator: /usr/local/google/home/sprigogin/Android/Sdk/emulator/emulator -netdelay none -netspeed full -avd Nexus_10_API_29 -no-window -gpu auto-no-window -grpc-use-token
2020-05-06 11:07:04,976 [ 39247] INFO - manager.EmulatorProcessHandler - Emulator: pulseaudio: Failed to initialize PA contextaudio: Could not init `pa' audio driver
2020-05-06 11:07:04,985 [ 39256] INFO - manager.EmulatorProcessHandler - Emulator: E0506 11:07:04.983601525 31440 socket_utils_common_posix.cc:201] check for SO_REUSEPORT: {"created":"@1588788424.983585430","description":"SO_REUSEPORT unavailable on compiling system","file":"/mnt/tmpfs/src/android/emu-master-dev/external/grpc/src/core/lib/iomgr/socket_utils_common_posix.cc","file_line":169}
2020-05-06 11:07:05,321 [ 39592] INFO - manager.EmulatorProcessHandler - Emulator: Your emulator is out of date, please update by launching Android Studio:
2020-05-06 11:07:05,321 [ 39592] INFO - manager.EmulatorProcessHandler - Emulator: - Start Android Studio
2020-05-06 11:07:05,321 [ 39592] INFO - manager.EmulatorProcessHandler - Emulator: - Select menu "Tools > Android > SDK Manager"
2020-05-06 11:07:05,321 [ 39592] INFO - manager.EmulatorProcessHandler - Emulator: - Click "SDK Tools" tab
2020-05-06 11:07:05,321 [ 39592] INFO - manager.EmulatorProcessHandler - Emulator: - Check "Android Emulator" checkbox
2020-05-06 11:07:05,321 [ 39592] INFO - manager.EmulatorProcessHandler - Emulator: - Click "OK"
2020-05-06 11:07:05,321 [ 39592] INFO - manager.EmulatorProcessHandler - Emulator:
2020-05-06 11:07:06,475 [ 40746] INFO - manager.EmulatorProcessHandler - Emulator: emulator: INFO: LoggingInterceptor.cpp:70: 1588788426470945, rcvTime: 84, sndTime: 995, UNARY, rcv: 24, snd: 12156, /android.emulation.control.EmulatorController/getStatus() -> [...], OK
2020-05-06 11:07:07,355 [ 41626] INFO - manager.EmulatorProcessHandler - Emulator: emulator: INFO: LoggingInterceptor.cpp:70: 1588788426597819, rcvTime: 34, sndTime: 12945, SERVER_STREAMING, rcv: 48, snd: 1104071, /android.emulation.control.EmulatorController/streamScreenshot(format: RGBA8888 width: 665 height: 1064) -> [...], OK
sp...@google.com <sp...@google.com> #9
The pending fix in #8 changes AGP's behavior to include native libraries from the app's external native build in the android test APK, but that will make it so that users would need to manually exclude the test .so files from their application APK.
Is the desired behavior to support having a src/androidTest/cpp
source directory and package the resulting .so files only in the android test APK?
da...@google.com <da...@google.com> #10
Is the desired behavior to support having a src/androidTest/cpp source directory and package the resulting .so files only in the android test APK?
It'd likely be quite cumbersome to do so. There are extra hoops that would need to be jumped through for the test in src/androidTest/cpp
to refer to the implementation in src/main/cpp
. I don't think there's a good way to simplify that workflow either.
The intent behind externalNativeBuild
is that users should be able to reuse existing CMake projects in AGP without needing the dramatically reorganize the project to fit AGP. Some porting work is usually expected, but it shouldn't require changing the layout of a project's source, so we sort of need to keep test sources in src/main/cpp
.
We do need some way to communicate to AGP that some libraries defined by externalNativeBuild
should be in the test APK but not in the main APK. I'd be content with an explicit packagingOptions
DSL for that. CMake does have add_test
, but that's for executables, which isn't how junit-gtest
works, so that won't work. I'm not sure if there's another way to identify which CMake (or ndk-build, for that matter) outputs are tests and which are implementation, so it likely does need to be explicitly managed by the user?
+jomof in case he has better ideas.
sp...@google.com <sp...@google.com> #11
+xav
We do need some way to communicate to AGP that some libraries defined by externalNativeBuild should be in the test APK but not in the main APK.
This is possible with the snippet from #2 after Change-Id: I2caf6a4832a2781790b5c7ee9a66d11e4835bd36 (I added this to the test in the latest patch).
I'd be content with an explicit packagingOptions DSL for that. CMake does have add_test, but that's for executables, which isn't how junit-gtest works, so that won't work. I'm not sure if there's another way to identify which CMake (or ndk-build, for that matter) outputs are tests and which are implementation, so it likely does need to be explicitly managed by the user?
If there's no way for AGP to detect this implicitly, then we can consider adding a DSL for this special case (for ease of use, compared to #2).
xa...@google.com <xa...@google.com> #12
I think there are 2 separate problems here:
-
AGP currently skips all the native libs from test APKs (which Scott's CL attempts to fix). We need to be careful there and understand what happens if the same lib is packaged in both prod and test APKs. It does make sense that native libs coming from test-only dependencies are packaged in the test APKs but we should filter out libs that are coming via the prod dependencies.
-
Building native code via
externalNativeBuild
does not go in the test APK. The issue is that there's no way to target what it's for (prod and/or test) and because the external build can build several.so
files, we need granularity in pointing each native libs to their target APK (or AAR). We need to figure this one out.
xa...@google.com <xa...@google.com> #13
did I forget something?
sp...@google.com <sp...@google.com> #14
Thanks, Xav.
I think I'll need to write a doc for this, but I'm thinking we can add something like val testOnly: MutableSet<String>
to the JniLibsPackaging
DSL.
Example usage:
android {
packaging {
jniLibs {
testOnly += '**/testStuff.so'
}
}
}
If nothing is added to testOnly
, the behavior will be the same as today, but if patterns are added to testOnly
, matching native libs (from externalNativeBuild
or otherwise) will be excluded from the prod APK/AAR and included in the android test APK.
xa...@google.com <xa...@google.com> #15
Yes, something like this could work.
da...@google.com <da...@google.com> #16
+1 from me as well. That'd work great!
em...@google.com <em...@google.com> #17
Hi Scott, did you get a chance to write a doc for the proposal you have in
Dan, this is something we still need, right? Is it a blocker for
sp...@google.com <sp...@google.com> #18
Hi Emre, sorry for the delay... I just got back from leave this week.
I haven't written a doc yet, but I'll prioritize it now that I'm back.
da...@google.com <da...@google.com> #19
Yes, still needed.
sp...@google.com <sp...@google.com> #20
Sorry again for the delay. I'm looking into this now, but I want to clarify what's needed.
The proposal in
In a comment in ag/20833989, you suggest that it might be sufficient for your use case to simply include the .so files in both the androidTest APK and the main APK. I don't think we'd want to do that by default in AGP, but it might make sense to add a flag to enable that behavior instead of adding the DSL if that solution seems equally good to you. WDYT?
sp...@google.com <sp...@google.com>
da...@google.com <da...@google.com> #21
We probably do need it for both dependencies and jniLibs. My first instinct was that a dependency that made test-only libraries available in an AAR should do so in a separate AAR, but that's actually what the problem is here. That separate test AAR would need to be pulled in as part of the same gradle configuration, since for externalNativeBuild
, there isn't a distinct test configuration. Tests are built by the same configuration as the implementation. That's actually partly the case in the motivating example for this bug. The dependency we first discovered this with was junit-gtest. We don't want those libraries in the real APK, but we do need them at test time.
In a comment in ag/20833989, you suggest that it might be sufficient for your use case to simply include the .so files in both the androidTest APK and the main APK.
Sorry. Not sure what I was thinking when I left that comment, but that's just wrong. The problem we have is that when we build a library that contains native tests, e.g. libapp_test.so, libapp_test.so will end up in the prod APK. That's useless bloat that just increases on-disk and download side for users. If we try to exclude the library from the APK, the tests no longer work because the test library is not available, because it's not in the test APK either.
This is a problem both for app APKs and for library AARs. For example, junit-gtest originally shiped its own tests that consumers needed to filter out of their own APKs:
- Remove its own tests
- Move its tests to a separate gradle project
It went with option 2, but it's cumbersome and isn't going to be a viable option for every project.
sp...@google.com <sp...@google.com>
sp...@google.com <sp...@google.com> #22
Internal design doc
As mentioned in the doc, there is a workaround to exclude .so files from release variants that can be used in cases where devs are not testing against the release variant.
For example, adding this block to Junit-Gtest's build.gradle
file will exclude the unnecessary test .so files from the published AAR:
androidComponents {
onVariants(selector().withBuildType("release"), {
packaging.jniLibs.excludes.add("**/libtestartifact.so")
packaging.jniLibs.excludes.add("**/libtest.so")
})
}
sp...@google.com <sp...@google.com> #23
Question after reviewing the above doc with AGP team:
Would it be possible for the external native build to instead detect and output test-only .so files to a separate external native build output directory?
an...@google.com <an...@google.com> #25
Thank you for your patience while our engineering team worked to resolve this issue. A fix for this issue is now available in:
- Android Studio Jellyfish | 2023.3.1 Canary 12
- Android Gradle Plugin 8.4.0-alpha12
We encourage you to try the latest update.
If you notice further issues or have questions, please file a new bug report.
Thank you for taking the time to submit feedback — we really appreciate it!
sp...@google.com <sp...@google.com> #26
Re: #24 and #25 - sorry, my mistake, it's AGP 8.4.0-alpha13
(not alpha12).
Description
I'm not sure if this should be filed as a C++ issue or if it's a generic packaging issue.
We've been working on adding instrumentation testing support for native code by wrapping native test libraries in junit. We do this with an androidx library called junit-gtest. That's all working great... until you inspect the AARs and APKs that are produced by a gradle module that has native tests.
The problem is that the test libraries are being bundled into the main APK/AAR. If we work around this by excluding the test libraries in packagingOptions, the test libraries are excluded from the test APK as well. Seehttps://android-review.googlesource.com/c/platform/frameworks/support/+/2106823/9/test/ext/junit-gtest/src/main/cpp/CMakeLists.txt#b32 for an example.
We need a way to exclude some native libraries from being packaged in the main APK (or AAR), but include them in the test APK (or AAR). Until then native tests and implementation cannot live in the same gradle module.