From c51a0535c92cb17aa958cd4467872868f78bc53b Mon Sep 17 00:00:00 2001 From: Thomas Kuehne Date: Sun, 3 May 2026 08:38:42 +0000 Subject: [PATCH] add EXTRA_OPTIONS support to FwAppInstallerActivity and FileInstallerActivity If present, the extra of type Bundle is passed on to as `options` argument to DeviceCoordinator.findInstallHandler and EventHandler.onInstallApp. --- .../install/FileInstallerActivity.kt | 30 +++++++++++++++++-- .../install/FileInstallerViewModel.kt | 20 +++++++++++-- .../install/FwAppInstallerActivity.java | 19 +++++++++--- 3 files changed, 60 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/install/FileInstallerActivity.kt b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/install/FileInstallerActivity.kt index abebf3fad5..0aa1913f3a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/install/FileInstallerActivity.kt +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/install/FileInstallerActivity.kt @@ -1,3 +1,19 @@ +/* Copyright (C) 2025-2026 José Rebelo, Thomas Kuehne + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.activities.install import android.annotation.SuppressLint @@ -17,11 +33,14 @@ import nodomain.freeyourgadget.gadgetbridge.adapter.DeviceInstallAdapter import nodomain.freeyourgadget.gadgetbridge.databinding.ActivityFileInstallerBinding import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice +import nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_OPTIONS import org.slf4j.LoggerFactory class FileInstallerActivity : AppCompatActivity() { private val viewModel: FileInstallerViewModel by viewModels { - FileInstallerViewModelFactory(GBApplication.app()) + FileInstallerViewModelFactory(GBApplication.app(), + intent.getParcelableExtra(EXTRA_OPTIONS) ?: Bundle.EMPTY + ) } private lateinit var binding: ActivityFileInstallerBinding @@ -124,6 +143,10 @@ class FileInstallerActivity : AppCompatActivity() { Intent.FLAG_ACTIVITY_TASK_ON_HOME or Intent.FLAG_GRANT_READ_URI_PERMISSION } + val installAppBundle = getIntent().getParcelableExtra(EXTRA_OPTIONS) + if (installAppBundle != null) { + intent.putExtra(EXTRA_OPTIONS, installAppBundle) + } startActivity(intent) finish() } @@ -136,12 +159,13 @@ class FileInstallerActivity : AppCompatActivity() { // FileInstallerViewModelFactory remains the same class FileInstallerViewModelFactory( - private val application: GBApplication + private val application: GBApplication, + private val fwOptions: Bundle ) : ViewModelProvider.Factory { @Suppress("UNCHECKED_CAST") override fun create(modelClass: Class): T { if (modelClass.isAssignableFrom(FileInstallerViewModel::class.java)) { - return FileInstallerViewModel(application) as T + return FileInstallerViewModel(application, fwOptions) as T } throw IllegalArgumentException("Unknown ViewModel class") } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/install/FileInstallerViewModel.kt b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/install/FileInstallerViewModel.kt index b9fa9c5ca3..8d1acc5ba2 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/install/FileInstallerViewModel.kt +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/install/FileInstallerViewModel.kt @@ -1,3 +1,19 @@ +/* Copyright (C) 2025-2026 José Rebelo, Thomas Kuehne + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.activities.install import android.net.Uri @@ -22,7 +38,7 @@ sealed class InstallDeviceUiState { data class Error(val message: String) : InstallDeviceUiState() } -class FileInstallerViewModel(private val application: GBApplication) : ViewModel() { +class FileInstallerViewModel(private val application: GBApplication, private val fwOptions: Bundle) : ViewModel() { private val _uiState = MutableLiveData() val uiState: LiveData = _uiState @@ -39,7 +55,7 @@ class FileInstallerViewModel(private val application: GBApplication) : ViewModel for (device in getAllDeviceTypesConnectedFirst()) { val coordinator = device.deviceCoordinator try { - val handler = coordinator.findInstallHandler(uri, Bundle.EMPTY, application.applicationContext) + val handler = coordinator.findInstallHandler(uri, fwOptions, application.applicationContext) if (handler != null) { LOG.debug( "Found compatible install handler {} for {}", diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/install/FwAppInstallerActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/install/FwAppInstallerActivity.java index 1195bcef1c..7ae4c45c4f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/install/FwAppInstallerActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/install/FwAppInstallerActivity.java @@ -1,5 +1,6 @@ -/* Copyright (C) 2015-2024 Andreas Shimokawa, Carsten Pfeiffer, Daniel - Dakhno, Daniele Gobbetti, José Rebelo, Lem Dulfo, Petr VanÄ›k, Taavi Eomäe +/* Copyright (C) 2015-2026 Andreas Shimokawa, Carsten Pfeiffer, Daniel + Dakhno, Daniele Gobbetti, José Rebelo, Lem Dulfo, Petr VanÄ›k, Taavi Eomäe, + Thomas Kuehne This file is part of Gadgetbridge. @@ -17,6 +18,8 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.activities.install; +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_OPTIONS; + import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -212,7 +215,11 @@ public class FwAppInstallerActivity extends AbstractGBActivity implements Instal installButton.setOnClickListener(v -> { setInstallEnabled(false); installHandler.onStartInstall(device); - GBApplication.deviceService(device).onInstallApp(uri, Bundle.EMPTY); + Bundle options = getIntent().getParcelableExtra(EXTRA_OPTIONS); + if (options == null) { + options = Bundle.EMPTY; + } + GBApplication.deviceService(device).onInstallApp(uri, options); }); closeButton.setOnClickListener(v -> finish()); @@ -222,7 +229,11 @@ public class FwAppInstallerActivity extends AbstractGBActivity implements Instal uri = getIntent().getParcelableExtra(Intent.EXTRA_STREAM); } - installHandler = device.getDeviceCoordinator().findInstallHandler(uri, Bundle.EMPTY, this); + Bundle options = getIntent().getParcelableExtra(EXTRA_OPTIONS); + if (options == null) { + options = Bundle.EMPTY; + } + installHandler = device.getDeviceCoordinator().findInstallHandler(uri, options, this); if (installHandler == null) { // Should never happen? at this point, we got here by installing to the device