onInstallApp: Add support for custom options

This commit is contained in:
José Rebelo
2025-07-18 09:03:49 +01:00
parent c3af3b3ce1
commit ce334fad33
25 changed files with 82 additions and 38 deletions
@@ -212,7 +212,7 @@ public class FwAppInstallerActivity extends AbstractGBActivity implements Instal
public void onClick(View v) {
setInstallEnabled(false);
installHandler.onStartInstall(device);
GBApplication.deviceService(device).onInstallApp(uri);
GBApplication.deviceService(device).onInstallApp(uri, Bundle.EMPTY);
}
});
@@ -604,7 +604,7 @@ public abstract class AbstractAppManagerFragment extends Fragment {
return true;
} else if (itemId == R.id.appmanager_app_reinstall) {
final File cachePath = new File(appCacheDir, selectedApp.getUUID() + mCoordinator.getAppFileExtension());
GBApplication.deviceService(mGBDevice).onInstallApp(Uri.fromFile(cachePath));
GBApplication.deviceService(mGBDevice).onInstallApp(Uri.fromFile(cachePath), Bundle.EMPTY);
return true;
} else if (itemId == R.id.appmanager_app_share) {
final File origFilePath = new File(appCacheDir, selectedApp.getUUID() + mCoordinator.getAppFileExtension());
@@ -627,13 +627,13 @@ public abstract class AbstractAppManagerFragment extends Fragment {
}
return true;
} else if (itemId == R.id.appmanager_health_activate) {
GBApplication.deviceService(mGBDevice).onInstallApp(Uri.parse("fake://health"));
GBApplication.deviceService(mGBDevice).onInstallApp(Uri.parse("fake://health"), Bundle.EMPTY);
return true;
} else if (itemId == R.id.appmanager_hrm_activate) {
GBApplication.deviceService(mGBDevice).onInstallApp(Uri.parse("fake://hrm"));
GBApplication.deviceService(mGBDevice).onInstallApp(Uri.parse("fake://hrm"), Bundle.EMPTY);
return true;
} else if (itemId == R.id.appmanager_weather_activate) {
GBApplication.deviceService(mGBDevice).onInstallApp(Uri.parse("fake://weather"));
GBApplication.deviceService(mGBDevice).onInstallApp(Uri.parse("fake://weather"), Bundle.EMPTY);
return true;
} else if (itemId == R.id.appmanager_health_deactivate || itemId == R.id.appmanager_hrm_deactivate || itemId == R.id.appmanager_weather_deactivate) {
GBApplication.deviceService(mGBDevice).onAppDelete(selectedApp.getUUID());
@@ -22,6 +22,8 @@ import android.location.Location;
import android.net.Uri;
import android.os.Bundle;
import androidx.annotation.NonNull;
import java.util.ArrayList;
import java.util.UUID;
@@ -83,7 +85,7 @@ public interface EventHandler {
void onEnableRealtimeSteps(boolean enable);
void onInstallApp(Uri uri);
void onInstallApp(Uri uri, @NonNull Bundle options);
void onAppInfoReq();
@@ -78,7 +78,6 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceApp;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport;
import nodomain.freeyourgadget.gadgetbridge.util.AndroidUtils;
import nodomain.freeyourgadget.gadgetbridge.util.BitmapUtil;
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
public class HybridHRWatchfaceDesignerActivity extends AbstractGBActivity implements View.OnClickListener, View.OnLongClickListener, View.OnDragListener {
@@ -637,7 +636,7 @@ public class HybridHRWatchfaceDesignerActivity extends AbstractGBActivity implem
final Uri tempAppFileUri = Uri.fromFile(tempFile);
if (preview) {
findViewById(R.id.watchface_upload_progress_bar).setVisibility(View.VISIBLE);
GBApplication.deviceService(mGBDevice).onInstallApp(tempAppFileUri);
GBApplication.deviceService(mGBDevice).onInstallApp(tempAppFileUri, Bundle.EMPTY);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
@@ -658,14 +657,14 @@ public class HybridHRWatchfaceDesignerActivity extends AbstractGBActivity implem
@Override
public void onClick(DialogInterface dialog, int which) {
findViewById(R.id.watchface_upload_progress_bar).setVisibility(View.VISIBLE);
GBApplication.deviceService(mGBDevice).onInstallApp(tempAppFileUri);
GBApplication.deviceService(mGBDevice).onInstallApp(tempAppFileUri, Bundle.EMPTY);
FossilHRInstallHandler.saveAppInCache(fossilFile, selectedBackgroundImage, wfFactory.getPreviewImage(mContext), mCoordinator, HybridHRWatchfaceDesignerActivity.this);
}
})
.show();
} else {
findViewById(R.id.watchface_upload_progress_bar).setVisibility(View.VISIBLE);
GBApplication.deviceService(mGBDevice).onInstallApp(tempAppFileUri);
GBApplication.deviceService(mGBDevice).onInstallApp(tempAppFileUri, Bundle.EMPTY);
FossilHRInstallHandler.saveAppInCache(fossilFile, selectedBackgroundImage, wfFactory.getPreviewImage(mContext), mCoordinator, HybridHRWatchfaceDesignerActivity.this);
}
}
@@ -54,6 +54,8 @@ import nodomain.freeyourgadget.gadgetbridge.util.RtlUtils;
import static nodomain.freeyourgadget.gadgetbridge.util.JavaExtensions.coalesce;
import androidx.annotation.NonNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -318,9 +320,10 @@ public class GBDeviceService implements DeviceService {
}
@Override
public void onInstallApp(Uri uri) {
public void onInstallApp(Uri uri, @NonNull final Bundle options) {
Intent intent = createIntent().setAction(ACTION_INSTALL)
.putExtra(EXTRA_URI, uri);
.putExtra(EXTRA_URI, uri)
.putExtra(EXTRA_OPTIONS, options);
invokeService(intent);
}
@@ -134,6 +134,7 @@ public interface DeviceService extends EventHandler {
String EXTRA_APP_CONFIG = "app_config";
String EXTRA_APP_CONFIG_ID = "app_config_id";
String EXTRA_URI = "uri";
String EXTRA_OPTIONS = "options";
String EXTRA_CONFIG = "config";
String EXTRA_ALARMS = "alarms";
String EXTRA_REMINDERS = "reminders";
@@ -25,6 +25,8 @@ import android.location.Location;
import android.net.Uri;
import android.os.Bundle;
import androidx.annotation.NonNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -357,10 +359,12 @@ public abstract class AbstractDeviceSupport implements DeviceSupport {
/**
* If apps can be installed on the device, this method can be
* overridden and implemented by the device support class.
* @param uri reference to a watch app file
*
* @param uri reference to a watch app file
* @param options a bundle of custom options
*/
@Override
public void onInstallApp(Uri uri) {
public void onInstallApp(Uri uri, @NonNull final Bundle options) {
}
@@ -1097,9 +1097,10 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
}
case ACTION_INSTALL:
Uri uri = intentCopy.getParcelableExtra(EXTRA_URI);
Bundle options = intentCopy.getBundleExtra(EXTRA_OPTIONS);
if (uri != null) {
LOG.info("will try to install app/fw");
deviceSupport.onInstallApp(uri);
deviceSupport.onInstallApp(uri, options);
}
break;
case ACTION_SET_ALARMS:
@@ -24,6 +24,8 @@ import android.location.Location;
import android.net.Uri;
import android.os.Bundle;
import androidx.annotation.NonNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -247,11 +249,11 @@ public class ServiceDeviceSupport implements DeviceSupport {
}
@Override
public void onInstallApp(Uri uri) {
public void onInstallApp(Uri uri, @NonNull final Bundle options) {
if (checkBusy("install app")) {
return;
}
delegate.onInstallApp(uri);
delegate.onInstallApp(uri, options);
}
@Override
@@ -27,9 +27,12 @@ import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.widget.Toast;
import androidx.annotation.NonNull;
import com.android.nQuant.PnnLABQuantizer;
import org.slf4j.Logger;
@@ -49,7 +52,6 @@ import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSett
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLESingleDeviceSupport;
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceStateAction;
import nodomain.freeyourgadget.gadgetbridge.util.CheckSums;
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
@@ -352,7 +354,7 @@ public class ATCBLEOEPLDeviceSupport extends AbstractBTLESingleDeviceSupport {
}
@Override
public void onInstallApp(Uri uri) {
public void onInstallApp(Uri uri, @NonNull final Bundle options) {
try {
boolean is_firmware = false;
UriHelper uriHelper = UriHelper.get(uri, getContext());
@@ -25,8 +25,10 @@ import android.location.Location;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import net.e175.klaus.solarpositioning.DeltaT;
@@ -751,7 +753,7 @@ public class CmfWatchProSupport extends AbstractBTLESingleDeviceSupport implemen
}
@Override
public void onInstallApp(final Uri uri) {
public void onInstallApp(final Uri uri, @NonNull final Bundle options) {
dataUploader.onInstallApp(uri);
}
@@ -18,6 +18,9 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.divoom;
import android.net.Uri;
import android.os.Bundle;
import androidx.annotation.NonNull;
import nodomain.freeyourgadget.gadgetbridge.service.serial.AbstractSerialDeviceSupport;
import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceIoThread;
@@ -45,7 +48,7 @@ public class PixooSupport extends AbstractSerialDeviceSupport {
}
@Override
public void onInstallApp(Uri uri) {
public void onInstallApp(Uri uri, @NonNull final Bundle options) {
getDeviceIOThread().write(((PixooProtocol) getDeviceProtocol()).encodeShowFrame(uri));
}
@@ -9,8 +9,10 @@ import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.location.Location;
import android.net.Uri;
import android.os.Bundle;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.documentfile.provider.DocumentFile;
@@ -964,7 +966,7 @@ public class GarminSupport extends AbstractBTLESingleDeviceSupport implements IC
}
@Override
public void onInstallApp(Uri uri) {
public void onInstallApp(Uri uri, @NonNull final Bundle options) {
final GarminFitFileInstallHandler fitFileInstallHandler = new GarminFitFileInstallHandler(uri, getContext());
if (fitFileInstallHandler.isValid()) {
communicator.sendMessage(
@@ -28,10 +28,12 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.location.Location;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import net.e175.klaus.solarpositioning.DeltaT;
@@ -1558,7 +1560,7 @@ public abstract class HuamiSupport extends AbstractBTLESingleDeviceSupport
}
@Override
public void onInstallApp(Uri uri) {
public void onInstallApp(Uri uri, @NonNull final Bundle options) {
try {
createUpdateFirmwareOperation(uri).perform();
} catch (IOException ex) {
@@ -26,6 +26,8 @@ import android.os.Looper;
import android.util.SparseArray;
import android.widget.Toast;
import androidx.annotation.NonNull;
import org.apache.commons.lang3.RandomUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -566,8 +568,8 @@ public class ZeppOsBtbrSupport extends AbstractBTBRDeviceSupport implements Zepp
}
@Override
public void onInstallApp(final Uri uri) {
zeppOsSupport.onInstallApp(uri);
public void onInstallApp(final Uri uri, @NonNull final Bundle options) {
zeppOsSupport.onInstallApp(uri, options);
}
@Override
@@ -24,6 +24,8 @@ import android.location.Location;
import android.net.Uri;
import android.os.Bundle;
import androidx.annotation.NonNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -312,8 +314,8 @@ public class ZeppOsBtleSupport extends AbstractBTLESingleDeviceSupport implement
}
@Override
public void onInstallApp(final Uri uri) {
zeppOsSupport.onInstallApp(uri);
public void onInstallApp(final Uri uri, @NonNull final Bundle options) {
zeppOsSupport.onInstallApp(uri, options);
}
@Override
@@ -28,6 +28,7 @@ import android.net.Uri;
import android.os.Bundle;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.slf4j.Logger;
@@ -464,7 +465,7 @@ public class ZeppOsSupport extends AbstractDeviceSupport
}
@Override
public void onInstallApp(final Uri uri) {
public void onInstallApp(final Uri uri, @NonNull final Bundle options) {
final ZeppOsAgpsInstallHandler agpsHandler = new ZeppOsAgpsInstallHandler(uri, getContext());
if (agpsHandler.isValid()) {
try {
@@ -20,6 +20,9 @@ import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.location.Location;
import android.net.Uri;
import android.os.Bundle;
import androidx.annotation.NonNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -155,7 +158,7 @@ public class HuaweiBRSupport extends AbstractBTBRDeviceSupport {
}
@Override
public void onInstallApp(Uri uri) {
public void onInstallApp(Uri uri, @NonNull final Bundle options) {
supportProvider.onInstallApp(uri);
}
@@ -22,8 +22,11 @@ import android.bluetooth.BluetoothGattCharacteristic;
import android.content.Context;
import android.location.Location;
import android.net.Uri;
import android.os.Bundle;
import androidx.annotation.NonNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -160,7 +163,7 @@ public class HuaweiLESupport extends AbstractBTLESingleDeviceSupport {
}
@Override
public void onInstallApp(Uri uri) {
public void onInstallApp(Uri uri, @NonNull final Bundle options) {
supportProvider.onInstallApp(uri);
}
@@ -23,8 +23,10 @@ import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
@@ -78,7 +80,6 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.GattCharacteristic;
import nodomain.freeyourgadget.gadgetbridge.service.btle.GattService;
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.ConditionalWriteAction;
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceStateAction;
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.WriteAction;
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.AlertCategory;
import nodomain.freeyourgadget.gadgetbridge.service.devices.common.SimpleNotification;
@@ -780,7 +781,7 @@ public class MiBandSupport extends AbstractBTLESingleDeviceSupport {
}
@Override
public void onInstallApp(Uri uri) {
public void onInstallApp(Uri uri, @NonNull final Bundle options) {
try {
new UpdateFirmwareOperation(uri, this).perform();
} catch (IOException ex) {
@@ -20,8 +20,10 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.pebble;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.Bundle;
import android.util.Pair;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import org.json.JSONArray;
@@ -107,7 +109,7 @@ public class PebbleSupport extends AbstractSerialDeviceSupport {
}
@Override
public void onInstallApp(Uri uri) {
public void onInstallApp(Uri uri, @NonNull final Bundle options) {
PebbleProtocol pebbleProtocol = (PebbleProtocol) getDeviceProtocol();
PebbleIoThread pebbleIoThread = getDeviceIOThread();
// Catch fake URLs first
@@ -29,8 +29,10 @@ import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.apache.commons.lang3.StringUtils;
@@ -440,7 +442,7 @@ public class PineTimeJFSupport extends AbstractBTLESingleDeviceSupport implement
}
@Override
public void onInstallApp(Uri uri) {
public void onInstallApp(Uri uri, @NonNull final Bundle options) {
try {
handler = new PineTimeInstallHandler(uri, getContext());
@@ -28,6 +28,7 @@ import android.net.Uri;
import android.os.Bundle;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
@@ -716,7 +717,7 @@ public class QHybridSupport extends QHybridBaseSupport {
}
@Override
public void onInstallApp(Uri uri) {
public void onInstallApp(Uri uri, @NonNull final Bundle options) {
watchAdapter.onInstallApp(uri);
}
@@ -13,6 +13,7 @@ import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.text.Layout;
@@ -20,6 +21,7 @@ import android.text.StaticLayout;
import android.text.TextPaint;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.slf4j.Logger;
@@ -39,7 +41,6 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLESingleDeviceSupport;
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceStateAction;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
public class GenericThermalPrinterSupport extends AbstractBTLESingleDeviceSupport {
@@ -439,7 +440,7 @@ public class GenericThermalPrinterSupport extends AbstractBTLESingleDeviceSuppor
}
@Override
public void onInstallApp(Uri uri) {
public void onInstallApp(Uri uri, @NonNull final Bundle options) {
//we just abuse the install functionality to start our own activity
}
@@ -21,9 +21,12 @@ import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.location.Location;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.widget.Toast;
import androidx.annotation.NonNull;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -320,7 +323,7 @@ public class XiaomiSupport extends AbstractDeviceSupport {
}
@Override
public void onInstallApp(final Uri uri) {
public void onInstallApp(final Uri uri, @NonNull final Bundle options) {
final XiaomiFWHelper fwHelper = new XiaomiFWHelper(uri, getContext());
if (!fwHelper.isValid()) {