Skip to content

F-Droid reproducible build failed #122

Closed

Description

@linsui

https://gitlab.com/fdroid/fdroiddata/-/jobs/9383066809 The apk was built from fe4b0d4adc72c6e49cd5e5c0191395b17d4e6f86. Could you please rebuild it from the tag? See https://f-droid.org/docs/Reproducible_Builds/#vcs-info. Thanks!

Activity

  1. IzzySoft commented on Mar 12, 2025

    @IzzySoft

    @linsui How was that with replacing what has already been distributed? Not to do, right? 😉 A new tag would do (aka "maintenance release"). For the current one, just add to your recipe:

    reproducible-apk-tools/inplace-fix.py --internal --zipalign fix-files "$OUT" 'sed s/26163924fb78bf9a87ec6f1c6a2b4f5af36653ba/fe4b0d4adc72c6e49cd5e5c0191395b17d4e6f86/' 'META-INF/version-control-info.textproto'
    
  2. linsui commented on Mar 12, 2025

    @linsui
    Author

    Ah, I didn't know that this is in your repo. I'll wait for a proper fix. :)

  3. IzzySoft commented on Mar 12, 2025

    @IzzySoft

    But while I'm here:

    SigningBlock blobs:
    -------------------
    0x504b4453 (DEPENDENCY_INFO_BLOCK; GOOGLE)
    

    @DeweyReed please add to your build.gradle:

    android {
        dependenciesInfo {
            // Disables dependency metadata when building APKs.
            includeInApk = false
            // Disables dependency metadata when building Android App Bundles.
            includeInBundle = false
        }
    }

    For some background: that BLOB is supposed to be just a binary representation of your app's dependency tree. But as it's encrypted with a public key belonging to Google, only Google can read it – and nobody else can even verify what it really contains. More details can be found e.g. here: Ramping up security: additional APK checks are in place with the IzzyOnDroid repo.

  4. IzzySoft commented on Mar 12, 2025

    @IzzySoft

    Ah, I didn't know that this is in your repo.

    Just returning today, so you couldn't know. Was just added to staging (so goes live with the next sync). I just ran into the very same issue when establishing RB at IoD, which is how I found yours here 😉

    As pointed out, that one-liner would fix it for you as well (and your recipe already has repro-apk as srclib, for the newline fixes). The sed would only affect this release, as the next one will have a different hash – but yeah, I get why you prefer to wait, ackack 😜

  5. DeweyReed commented on Mar 13, 2025

    @DeweyReed
    Member

    Thank you for telling me! I'll fix the problem and create a new release.

    The commit fe4b0d4adc72c6e49cd5e5c0191395b17d4e6f86 doesn't even exist in this repo. Quite weird.🤔

  6. IzzySoft commented on Mar 13, 2025

    @IzzySoft

    The commit fe4b0d4adc72c6e49cd5e5c0191395b17d4e6f86 doesn't even exist in this repo. Quite weird.🤔

    I guess something like "code => commit => build => squash => tag"? Did you build from a branch that was later merged before you tagged the commit? Or built from a local branch that was never pushed? That's usually how this happens.

  7. DeweyReed commented on Mar 13, 2025

    @DeweyReed
    Member

    @IzzySoft Although I can't remember what happened, you're probably right. Anyway, this issue teaches me how to build appropriately.😄

  8. IzzySoft commented on Mar 14, 2025

    @IzzySoft

    If you want some more "interesting details", be welcome to take a look at our hints on reproducible builds 😉

  9. DeweyReed commented on Mar 14, 2025

    @DeweyReed
    Member

    @IzzySoft I'm glad to know how complicated RB is. I'll find some time in the future to build the APK with CI to solve these kinds of issues for good.

    I've created a new release that fixes the issues above.

  10. licaon-kter commented on Mar 14, 2025

    @licaon-kter

    thanks, confirmed

  11. linsui commented on Mar 14, 2025

    @linsui
    Author

    Thanks!

  12. IzzySoft commented on Mar 14, 2025

    @IzzySoft

    Confirming the BLOB being gone. Our scanners here at IzzyOnDroid just complained about:

    ! repo/io.github.deweyreed.timer.other_7060100.apk declares sensitive permission(s):
      android.permission.READ_EXTERNAL_STORAGE android.permission.READ_MEDIA_AUDIO
      android.permission.READ_PHONE_STATE android.permission.SYSTEM_ALERT_WINDOW
    

    With minimum supported Android version of 6 I'm not sure why you need the legacy READ/WRITE storage permissions (you're using Storage Access Framework, don't you?). READ_MEDIA_AUDIO is clear (to pick music for reminders), so I've added that to the green list already. Leaves READ_PHONE_STATE and SYSTEM_ALERT_WINDOW, could you please clarify them, @DeweyReed?

    Image

    Oh: And RB confirmed on our end, too. Btw, be welcome to add the IoD badge back to your Readme (you can pick one here) 😉

  13. DeweyReed commented on Mar 15, 2025

    @DeweyReed
    Member

    @IzzySoft I'm glad that the problem is fixed!

    SAF doesn't support music picking, so READ_EXTERNAL_STORAGE is the backward-compatible permission for READ_MEDIA_AUDIO. The app uses READ_PHONE_STATE to pause timers during phone calls since recent Android releases and SYSTEM_ALERT_WINDOW to show floating timer windows.

    There's some usage for permissions in Manifest.xml.

  14. IzzySoft commented on Mar 15, 2025

    @IzzySoft

    I'm glad that the problem is fixed!

    So am I! Thanks again!

    SAF doesn't support music picking

    Isn't that what READ_MEDIA_AUDIO is for? But well, maybe not if music files are "somewhere else" on storage. And yes, READ_EXTERNAL_STORAGE is the "legacy" one. Remains what WRITE_EXTERNAL_STORAGE is for 😉

    The app uses READ_PHONE_STATE to pause timers during phone calls

    Which to me still sounds like using atomics to catch a mouse. That permission is much too evasive for a task like that (looking at you, Google: 10 years and still this is the way you suggest?). In the past, a different approach to that was to listen to the onAudioFocusChanged broadcast (which the ringer on an incoming call would trigger). But OK, added that to the green list then. Scanner will notify me when it's no longer needed.

    to show floating timer windows.

    Ah, guessed something something floating but wasn't sure if and what. Added as well then, thanks! All "chocolate bars" gone then (the warning color is "chocolate").

    There's some usage for permissions in Manifest.xml.

    I love that "not needed from M to S" stuff. The back-and-forth with needed and not-needed. Especially tricky concerning storage between L and S… Permissions on Android often seems to be a mine field… Which is one of the reasons we try to make their use transparent. Thanks again for helping with that!

  15. DeweyReed commented on Mar 15, 2025

    @DeweyReed
    Member

    @IzzySoft Thanks for your patience!

    Android added READ_MEDIA_AUDIO in API 33 to replace READ_EXTERNAL_STORAGE, so older devices must use the old permission. READ_EXTERNAL_STORAGE also has specified android:maxSdkVersion="32".

    READ_PHONE_STATE is a legacy permission. When I was a junior developer, I copied the feature from AOSP without too much careful consideration. I'd be happy to remove it now, but deleting existing features can frustrate users who rely on them.

    Permissions on Android are confusing, as always. 😄

  16. IzzySoft commented on Mar 16, 2025

    @IzzySoft

    IIRC, there were alternative implementations for that using the onAudioFocusChanged broadcast, so using one of those would keep the feature while getting rid of the permission. Not saying you have to do that, just mentioning the path available if you want to. I also understand that's nothing one does between breakfast and a coffee, so I wouldn't expect you to "jump right into it" and "have it ready tomorrow" 😉 Might be something for an issue with "help needed" label 🤔

    Permissions on Android are confusing, as always. 😄

    Oh, where shall I sign? 🙈 Can't agree more – but could provide a list of things which are not only confusing to "end users", but also take some time to be grasped by "standing devs". In my area, you see a lot…

  17. DeweyReed commented on Mar 17, 2025

    @DeweyReed
    Member

    @IzzySoft I did some little experiments and realized that onAudioFocusChanged doesn't provide the source of the change. If it was a phone call, the app could pause timers; If the user played music, the app might as well ignore the change. Any API that checks if there is any phone call requires permission.

    Fortunately, the app only declares READ_PHONE_STATE to make things work and doesn't require the runtime permission request.

  18. IzzySoft commented on Mar 17, 2025

    @IzzySoft

    Thanks for checking, @DeweyReed – at IoD, we already have put the permission to the app's "green list" (including the explanation). Still sad that just for detecting that, one needs a permission with such broad access to PII (you wouldn't need to know who's calling, what provider the phone is booked into, etc – but still, there we are). This example claims to need no permissions; but being 12 years old I don't know if it still works (or if it does what you need). But here is opne from 2022 using the AudioFocus approach I've mentioned. It also checks which channel was causing it – maybe that's doing the trick? If so, I'd add it to one of my snippets to easily find it again for future cases 😉

  19. DeweyReed commented on Mar 18, 2025

    @DeweyReed
    Member

    @IzzySoft Thank you! I'll try them and try to figure out a better solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions