fix(kiosk): STATUS_FAILURE=1 (wrong package) + issue version-guard bypass

Bug 1 — Root cause of PackageInstaller STATUS_FAILURE=1:
  The dest file is always named 'evershelf-update.apk'. installApk()
  was trying to detect 'gateway' in the filename — always false.
  So setAppPackageName() was always passed 'it.dadaloop.evershelf.kiosk'
  even when installing the gateway APK (package scalegate).
  PackageInstaller rejects the mismatch with STATUS_FAILURE=1.

  Fix: save apkUrl into pendingApkDownloadUrl at the TOP of
  triggerApkDownload() (not only in the permission branch), then derive
  targetPkg from the URL (which does contain 'gateway'/'scale') instead
  of the filename.

Bug 2 — Install errors not reaching GitHub Issues:
  PHP reportError() has a version guard: if the client version is not
  the latest release, it silently skips GitHub issue creation.
  A device that is FAILING TO INSTALL an update is by definition on an
  old version, so every install error was silently dropped.

  Fix: bypass the version guard for types install_download_failed,
  install_failure, install_packager_exception.
This commit is contained in:
dadaloop82
2026-05-03 19:29:04 +00:00
parent 645162f063
commit 15e1dfbd69
2 changed files with 16 additions and 5 deletions
+7 -1
View File
@@ -5643,7 +5643,13 @@ function reportError(): void {
// ── Version guard: skip GitHub issue if client is not on latest release ─
// Avoids noise from bugs already fixed in a newer version.
if (!_isLatestVersion($version)) {
// Exception: install/update errors are ALWAYS reported regardless of version,
// because a device that is failing to install the update is by definition on
// an old version — suppressing the issue is the opposite of useful.
$installErrorTypes = ['install_download_failed', 'install_failure', 'install_packager_exception'];
$bypassVersionGuard = in_array($type, $installErrorTypes, true)
|| ($context['version_guard_bypass'] ?? false);
if (!$bypassVersionGuard && !_isLatestVersion($version)) {
echo json_encode(['ok' => true, 'skipped' => 'outdated_version']);
return;
}
@@ -993,11 +993,13 @@ class KioskActivity : AppCompatActivity() {
*/
private fun triggerApkDownload(apkUrl: String) {
if (apkUrl.isEmpty()) return
// Always keep this up-to-date so installApk() can derive the target package from the URL.
pendingApkDownloadUrl = apkUrl
try {
// On Android 8+ check the "install unknown apps" source permission
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O &&
!packageManager.canRequestPackageInstalls()) {
pendingApkDownloadUrl = apkUrl
// pendingApkDownloadUrl already set above
setInstallUI(
"\uD83D\uDD12",
getString(R.string.install_perm_detail),
@@ -1113,10 +1115,13 @@ class KioskActivity : AppCompatActivity() {
runOnUiThread { activeInstallBtn?.text = getString(R.string.install_btn_retry) }
return
}
// Derive the package name we are installing from the filename
// Derive the target package from the download URL (not the filename, which is always
// 'evershelf-update.apk'). The URL contains 'gateway' or 'scale' when installing the
// scale gateway; anything else is a kiosk self-update.
val targetPkg = when {
file.name.contains("gateway") || file.name.contains("scale") -> GATEWAY_PACKAGE
else -> packageName // kiosk self-update
pendingApkDownloadUrl.contains("gateway", ignoreCase = true) ||
pendingApkDownloadUrl.contains("scale", ignoreCase = true) -> GATEWAY_PACKAGE
else -> packageName
}
installWithPackageInstaller(file, targetPkg)
}