1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-07-03 11:33:19 +02:00

Zepp OS: Add experimental app management

This commit is contained in:
José Rebelo 2023-06-10 23:31:38 +01:00
parent 89b23f77b7
commit 8ff3ce0477
51 changed files with 272 additions and 52 deletions

View File

@ -438,7 +438,7 @@ public class GBDeviceAdapterv2 extends ListAdapter<GBDevice, GBDeviceAdapterv2.V
); );
//manage apps //manage apps
holder.manageAppsView.setVisibility((device.isInitialized() && coordinator.supportsAppsManagement()) ? View.VISIBLE : View.GONE); holder.manageAppsView.setVisibility((device.isInitialized() && coordinator.supportsAppsManagement(device)) ? View.VISIBLE : View.GONE);
holder.manageAppsView.setOnClickListener(new View.OnClickListener() holder.manageAppsView.setOnClickListener(new View.OnClickListener()
{ {
@ -811,7 +811,7 @@ public class GBDeviceAdapterv2 extends ListAdapter<GBDevice, GBDeviceAdapterv2.V
private boolean showInstallerItem(GBDevice device) { private boolean showInstallerItem(GBDevice device) {
final DeviceCoordinator coordinator = DeviceHelper.getInstance().getCoordinator(device); final DeviceCoordinator coordinator = DeviceHelper.getInstance().getCoordinator(device);
return coordinator.supportsAppsManagement() || coordinator.supportsFlashing(); return coordinator.supportsAppsManagement(device) || coordinator.supportsFlashing();
} }
private void showDeviceSubmenu(final View v, final GBDevice device) { private void showDeviceSubmenu(final View v, final GBDevice device) {

View File

@ -364,7 +364,7 @@ public interface DeviceCoordinator {
* *
* @return * @return
*/ */
boolean supportsAppsManagement(); boolean supportsAppsManagement(GBDevice device);
/** /**
* Returns the Activity class that will be used to manage device apps. * Returns the Activity class that will be used to manage device apps.

View File

@ -166,7 +166,7 @@ public class UnknownDeviceCoordinator extends AbstractDeviceCoordinator {
} }
@Override @Override
public boolean supportsAppsManagement() { public boolean supportsAppsManagement(final GBDevice device) {
return false; return false;
} }

View File

@ -42,7 +42,7 @@ public class AsteroidOSDeviceCoordinator extends AbstractDeviceCoordinator {
} }
@Override @Override
public boolean supportsAppsManagement() { public boolean supportsAppsManagement(final GBDevice device) {
return false; return false;
} }

View File

@ -156,7 +156,9 @@ public class BangleJSCoordinator extends AbstractBLEDeviceCoordinator {
} }
@Override @Override
public boolean supportsAppsManagement() { return BuildConfig.INTERNET_ACCESS; } public boolean supportsAppsManagement(final GBDevice device) {
return BuildConfig.INTERNET_ACCESS;
}
@Override @Override
public Class<? extends Activity> getAppsManagementActivity() { public Class<? extends Activity> getAppsManagementActivity() {

View File

@ -121,7 +121,7 @@ public class BinarySensorCoordinator extends AbstractBLEDeviceCoordinator {
} }
@Override @Override
public boolean supportsAppsManagement() { public boolean supportsAppsManagement(final GBDevice device) {
return true; return true;
} }

View File

@ -138,7 +138,7 @@ public class CasioGB6900DeviceCoordinator extends AbstractBLEDeviceCoordinator {
} }
@Override @Override
public boolean supportsAppsManagement() { public boolean supportsAppsManagement(final GBDevice device) {
return false; return false;
} }

View File

@ -142,7 +142,7 @@ public class CasioGBX100DeviceCoordinator extends AbstractBLEDeviceCoordinator {
} }
@Override @Override
public boolean supportsAppsManagement() { public boolean supportsAppsManagement(final GBDevice device) {
return false; return false;
} }

View File

@ -33,7 +33,7 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
public class DomyosT540Cooridnator extends AbstractBLEDeviceCoordinator { public class DomyosT540Coordinator extends AbstractBLEDeviceCoordinator {
@NonNull @NonNull
@Override @Override
public DeviceType getSupportedType(GBDeviceCandidate candidate) { public DeviceType getSupportedType(GBDeviceCandidate candidate) {
@ -100,7 +100,7 @@ public class DomyosT540Cooridnator extends AbstractBLEDeviceCoordinator {
} }
@Override @Override
public boolean supportsAppsManagement() { public boolean supportsAppsManagement(final GBDevice device) {
return false; return false;
} }

View File

@ -143,7 +143,7 @@ public class FitProDeviceCoordinator extends AbstractBLEDeviceCoordinator {
} }
@Override @Override
public boolean supportsAppsManagement() { public boolean supportsAppsManagement(final GBDevice device) {
return false; return false;
} }

View File

@ -87,7 +87,7 @@ public class FlipperZeroCoordinator extends AbstractBLEDeviceCoordinator {
} }
@Override @Override
public boolean supportsAppsManagement() { public boolean supportsAppsManagement(final GBDevice device) {
return false; return false;
} }

View File

@ -76,7 +76,7 @@ public abstract class GalaxyBudsGenericCoordinator extends AbstractBLClassicDevi
} }
@Override @Override
public boolean supportsAppsManagement() { public boolean supportsAppsManagement(final GBDevice device) {
return false; return false;
} }

View File

@ -161,7 +161,7 @@ public class HPlusCoordinator extends AbstractBLEDeviceCoordinator {
} }
@Override @Override
public boolean supportsAppsManagement() { public boolean supportsAppsManagement(final GBDevice device) {
return false; return false;
} }

View File

@ -16,6 +16,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */ along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.devices.huami; package nodomain.freeyourgadget.gadgetbridge.devices.huami;
import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.net.Uri; import android.net.Uri;
@ -23,12 +24,15 @@ import androidx.annotation.NonNull;
import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.ArrayUtils;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.activities.appmanager.AppManagerActivity;
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsCustomizer; import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsCustomizer;
import nodomain.freeyourgadget.gadgetbridge.capabilities.HeartRateCapability; import nodomain.freeyourgadget.gadgetbridge.capabilities.HeartRateCapability;
import nodomain.freeyourgadget.gadgetbridge.capabilities.password.PasswordCapabilityImpl; import nodomain.freeyourgadget.gadgetbridge.capabilities.password.PasswordCapabilityImpl;
@ -52,6 +56,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.zeppos.service
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiLanguageType; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiLanguageType;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiVibrationPatternNotificationType; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiVibrationPatternNotificationType;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.zeppos.services.ZeppOsPhoneService; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.zeppos.services.ZeppOsPhoneService;
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
import nodomain.freeyourgadget.gadgetbridge.util.Prefs; import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
public abstract class Huami2021Coordinator extends HuamiCoordinator { public abstract class Huami2021Coordinator extends HuamiCoordinator {
@ -158,6 +163,41 @@ public abstract class Huami2021Coordinator extends HuamiCoordinator {
return true; return true;
} }
@Override
public boolean supportsAppsManagement(final GBDevice device) {
return experimentalFeatures(device);
}
@Override
public Class<? extends Activity> getAppsManagementActivity() {
return AppManagerActivity.class;
}
@Override
public File getAppCacheDir() throws IOException {
return new File(FileUtils.getExternalFilesDir(), "zepp-os-app-cache");
}
@Override
public String getAppCacheSortFilename() {
return "zepp-os-app-cache-order.txt";
}
@Override
public String getAppFileExtension() {
return ".zip";
}
@Override
public boolean supportsAppListFetching() {
return true;
}
@Override
public boolean supportsAppReordering() {
return false;
}
@Override @Override
public boolean supportsCalendarEvents() { public boolean supportsCalendarEvents() {
return true; return true;

View File

@ -91,7 +91,7 @@ public abstract class HuamiCoordinator extends AbstractBLEDeviceCoordinator {
} }
@Override @Override
public boolean supportsAppsManagement() { public boolean supportsAppsManagement(final GBDevice device) {
return false; return false;
} }

View File

@ -126,7 +126,7 @@ public class ID115Coordinator extends AbstractBLEDeviceCoordinator {
} }
@Override @Override
public boolean supportsAppsManagement() { public boolean supportsAppsManagement(final GBDevice device) {
return false; return false;
} }

View File

@ -126,7 +126,7 @@ public class ITagCoordinator extends AbstractBLEDeviceCoordinator {
} }
@Override @Override
public boolean supportsAppsManagement() { public boolean supportsAppsManagement(final GBDevice device) {
return false; return false;
} }

View File

@ -160,8 +160,7 @@ public class BFH16DeviceCoordinator extends AbstractBLEDeviceCoordinator
} }
@Override @Override
public boolean supportsAppsManagement() public boolean supportsAppsManagement(final GBDevice device) {
{
return false; return false;
} }

View File

@ -162,7 +162,7 @@ public class TeclastH30Coordinator extends AbstractBLEDeviceCoordinator {
} }
@Override @Override
public boolean supportsAppsManagement() { public boolean supportsAppsManagement(final GBDevice device) {
return false; return false;
} }

View File

@ -118,7 +118,7 @@ public class Y5Coordinator extends AbstractBLEDeviceCoordinator {
} }
@Override @Override
public boolean supportsAppsManagement() { public boolean supportsAppsManagement(final GBDevice device) {
return false; return false;
} }

View File

@ -129,7 +129,7 @@ public class LefunDeviceCoordinator extends AbstractBLEDeviceCoordinator {
} }
@Override @Override
public boolean supportsAppsManagement() { public boolean supportsAppsManagement(final GBDevice device) {
return false; return false;
} }

View File

@ -161,7 +161,7 @@ public class WatchXPlusDeviceCoordinator extends AbstractBLEDeviceCoordinator {
} }
@Override @Override
public boolean supportsAppsManagement() { public boolean supportsAppsManagement(final GBDevice device) {
return false; return false;
} }

View File

@ -100,7 +100,7 @@ public class LiveviewCoordinator extends AbstractBLClassicDeviceCoordinator {
} }
@Override @Override
public boolean supportsAppsManagement() { public boolean supportsAppsManagement(final GBDevice device) {
return false; return false;
} }

View File

@ -256,7 +256,7 @@ public class MakibesHR3Coordinator extends AbstractBLEDeviceCoordinator {
} }
@Override @Override
public boolean supportsAppsManagement() { public boolean supportsAppsManagement(final GBDevice device) {
return false; return false;
} }

View File

@ -154,7 +154,7 @@ public class MiBandCoordinator extends AbstractBLEDeviceCoordinator {
} }
@Override @Override
public boolean supportsAppsManagement() { public boolean supportsAppsManagement(final GBDevice device) {
return false; return false;
} }

View File

@ -105,7 +105,7 @@ public class MijiaLywsd02Coordinator extends AbstractBLEDeviceCoordinator {
} }
@Override @Override
public boolean supportsAppsManagement() { public boolean supportsAppsManagement(final GBDevice device) {
return false; return false;
} }

View File

@ -145,7 +145,7 @@ public class MiScale2DeviceCoordinator extends AbstractBLEDeviceCoordinator {
} }
@Override @Override
public boolean supportsAppsManagement() { public boolean supportsAppsManagement(final GBDevice device) {
return false; return false;
} }

View File

@ -126,7 +126,7 @@ public class No1F1Coordinator extends AbstractBLEDeviceCoordinator {
} }
@Override @Override
public boolean supportsAppsManagement() { public boolean supportsAppsManagement(final GBDevice device) {
return false; return false;
} }

View File

@ -87,7 +87,7 @@ public class Ear1Coordinator extends AbstractBLClassicDeviceCoordinator {
} }
@Override @Override
public boolean supportsAppsManagement() { public boolean supportsAppsManagement(final GBDevice device) {
return false; return false;
} }

View File

@ -128,7 +128,7 @@ public class NutCoordinator extends AbstractBLEDeviceCoordinator {
} }
@Override @Override
public boolean supportsAppsManagement() { public boolean supportsAppsManagement(final GBDevice device) {
return false; return false;
} }

View File

@ -146,7 +146,7 @@ public class PebbleCoordinator extends AbstractBLClassicDeviceCoordinator {
} }
@Override @Override
public boolean supportsAppsManagement() { public boolean supportsAppsManagement(final GBDevice device) {
return true; return true;
} }

View File

@ -105,7 +105,7 @@ public class PineTimeJFCoordinator extends AbstractBLEDeviceCoordinator {
} }
@Override @Override
public boolean supportsAppsManagement() { public boolean supportsAppsManagement(final GBDevice device) {
return false; return false;
} }

View File

@ -114,7 +114,7 @@ public class QC35Coordinator extends AbstractBLClassicDeviceCoordinator {
} }
@Override @Override
public boolean supportsAppsManagement() { public boolean supportsAppsManagement(final GBDevice device) {
return false; return false;
} }

View File

@ -174,7 +174,7 @@ public class QHybridCoordinator extends AbstractBLEDeviceCoordinator {
} }
@Override @Override
public boolean supportsAppsManagement() { public boolean supportsAppsManagement(final GBDevice device) {
return true; return true;
} }

View File

@ -99,7 +99,7 @@ public abstract class RoidmiCoordinator extends AbstractBLClassicDeviceCoordinat
} }
@Override @Override
public boolean supportsAppsManagement() { public boolean supportsAppsManagement(final GBDevice device) {
return false; return false;
} }

View File

@ -123,7 +123,7 @@ public class SMAQ2OSSCoordinator extends AbstractBLEDeviceCoordinator {
} }
@Override @Override
public boolean supportsAppsManagement() { public boolean supportsAppsManagement(final GBDevice device) {
return false; return false;
} }

View File

@ -100,7 +100,7 @@ public class SoFlowCoordinator extends AbstractBLEDeviceCoordinator {
} }
@Override @Override
public boolean supportsAppsManagement() { public boolean supportsAppsManagement(final GBDevice device) {
return false; return false;
} }

View File

@ -106,7 +106,7 @@ public abstract class SonyHeadphonesCoordinator extends AbstractBLClassicDeviceC
} }
@Override @Override
public boolean supportsAppsManagement() { public boolean supportsAppsManagement(final GBDevice device) {
return false; return false;
} }

View File

@ -111,7 +111,7 @@ public class SonySWR12DeviceCoordinator extends AbstractBLEDeviceCoordinator {
} }
@Override @Override
public boolean supportsAppsManagement() { public boolean supportsAppsManagement(final GBDevice device) {
return false; return false;
} }

View File

@ -115,7 +115,7 @@ public class SuperCarsCoordinator extends AbstractDeviceCoordinator {
} }
@Override @Override
public boolean supportsAppsManagement() { public boolean supportsAppsManagement(final GBDevice device) {
return true; return true;
} }

View File

@ -111,7 +111,7 @@ public class TLW64Coordinator extends AbstractBLEDeviceCoordinator {
} }
@Override @Override
public boolean supportsAppsManagement() { public boolean supportsAppsManagement(final GBDevice device) {
return false; return false;
} }

View File

@ -121,7 +121,7 @@ public class UM25Coordinator extends AbstractBLEDeviceCoordinator {
} }
@Override @Override
public boolean supportsAppsManagement() { public boolean supportsAppsManagement(final GBDevice device) {
return true; return true;
} }

View File

@ -136,7 +136,7 @@ public class VescCoordinator extends AbstractBLEDeviceCoordinator {
} }
@Override @Override
public boolean supportsAppsManagement() { public boolean supportsAppsManagement(final GBDevice device) {
return true; return true;
} }

View File

@ -100,7 +100,7 @@ public class VibratissimoCoordinator extends AbstractBLEDeviceCoordinator {
} }
@Override @Override
public boolean supportsAppsManagement() { public boolean supportsAppsManagement(final GBDevice device) {
return false; return false;
} }

View File

@ -131,7 +131,7 @@ public class WaspOSCoordinator extends AbstractBLEDeviceCoordinator {
} }
@Override @Override
public boolean supportsAppsManagement() { public boolean supportsAppsManagement(final GBDevice device) {
return false; return false;
} }

View File

@ -134,7 +134,7 @@ public class Watch9DeviceCoordinator extends AbstractBLEDeviceCoordinator {
} }
@Override @Override
public boolean supportsAppsManagement() { public boolean supportsAppsManagement(final GBDevice device) {
return false; return false;
} }

View File

@ -107,7 +107,7 @@ public class XWatchCoordinator extends AbstractBLEDeviceCoordinator {
} }
@Override @Override
public boolean supportsAppsManagement() { public boolean supportsAppsManagement(final GBDevice device) {
return false; return false;
} }

View File

@ -118,7 +118,7 @@ public class ZeTimeCoordinator extends AbstractBLEDeviceCoordinator {
} }
@Override @Override
public boolean supportsAppsManagement() { public boolean supportsAppsManagement(final GBDevice device) {
return false; return false;
} }

View File

@ -66,6 +66,7 @@ import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -112,6 +113,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.zeppos.operati
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.zeppos.services.ZeppOsAgpsService; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.zeppos.services.ZeppOsAgpsService;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.zeppos.services.ZeppOsAlarmsService; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.zeppos.services.ZeppOsAlarmsService;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.zeppos.services.ZeppOsAlexaService; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.zeppos.services.ZeppOsAlexaService;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.zeppos.services.ZeppOsAppsService;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.zeppos.services.ZeppOsCalendarService; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.zeppos.services.ZeppOsCalendarService;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.zeppos.services.ZeppOsCannedMessagesService; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.zeppos.services.ZeppOsCannedMessagesService;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.zeppos.services.ZeppOsNotificationService; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.zeppos.services.ZeppOsNotificationService;
@ -154,6 +156,7 @@ public abstract class Huami2021Support extends HuamiSupport {
private final ZeppOsCannedMessagesService cannedMessagesService = new ZeppOsCannedMessagesService(this); private final ZeppOsCannedMessagesService cannedMessagesService = new ZeppOsCannedMessagesService(this);
private final ZeppOsNotificationService notificationService = new ZeppOsNotificationService(this, fileUploadService); private final ZeppOsNotificationService notificationService = new ZeppOsNotificationService(this, fileUploadService);
private final ZeppOsAlexaService alexaService = new ZeppOsAlexaService(this); private final ZeppOsAlexaService alexaService = new ZeppOsAlexaService(this);
private final ZeppOsAppsService appsService = new ZeppOsAppsService(this);
private final Map<Short, AbstractZeppOsService> mServiceMap = new LinkedHashMap<Short, AbstractZeppOsService>() {{ private final Map<Short, AbstractZeppOsService> mServiceMap = new LinkedHashMap<Short, AbstractZeppOsService>() {{
put(fileUploadService.getEndpoint(), fileUploadService); put(fileUploadService.getEndpoint(), fileUploadService);
@ -171,6 +174,7 @@ public abstract class Huami2021Support extends HuamiSupport {
put(cannedMessagesService.getEndpoint(), cannedMessagesService); put(cannedMessagesService.getEndpoint(), cannedMessagesService);
put(notificationService.getEndpoint(), notificationService); put(notificationService.getEndpoint(), notificationService);
put(alexaService.getEndpoint(), alexaService); put(alexaService.getEndpoint(), alexaService);
put(appsService.getEndpoint(), appsService);
}}; }};
public Huami2021Support() { public Huami2021Support() {
@ -669,6 +673,24 @@ public abstract class Huami2021Support extends HuamiSupport {
super.onInstallApp(uri); super.onInstallApp(uri);
} }
@Override
public void onAppInfoReq() {
appsService.requestApps();
// TODO watchfaceService.requestWatchfaces();
}
@Override
public void onAppStart(final UUID uuid, final boolean start) {
// TODO check if watchface
//LOG.warn("TODO: onAppStart {} {}", uuid, start);
//watchfaceService.setWatchface("0x" + uuid.toString().split("-")[0]);
}
@Override
public void onAppDelete(final UUID uuid) {
appsService.deleteApp(Integer.parseInt(uuid.toString().split("-")[0], 16));
}
@Override @Override
protected Huami2021Support setHeartrateSleepSupport(final TransactionBuilder builder) { protected Huami2021Support setHeartrateSleepSupport(final TransactionBuilder builder) {
final boolean enableHrSleepSupport = MiBandCoordinator.getHeartrateSleepSupport(gbDevice.getAddress()); final boolean enableHrSleepSupport = MiBandCoordinator.getHeartrateSleepSupport(gbDevice.getAddress());

View File

@ -0,0 +1,157 @@
/* Copyright (C) 2023 José Rebelo
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 <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.service.devices.huami.zeppos.services;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventAppInfo;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceApp;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.Huami2021Support;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.zeppos.AbstractZeppOsService;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
public class ZeppOsAppsService extends AbstractZeppOsService {
private static final Logger LOG = LoggerFactory.getLogger(ZeppOsAppsService.class);
private static final short ENDPOINT = 0x00a0;
private static final byte CMD_BYTE = 0x02;
private static final byte CMD_INCOMING = 0x00;
private static final byte CMD_OUTGOING = 0x01;
private static final byte CMD_APP_LIST = 0x01;
private static final byte CMD_APP_DELETE = 0x03;
private static final byte CMD_APP_DELETING = 0x04;
public ZeppOsAppsService(final Huami2021Support support) {
super(support);
}
@Override
public short getEndpoint() {
return ENDPOINT;
}
@Override
public boolean isEncrypted() {
return false;
}
@Override
public void handlePayload(final byte[] payload) {
if (payload[0] != CMD_BYTE) {
LOG.warn("Unexpected apps byte {}", String.format("0x%02x", payload[0]));
return;
}
if (payload[1] != CMD_INCOMING) {
LOG.warn("Unexpected apps 2nd byte {}", String.format("0x%02x", payload[1]));
return;
}
switch (payload[2]) {
case CMD_APP_LIST:
parseAppList(payload);
return;
case CMD_APP_DELETE:
LOG.info("Got app delete");
return;
case CMD_APP_DELETING:
LOG.info("Got app deleting");
return;
default:
LOG.warn("Unexpected apps payload {}", GB.hexdump(payload));
}
}
private void parseAppList(final byte[] payload) {
final List<GBDeviceApp> apps = new ArrayList<>();
final byte[] appListStringBytes = ArrayUtils.subarray(payload, 16, payload.length);
final String appListString = new String(appListStringBytes);
final String[] appListSplit = appListString.split(";");
for (final String appString : appListSplit) {
if (StringUtils.isBlank(appString)) {
continue;
}
final String[] appSplit = appString.split("-", 2);
if (appSplit.length != 2) {
LOG.warn("Failed to parse {}", appString);
continue;
}
final int appId = Integer.parseInt(appSplit[0], 16);
final String appVersion = appSplit[1];
LOG.debug("Got app: '{}'", appString);
apps.add(new GBDeviceApp(
UUID.fromString(String.format("%08x-0000-0000-0000-000000000000", appId)),
"", //String.format("0x%08x", appId),
"",
appVersion,
GBDeviceApp.Type.APP_GENERIC // it might actually be a watchface
));
}
final GBDeviceEventAppInfo appInfoCmd = new GBDeviceEventAppInfo();
appInfoCmd.apps = apps.toArray(new GBDeviceApp[0]);
getSupport().evaluateGBDeviceEvent(appInfoCmd);
}
public void requestApps() {
LOG.info("Request apps");
final ByteBuffer buf = ByteBuffer.allocate(16).order(ByteOrder.LITTLE_ENDIAN);
buf.put(CMD_BYTE);
buf.put(CMD_OUTGOING);
buf.put(CMD_APP_LIST);
buf.put((byte) 0x00);
write("request apps", buf.array());
}
public void deleteApp(final int appId) {
LOG.info("Delete app {}", String.format("0x%08x", appId));
final ByteBuffer buf = ByteBuffer.allocate(20).order(ByteOrder.LITTLE_ENDIAN);
buf.put(CMD_BYTE);
buf.put(CMD_OUTGOING);
buf.put(CMD_APP_DELETE);
buf.put((byte) 0x00);
buf.putInt(0x00);
buf.putInt(0x00);
buf.putInt(0x00);
buf.putInt(appId);
write("delete app", buf.array());
}
}

View File

@ -57,7 +57,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.UnknownDeviceCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.banglejs.BangleJSCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.banglejs.BangleJSCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.casio.gb6900.CasioGB6900DeviceCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.casio.gb6900.CasioGB6900DeviceCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.casio.gbx100.CasioGBX100DeviceCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.casio.gbx100.CasioGBX100DeviceCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.domyos.DomyosT540Cooridnator; import nodomain.freeyourgadget.gadgetbridge.devices.domyos.DomyosT540Coordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.galaxy_buds.GalaxyBuds2DeviceCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.galaxy_buds.GalaxyBuds2DeviceCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.flipper.zero.FlipperZeroCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.flipper.zero.FlipperZeroCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.galaxy_buds.GalaxyBudsDeviceCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.galaxy_buds.GalaxyBudsDeviceCoordinator;
@ -348,7 +348,7 @@ public class DeviceHelper {
result.add(new WaspOSCoordinator()); result.add(new WaspOSCoordinator());
result.add(new SMAQ2OSSCoordinator()); result.add(new SMAQ2OSSCoordinator());
result.add(new UM25Coordinator()); result.add(new UM25Coordinator());
result.add(new DomyosT540Cooridnator()); result.add(new DomyosT540Coordinator());
result.add(new FitProDeviceCoordinator()); result.add(new FitProDeviceCoordinator());
result.add(new Ear1Coordinator()); result.add(new Ear1Coordinator());
result.add(new GalaxyBudsDeviceCoordinator()); result.add(new GalaxyBudsDeviceCoordinator());