Skip to content

Fix reported bugs from the Abloq-MDM tracker on PreBuild 0.5.1 - #5

Open
sesese1234 wants to merge 4 commits into
Pre-Releasefrom
claude/secureguard-mdm-bug-fixes-pecbfu
Open

Fix reported bugs from the Abloq-MDM tracker on PreBuild 0.5.1#5
sesese1234 wants to merge 4 commits into
Pre-Releasefrom
claude/secureguard-mdm-bug-fixes-pecbfu

Conversation

@sesese1234

@sesese1234 sesese1234 commented Aug 9, 2026

Copy link
Copy Markdown
Owner

Fixes the bugs reported in the Abloq-MDM issue tracker, applied on top of the pre-release line (Pre-Release, branched from PreBuild 0.5.1). Bug fixes only — no new features, and no version bumps (version.txt, versiontest.txt and changes.txt are untouched).

Issues addressed

Issue Problem Root cause
#30, #25.2 Can no longer select many apps at once; list jumps back to the top after every app Every checkbox opened a hide/lock dialog that saved immediately; the save reloaded the list, cleared the search box and swapped in a spinner
#17 Store crashes on open after adding a package that is already installed The package appeared both as installed and as a custom entry, and LazyColumn's key = { it.packageName } throws on a duplicate key
#21 Custom packages do not install; updates spin forever Installed custom packages were filtered out of the custom tab; single-APK installs never requested unattended install; the download flow never closed
#25.3 Kiosk action-button toggles stuck and drawn on top of each other The settings column does not scroll, so Arrangement.spacedBy had to distribute negative free space
#25.4 Flashlight turns on but never off State was persisted with Settings.Global.putInt, which needs WRITE_SECURE_SETTINGS and always threw, so every tap re-ran setTorchMode(id, true)
#25.5 Kiosk collapses and leaves the device unblocked If the lock-task allowlist was missing, startLockTask() was skipped with no fallback
#28 App cannot be uninstalled on Android 13; blocks just stop Device ownership was cleared before the user restrictions, so DISALLOW_UNINSTALL_APPS / DISALLOW_APPS_CONTROL survived and could no longer be removed
#29 Internal VPN drops after a reboot Nothing restored it on boot — START_STICKY does not cover a power cycle — and the boot receiver ships disabled
#1 Settings button hidden behind the navigation buttons targetSdk 36 forces edge-to-edge, and a raw Button in a Scaffold bottomBar gets no inset padding

Changes

App blocking — checkboxes stage changes instead of saving per app, so apps can be marked in bulk and committed with Save; refresh no longer clears the search box or the scroll position; deselection now actually unblocks (the saved set used to be unioned with the previous one, so removing an app was impossible and blocked apps were never unhidden); setPackagesSuspended is guarded by an API check since minSdk is 22.

App store — installed custom packages are no longer dropped from the custom tab and keep their isCustomPackage flag; the app list is de-duplicated by package name; single-APK sessions request USER_ACTION_NOT_REQUIRED, without which Android 12+ answered the commit with STATUS_PENDING_USER_ACTION and silently dropped the install; InstallReceiver now handles that status and reads EXTRA_PACKAGE_NAME instead of a key that was never set; the download flow closes when finished, so a package is released from the in-flight guard and can be retried; PendingIntents keep FLAG_UPDATE_CURRENT on API 31+ and are keyed by session id rather than a fixed request code of 0.

Kiosk — the management screen scrolls; torch state is tracked in-process from the framework's torch callback and the camera that actually reports a flash unit is selected; a missing lock-task allowlist is re-applied and retried rather than leaving the device open, and unreadable kiosk settings fail closed.

Removal — all user restrictions and the package's own uninstall block are cleared before device ownership is released, and each policy teardown is isolated so one failure no longer aborts the whole removal.

Boot — a new FirewallVpnBootTask restores the firewall VPN when it was active before the reboot, and the boot receiver is re-asserted on start (it ships disabled and was previously only enabled during first-time password setup).

CI — adds .github/workflows/build-apk.yml, which assembles the debug and unsigned release APKs on every push and pull request and uploads both as artifacts. It installs the NDK explicitly (the project runs ndk-build via app/src/main/jni/Android.mk and does not pin ndkVersion) and marks gradlew executable, since it is committed without the executable bit.

Not included

  • #14 (APKS/XAPK in manual updates) is labelled bug but reads as a feature request — the file picker only accepts application/vnd.android.package-archive, so those files cannot be chosen. Left out per "no new enhancements". Note the store install path already handles .xapk / .apks / .apkm.
  • #25.1 (password shows no feedback while typing) is already fixed on this branch — every password field uses PasswordVisualTransformation.
  • #25.6, #25.7, #31 and the remaining enhancement-labelled issues are feature requests.

Testing

The new workflow compiles the project and produces installable APKs, so the build is verified in CI rather than by hand. Behaviour still needs a pass on a device across the affected screens — app selection, the store, kiosk, removal, and a reboot with the firewall on.

🤖 Generated with Claude Code

https://claude.ai/code/session_01WKeZ6SjfkeLU7qf1YbBVLY

claude added 2 commits August 9, 2026 15:50
Bug fixes only; no version bumps and no new features.

App blocking (Abloq-MDM #30, #25.2)
- Restore bulk selection: ticking a checkbox stages the change instead of
  opening a per-app hide/lock dialog and immediately saving, so many apps
  can be marked in one pass and committed with Save.
- Stop the list jumping back to the top after each app: refreshing no
  longer clears the search box or swaps the list for a spinner, and the
  scroll state is hoisted so it survives the rebuild.
- Unchecking an app now actually removes it. The saved set was unioned
  with the previous one, so deselection was impossible and blocked apps
  were never unhidden.
- Guard setPackagesSuspended behind an API check (minSdk is 22).

App store (#17, #21)
- Fix the crash on opening the store after adding a package that is
  already installed: the package appeared both as installed and as a
  custom entry, and the duplicate LazyColumn key threw.
- Custom packages that are installed are no longer filtered out, and
  resolved entries keep isCustomPackage, so they reach the custom tab.
- Single-APK installs now request unattended install; without it
  Android 12+ answered the commit with STATUS_PENDING_USER_ACTION and
  the install was silently dropped.
- Handle STATUS_PENDING_USER_ACTION in InstallReceiver and read the
  package name from EXTRA_PACKAGE_NAME instead of a key that was never set.
- Close the download flow when it finishes. It stayed open forever, so
  the package was never released from the in-flight guard and further
  update attempts were ignored.
- Keep FLAG_UPDATE_CURRENT on API 31+ and key the PendingIntent by
  session id rather than a fixed request code of 0.

Kiosk (#25.3, #25.4, #25.5)
- Make the kiosk management screen scrollable; on shorter screens the
  action-button toggles were laid out on top of each other and unreachable.
- Fix the flashlight only ever switching on: the state was persisted via
  Settings.Global, which requires WRITE_SECURE_SETTINGS and always threw.
  Track the torch state in-process from the framework torch callback and
  pick the camera that actually reports a flash unit.
- Re-apply the lock task allowlist and retry when it is missing, instead
  of leaving the device sitting on the kiosk screen unlocked, and fail
  closed when kiosk settings cannot be read.

Removal (#28)
- Clear all user restrictions and the package's own uninstall block
  before clearing device ownership. DISALLOW_UNINSTALL_APPS and
  DISALLOW_APPS_CONTROL survived removal and could no longer be cleared
  once ownership was gone, which left the app installed and un-removable
  with its protections already off.
- Isolate each policy teardown so one failure no longer aborts removal.

Internal VPN after reboot (#29)
- Add a boot task that restores the firewall VPN when it was active
  before the reboot; START_STICKY does not cover a power cycle.
- Re-assert the boot receiver on start, as it ships disabled and was only
  enabled during first-time password setup.

Navigation bar overlap (#1)
- Inset the dashboard settings button and the kiosk bottom bar for the
  navigation bar; targetSdk 36 forces edge-to-edge, so they were drawn
  underneath the navigation buttons.

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01WKeZ6SjfkeLU7qf1YbBVLY
Builds the debug and unsigned release APKs on pushes and pull requests and
uploads both as artifacts, so changes are compile-verified in CI.

Installs the NDK explicitly (the project runs ndk-build via
app/src/main/jni/Android.mk and does not pin ndkVersion) and marks gradlew
executable, as it is committed without the executable bit.

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01WKeZ6SjfkeLU7qf1YbBVLY
@sesese1234
sesese1234 changed the base branch from PreBuild to Pre-Release August 9, 2026 16:59
claude added 2 commits August 9, 2026 17:01
gradle/gradle-daemon-jvm.properties pinned toolchainVendor=jetbrains, which
was picked up from the IDE's bundled runtime. Gradle has no toolchain
download URL for that vendor, so the build fails outright on any machine
without a JetBrains JDK already installed:

  Unable to download toolchain matching the requirements
  ({languageVersion=21, vendor=JetBrains, ...}) from 'null'

Keep the Java 21 requirement and drop the vendor pin; the JetBrains Runtime
still satisfies it.

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01WKeZ6SjfkeLU7qf1YbBVLY
The default locale defined the string as update_channel_PreRelease while the
code and values-en use update_channel_prebuild. A resource missing from the
default locale is stripped by AAPT:

  warn: removing resource string/update_channel_prebuild without required
        default value
  e: SettingsScreen.kt:745:52 Unresolved reference 'update_channel_prebuild'

so the branch did not compile. Rename the default-locale key to match the
name the code references; nothing referenced the old key.

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01WKeZ6SjfkeLU7qf1YbBVLY
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

Successfully merging this pull request may close these issues.

2 participants