huawei: Add huawei account support (#3721)

* this feature allows to pair HarmonyOS devices without factory reset to
  GB and Huawei Health.

* huawei account has form of 17 digit string and could be retrived from
  logcat filtering by huid=

Reviewed-on: https://codeberg.org/Freeyourgadget/Gadgetbridge/pulls/3721
Co-authored-by: Vitaliy Tomin <highwaystar.ru@gmail.com>
Co-committed-by: Vitaliy Tomin <highwaystar.ru@gmail.com>
This commit is contained in:
Vitaliy Tomin 2024-04-25 12:19:00 +00:00 committed by José Rebelo
parent 173e2d29b0
commit 67cf9b2f00
8 changed files with 53 additions and 10 deletions

View File

@ -30,6 +30,7 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import de.greenrobot.dao.query.QueryBuilder; import de.greenrobot.dao.query.QueryBuilder;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettings; import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettings;
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsCustomizer; import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsCustomizer;
@ -83,6 +84,11 @@ public abstract class HuaweiBRCoordinator extends AbstractBLClassicDeviceCoordin
return huaweiCoordinator.getSupportedLanguageSettings(device); return huaweiCoordinator.getSupportedLanguageSettings(device);
} }
@Override
public int[] getSupportedDeviceSpecificAuthenticationSettings() {
return new int[]{R.xml.devicesettings_huawei_account};
}
@Override @Override
public int getBondingStyle(){ public int getBondingStyle(){
return BONDING_STYLE_ASK; return BONDING_STYLE_ASK;

View File

@ -71,6 +71,7 @@ public final class HuaweiConstants {
public static final String PREF_HUAWEI_ADDRESS = "huawei_address"; public static final String PREF_HUAWEI_ADDRESS = "huawei_address";
public static final String PREF_HUAWEI_WORKMODE = "workmode"; public static final String PREF_HUAWEI_WORKMODE = "workmode";
public static final String PREF_HUAWEI_TRUSLEEP = "trusleep"; public static final String PREF_HUAWEI_TRUSLEEP = "trusleep";
public static final String PREF_HUAWEI_ACCOUNT = "huawei_account";
public static final String PREF_HUAWEI_DND_LIFT_WRIST_TYPE = "dnd_lift_wrist_type"; // SharedPref for 0x01 0x1D public static final String PREF_HUAWEI_DND_LIFT_WRIST_TYPE = "dnd_lift_wrist_type"; // SharedPref for 0x01 0x1D
public static final String PREF_HUAWEI_DEBUG_REQUEST = "debug_huawei_request"; public static final String PREF_HUAWEI_DEBUG_REQUEST = "debug_huawei_request";

View File

@ -30,6 +30,7 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import de.greenrobot.dao.query.QueryBuilder; import de.greenrobot.dao.query.QueryBuilder;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettings; import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettings;
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsCustomizer; import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsCustomizer;
import nodomain.freeyourgadget.gadgetbridge.GBException; import nodomain.freeyourgadget.gadgetbridge.GBException;
@ -82,7 +83,12 @@ public abstract class HuaweiLECoordinator extends AbstractBLEDeviceCoordinator i
public String[] getSupportedLanguageSettings(GBDevice device) { public String[] getSupportedLanguageSettings(GBDevice device) {
return huaweiCoordinator.getSupportedLanguageSettings(device); return huaweiCoordinator.getSupportedLanguageSettings(device);
} }
@Override
public int[] getSupportedDeviceSpecificAuthenticationSettings() {
return new int[]{R.xml.devicesettings_huawei_account};
}
@Override @Override
public int getBondingStyle(){ public int getBondingStyle(){
return BONDING_STYLE_NONE; return BONDING_STYLE_NONE;

View File

@ -26,15 +26,18 @@ public class AccountRelated {
public static final byte id = 0x01; public static final byte id = 0x01;
public static class Request extends HuaweiPacket { public static class Request extends HuaweiPacket {
public Request (ParamsProvider paramsProvider) { public Request (ParamsProvider paramsProvider, String account) {
super(paramsProvider); super(paramsProvider);
this.serviceId = AccountRelated.id; this.serviceId = AccountRelated.id;
this.commandId = id; this.commandId = id;
this.tlv = new HuaweiTLV() this.tlv = new HuaweiTLV();
.put(0x01); if (account.length() > 0) {
tlv.put(0x01, account);
} else {
tlv.put(0x01);
}
this.complete = true; this.complete = true;
} }
} }
@ -50,14 +53,19 @@ public class AccountRelated {
public static final byte id = 0x05; public static final byte id = 0x05;
public static class Request extends HuaweiPacket { public static class Request extends HuaweiPacket {
public Request (ParamsProvider paramsProvider, boolean accountPairingOptimization) { public Request (ParamsProvider paramsProvider, boolean accountPairingOptimization, String account) {
super(paramsProvider); super(paramsProvider);
this.serviceId = AccountRelated.id; this.serviceId = AccountRelated.id;
this.commandId = id; this.commandId = id;
this.tlv = new HuaweiTLV() this.tlv = new HuaweiTLV();
.put(0x01, (byte)0x00); if (account.length() > 0) {
tlv.put(0x01, account);
} else {
tlv.put(0x01, (byte)0x00);
}
if (accountPairingOptimization) { if (accountPairingOptimization) {
this.tlv.put(0x03, (byte)0x01); this.tlv.put(0x03, (byte)0x01);
} }

View File

@ -21,7 +21,9 @@ import org.slf4j.LoggerFactory;
import java.util.List; import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.GBException; import nodomain.freeyourgadget.gadgetbridge.GBException;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiConstants;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiPacket.CryptoException; import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiPacket.CryptoException;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.AccountRelated; import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.AccountRelated;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.HuaweiSupportProvider; import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.HuaweiSupportProvider;
@ -37,8 +39,11 @@ public class SendAccountRequest extends Request {
@Override @Override
protected List<byte[]> createRequest() throws RequestCreationException { protected List<byte[]> createRequest() throws RequestCreationException {
String account = GBApplication
.getDeviceSpecificSharedPrefs(supportProvider.getDevice().getAddress())
.getString(HuaweiConstants.PREF_HUAWEI_ACCOUNT, "").trim();
try { try {
return new AccountRelated.SendAccountToDevice.Request(paramsProvider).serialize(); return new AccountRelated.SendAccountToDevice.Request(paramsProvider, account).serialize();
} catch (CryptoException e) { } catch (CryptoException e) {
throw new RequestCreationException(e); throw new RequestCreationException(e);
} }

View File

@ -22,6 +22,8 @@ import org.slf4j.LoggerFactory;
import java.util.List; import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiConstants;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiPacket.CryptoException; import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiPacket.CryptoException;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.AccountRelated; import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.AccountRelated;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.HuaweiSupportProvider; import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.HuaweiSupportProvider;
@ -37,10 +39,14 @@ public class SendExtendedAccountRequest extends Request {
@Override @Override
protected List<byte[]> createRequest() throws Request.RequestCreationException { protected List<byte[]> createRequest() throws Request.RequestCreationException {
String account = GBApplication
.getDeviceSpecificSharedPrefs(supportProvider.getDevice().getAddress())
.getString(HuaweiConstants.PREF_HUAWEI_ACCOUNT, "").trim();
try { try {
return new AccountRelated.SendExtendedAccountToDevice.Request( return new AccountRelated.SendExtendedAccountToDevice.Request(
paramsProvider, paramsProvider,
supportProvider.getHuaweiCoordinator().supportsDiffAccountPairingOptimization()) supportProvider.getHuaweiCoordinator().supportsDiffAccountPairingOptimization(),
account)
.serialize(); .serialize();
} catch (CryptoException e) { } catch (CryptoException e) {
throw new Request.RequestCreationException(e); throw new Request.RequestCreationException(e);

View File

@ -2812,4 +2812,6 @@
<string name="pref_sleepasandroid_feat_heartrate">Heart rate</string> <string name="pref_sleepasandroid_feat_heartrate">Heart rate</string>
<string name="pref_sleepasandroid_feat_oximetry">Oximetry</string> <string name="pref_sleepasandroid_feat_oximetry">Oximetry</string>
<string name="pref_sleepasandroid_feat_spo2">SPO2</string> <string name="pref_sleepasandroid_feat_spo2">SPO2</string>
<string name="pref_title_huawei_account">Huawei Account</string>
<string name="pref_summary_huawei_account">Huawei account used in pairing process. Setting it allows to pair without factory reset.</string>
</resources> </resources>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<EditTextPreference
android:icon="@drawable/ic_vpn_key"
android:key="huawei_account"
android:maxLength="17"
android:summary="@string/pref_summary_huawei_account"
android:title="@string/pref_title_huawei_account" />
</androidx.preference.PreferenceScreen>