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.
This commit is contained in:
Thomas Kuehne
2026-05-03 16:11:49 +00:00
parent c40d3e63a8
commit c51a0535c9
3 changed files with 60 additions and 9 deletions
@@ -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 <https://www.gnu.org/licenses/>. */
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<Bundle?>(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 <T : ViewModel> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(FileInstallerViewModel::class.java)) {
return FileInstallerViewModel(application) as T
return FileInstallerViewModel(application, fwOptions) as T
}
throw IllegalArgumentException("Unknown ViewModel class")
}
@@ -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 <https://www.gnu.org/licenses/>. */
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<InstallDeviceUiState>()
val uiState: LiveData<InstallDeviceUiState> = _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 {}",
@@ -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 <https://www.gnu.org/licenses/>. */
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