Status Update
Comments
to...@gmail.com <to...@gmail.com> #2
We have shared this with our product and engineering team and will update this issue with more information as it becomes available.
sg...@google.com <sg...@google.com> #3
Thank you for the report. I didn't know that Play has started to check for this. Could it be that you updated a dependency which has code using removeFirst
or removeLast
?
to...@gmail.com <to...@gmail.com> #4
I have no idea how to detect that but I doubt.
It's possibly a new check from Play Store and the issue is older than that. Anything in the mapping I could look for or something else ?
The interesting thing about the media 3 LoudnessCodecController from the mapping reported is that it's an Android 35+ feature so maybe there's some optimisations running because of that and it's the Play Store check that is invalid?
to...@gmail.com <to...@gmail.com> #5
The bytecode for D5.h.e
It does actually generate a removeFirst()
java call that could be problematic if that file was not API 35+.
So it's either R8 who optimize too much by knowing it's API 35 and using that call, or R8 is correct and the Play Store check have no way to detect that it's fine and should be ignored.
In all cases seems it's something to see between you guys.
.class public abstract synthetic Ld5/h;
.super Ljava/lang/Object;
.source "SourceFile"
# direct methods
.method public static bridge synthetic a(ILd5/i;)Landroid/media/LoudnessCodecController;
.registers 3
sget-object v0, Lgu/n;->u:Lgu/n;
invoke-static {p0, v0, p1}, Landroid/media/LoudnessCodecController;->create(ILjava/util/concurrent/Executor;Landroid/media/LoudnessCodecController$OnLoudnessCodecUpdateListener;)Landroid/media/LoudnessCodecController;
move-result-object p0
return-object p0
.end method
.method public static bridge synthetic b(Landroid/media/LoudnessCodecController;)V
.registers 1
invoke-virtual {p0}, Landroid/media/LoudnessCodecController;->close()V
return-void
.end method
.method public static bridge synthetic c(Landroid/media/LoudnessCodecController;Landroid/media/MediaCodec;)V
.registers 2
invoke-virtual {p0, p1}, Landroid/media/LoudnessCodecController;->removeMediaCodec(Landroid/media/MediaCodec;)V
return-void
.end method
.method public static bridge synthetic d(Landroid/text/StaticLayout$Builder;)V
.registers 2
const/4 v0, 0x0
invoke-virtual {p0, v0}, Landroid/text/StaticLayout$Builder;->setUseBoundsForWidth(Z)Landroid/text/StaticLayout$Builder;
return-void
.end method
.method public static bridge synthetic e(Ljava/util/ArrayList;)V
.registers 1
invoke-virtual {p0}, Ljava/util/ArrayList;->removeFirst()Ljava/lang/Object;
return-void
.end method
.method public static bridge synthetic f(Landroid/media/LoudnessCodecController;Landroid/media/MediaCodec;)Z
.registers 2
invoke-virtual {p0, p1}, Landroid/media/LoudnessCodecController;->addMediaCodec(Landroid/media/MediaCodec;)Z
move-result p0
return p0
.end method
sg...@google.com <sg...@google.com> #6
I found the check in Play, and it is looking for these six signatures, and raising the flag you see for the following signatures:
Ljava/util/ArrayList;->removeFirst()Ljava/lang/Object;
Ljava/util/ArrayList;->removeLast()Ljava/lang/Object;
Ljava/util/List;->removeFirst()Ljava/lang/Object;
Ljava/util/List;->removeLast()Ljava/lang/Object;
Ljava/util/SequencedCollection;->removeFirst()Ljava/lang/Object;
Ljava/util/SequencedCollection;->removeLast()Ljava/lang/Object;
And the first signature is clearly in your code. The class containing the code seems to be an API outline class, where calls are outlined to avoid soft verification errors. The class android.media.LoudnessCodecController
was added in API 35, and all use of that is outlined. Likewise removeFirst
on ArrayList
is outlined.
As far as I can see the checks for the six signatures above is trying to see if this is under an SDK_INT
check, but as it has been outlined it is no longer in the method (if it even was there). The class androidx.media3.exoplayer.mediacodec.LoudnessCodecController
removeFirst
on ArrayList
in this class should be fine.
Is this "just" an info/warning on Play or does it prevent publishing?
tolriq@ can you find the invoke(s) to the the outline e
, to give the original unobfuscated location removeFirst
(should be in LoudnessCodecController
I don't see any direct use in the Java code).
to...@gmail.com <to...@gmail.com> #7
It requires tons of clicks to ignore but I can force publish.
tolriq@ can you find the invoke(s) to the the outline e, to give the original unobfuscated location removeFirst (should be in LoudnessCodecController I don't see any direct use in the Java code).
Not sure to understand what you want here sorry.
sg...@google.com <sg...@google.com> #8
God to hear that you are not completely blocked from releasing.
What I am looking for in ArrayList.removeFirst
actually originates from (where the outline is called). So looking in your smali of the whole app finding the invoke-static of method d5.h.e
. Searching for Ld5/h;->e(
should do the trick.
I looked into the library androidx.media3:media3-exoplayer:1.6.0-beta01
which contains class androidx.media3.exoplayer.mediacodec.LoudnessCodecController
. However the only removeFirst
invocations I could find in that was on java.util.Deque
and java.util.ArrayDeque
.
to...@gmail.com <to...@gmail.com> #9
I've sent you the AAB by mail.
AFAIK there's no calls to removeFirst on anything related to media3. Since it should be a compile time issue, the only dependency I have that compile against SDK 35 and have a call would be
sg...@google.com <sg...@google.com> #10
With help from then reporter the code containing the ArrayList.removeFirst
calls was located to be in the
The code from androidx.media3.exoplayer.mediacodec.LoudnessCodecController
was not involved after all, but due to R8 optimizations outline unrelated code was merged with outlines from that class.
The Play report is correctly warning about app compatibility, so other users of the Haze library can get similar reports.
to...@gmail.com <to...@gmail.com> #11
As answered by email, it is currently very hard to find the actual source after R8 as I had no idea how to find out the actual cause. Others probably will have the same issue for other cases. Some tool or data in the mapping file would avoid frustration as not all users are aware of R8 issue tracker and how things are rewritten.
sg...@google.com <sg...@google.com> #12
I just came to thing about what the easiest way to find the location could be. Maybe uploading a build using -dontoptimize
, -dontobfuscate
to Play could be a kind of a simple solution. Then Play when will finds the references to the methods they will be reported in the original locations. That build should not be published, but only uploaded to run the Play analysis on.
to...@gmail.com <to...@gmail.com> #13
As explained by mail, they only run the analysis (Or at least show the warning) when you actually try to publish.
That's why for that to work it would be nice that they show the alert for all tracks upload. From the my tests they actually already do run it, but it's only expose when we press publish.
No one should try to press publish on such build and forget to remove it after and break prod.
sg...@google.com <sg...@google.com> #14
Good point - that won't might not work. However, if you have the issue in the optimized build then the other build should also have it so publishing it should also fail. Otherwise can you maybe have a beta channel to publish to, which has only yourself enrolled? Or can you publish for actual release at a later time and then revoke it again? This is not a long term solution, but a simple way to quickly locate the issue with the given tools.
to...@gmail.com <to...@gmail.com> #15
In my case the beta is public with many many users, this is a full Compose app, without Optimize, performance is just not acceptable for prod :( Not to mention piracy with no obfuscation.
And the warning is not shown when I push to the private tracks.
And yes in theory, the build would be rejected too, but that's an insane risk to take (Specially when you can actually sometimes press publish before they finish the first analysis pass and it would be published), it's easier to use apktool and smali stuff to try to find the calls. Maybe you can write a very small how to on how you did it to help others? I had no idea how to efficiently find the calls.
Description
The last builds of my app triggers an error check from Play Store :
I'm well aware of that issue and I'm certain this is not caused by my code.
The mapping file for that place shows :
It seems this is something generated by R8, specially since Media3 is Java only. (The version used in that build is 1.6.0 RC1 of Media3 :https://github.com/androidx/media/blob/release-1.6.0-rc01/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/LoudnessCodecController.java )