[Huawei] Hookup GPS values

This commit is contained in:
Martin.JM 2024-04-01 06:43:19 +02:00
parent 22720514b9
commit 88746d5706
8 changed files with 213 additions and 1 deletions

View File

@ -202,6 +202,7 @@ public class HuaweiCoordinator {
notifications.add(R.xml.devicesettings_donotdisturb_allday_liftwirst_notwear);
// Workout
deviceSpecificSettings.addRootScreen(DeviceSpecificSettingsScreen.WORKOUT, R.xml.devicesettings_workout_send_gps_to_band);
// Other
deviceSpecificSettings.addRootScreen(R.xml.devicesettings_find_phone);

View File

@ -509,6 +509,8 @@ public class HuaweiPacket {
switch (this.commandId) {
case GpsAndTime.GpsParameters.id:
return new GpsAndTime.GpsParameters.Response(paramsProvider).fromPacket(this);
case GpsAndTime.GpsStatus.id:
return new GpsAndTime.GpsStatus.Response(paramsProvider).fromPacket(this);
case GpsAndTime.GpsData.id:
return new GpsAndTime.GpsData.Response(paramsProvider).fromPacket(this);
default:

View File

@ -45,9 +45,12 @@ import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiPacket;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Calls;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.DeviceConfig;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.FindPhone;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.GpsAndTime;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Menstrual;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.MusicControl;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Weather;
import nodomain.freeyourgadget.gadgetbridge.externalevents.gps.GBLocationListener;
import nodomain.freeyourgadget.gadgetbridge.externalevents.gps.GBLocationManager;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.Request;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.GetPhoneInfoRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendMenstrualModifyTimeRequest;
@ -98,6 +101,7 @@ public class AsynchronousResponse {
handlePhoneInfo(response);
handleMenstrualModifyTime(response);
handleWeatherCheck(response);
handleGpsRequest(response);
} catch (Request.ResponseParseException e) {
LOG.error("Response parse exception", e);
}
@ -395,4 +399,14 @@ public class AsynchronousResponse {
// TODO: send back weather?
}
}
private void handleGpsRequest(HuaweiPacket response) {
if (response.serviceId == GpsAndTime.id && response.commandId == GpsAndTime.GpsStatus.id) {
if (!(response instanceof GpsAndTime.GpsStatus.Response)) {
// TODO: exception?
return;
}
support.setGps(((GpsAndTime.GpsStatus.Response) response).enableGps);
}
}
}

View File

@ -16,6 +16,8 @@
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.service.devices.huawei;
import android.location.Location;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
@ -123,4 +125,9 @@ public class HuaweiBRSupport extends AbstractBTBRDeviceSupport {
public void onSendWeather(ArrayList<WeatherSpec> weatherSpecs) {
supportProvider.onSendWeather(weatherSpecs);
}
@Override
public void onSetGpsLocation(Location location) {
supportProvider.onSetGpsLocation(location);
}
}

View File

@ -18,6 +18,7 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.huawei;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.location.Location;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -131,4 +132,9 @@ public class HuaweiLESupport extends AbstractBTLEDeviceSupport {
public void onSendWeather(ArrayList<WeatherSpec> weatherSpecs) {
supportProvider.onSendWeather(weatherSpecs);
}
@Override
public void onSetGpsLocation(Location location) {
supportProvider.onSetGpsLocation(location);
}
}

View File

@ -19,6 +19,7 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.huawei;
import android.bluetooth.BluetoothGattCharacteristic;
import android.content.Context;
import android.content.SharedPreferences;
import android.location.Location;
import android.widget.Toast;
import androidx.annotation.NonNull;
@ -43,6 +44,7 @@ import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent;
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.EventHandler;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiConstants;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiCoordinatorSupplier;
@ -50,6 +52,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiCoordinatorSupp
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiCrypto;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiPacket;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiSampleProvider;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.GpsAndTime;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Weather;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.Workout;
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst;
@ -62,6 +65,7 @@ import nodomain.freeyourgadget.gadgetbridge.entities.HuaweiWorkoutPaceSample;
import nodomain.freeyourgadget.gadgetbridge.entities.HuaweiWorkoutPaceSampleDao;
import nodomain.freeyourgadget.gadgetbridge.entities.HuaweiWorkoutSummarySample;
import nodomain.freeyourgadget.gadgetbridge.entities.HuaweiWorkoutSummarySampleDao;
import nodomain.freeyourgadget.gadgetbridge.externalevents.gps.GBLocationManager;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.entities.Alarm;
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
@ -77,10 +81,12 @@ import nodomain.freeyourgadget.gadgetbridge.model.RecordedDataTypes;
import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.AcceptAgreementsRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.GetEventAlarmList;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.GetGpsParameterRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.GetNotificationConstraintsRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.GetSmartAlarmList;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendExtendedAccountRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendGpsAndTimeToDeviceRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendGpsDataRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendWeatherCurrentRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendNotifyHeartRateCapabilityRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendNotifyRestHeartRateCapabilityRequest;
@ -107,7 +113,6 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.Alar
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.DebugRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.GetActivityTypeRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.Request;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendAccountRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.Request.RequestCallback;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.GetAuthRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.GetBatteryLevelRequest;
@ -168,6 +173,8 @@ public class HuaweiSupportProvider {
private MusicStateSpec musicStateSpec = null;
private MusicSpec musicSpec = null;
private GpsAndTime.GpsParameters.Response gpsParametersResponse = null;
private final HuaweiPacket.ParamsProvider paramsProvider = new HuaweiPacket.ParamsProvider();
protected ResponseManager responseManager = new ResponseManager(this);
@ -220,6 +227,39 @@ public class HuaweiSupportProvider {
}
}
public void setGps(boolean start) {
EventHandler handler;
if (isBLE())
handler = leSupport;
else
handler = brSupport;
if (start) {
if (!GBApplication.getDeviceSpecificSharedPrefs(getDevice().getAddress()).getBoolean(DeviceSettingsPreferenceConst.PREF_WORKOUT_SEND_GPS_TO_BAND, false))
return;
if (gpsParametersResponse == null) {
GetGpsParameterRequest gpsParameterRequest = new GetGpsParameterRequest(this);
gpsParameterRequest.setFinalizeReq(new RequestCallback() {
@Override
public void call() {
GBLocationManager.start(getContext(), handler);
}
});
try {
gpsParameterRequest.doPerform();
} catch (IOException e) {
GB.toast(context, "Failed to get GPS parameters", Toast.LENGTH_SHORT, GB.ERROR, e);
LOG.error("Failed to get GPS parameters", e);
}
} else
GBLocationManager.start(getContext(), handler);
} else
GBLocationManager.stop(getContext(), handler);
}
public void setGpsParametersResponse(GpsAndTime.GpsParameters.Response response) {
this.gpsParametersResponse = response;
}
protected nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder initializeDevice(nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder builder) {
this.gbDevice = leSupport.getDevice();
this.context = leSupport.getContext();
@ -1768,4 +1808,21 @@ public class HuaweiSupportProvider {
LOG.error("Failed to send weather", e);
}
}
public void onSetGpsLocation(Location location) {
if (gpsParametersResponse == null) {
GB.toast(context, "Received location without knowing supported parameters", Toast.LENGTH_SHORT, GB.ERROR);
LOG.error("Received location without knowing supported parameters");
return;
}
SendGpsDataRequest sendGpsDataRequest = new SendGpsDataRequest(this, location, gpsParametersResponse);
try {
sendGpsDataRequest.doPerform();
} catch (IOException e) {
// TODO: Use translatable string
GB.toast(context, "Failed to send GPS data", Toast.LENGTH_SHORT, GB.ERROR, e);
LOG.error("Failed to send GPS data", e);
}
}
}

View File

@ -0,0 +1,48 @@
/* Copyright (C) 2024 Martin.JM
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.service.devices.huawei.requests;
import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiPacket;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.GpsAndTime;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.HuaweiSupportProvider;
public class GetGpsParameterRequest extends Request {
public GetGpsParameterRequest(HuaweiSupportProvider support) {
super(support);
this.serviceId = GpsAndTime.id;
this.commandId = GpsAndTime.GpsParameters.id;
}
@Override
protected List<byte[]> createRequest() throws RequestCreationException {
try {
return new GpsAndTime.GpsParameters.Request(this.paramsProvider).serialize();
} catch (HuaweiPacket.CryptoException e) {
throw new RequestCreationException(e);
}
}
@Override
protected void processResponse() throws ResponseParseException {
if (!(receivedPacket instanceof GpsAndTime.GpsParameters.Response))
throw new ResponseTypeMismatchException(receivedPacket, GpsAndTime.GpsParameters.Response.class);
supportProvider.setGpsParametersResponse((GpsAndTime.GpsParameters.Response) receivedPacket);
}
}

View File

@ -0,0 +1,77 @@
/* Copyright (C) 2024 Martin.JM
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.service.devices.huawei.requests;
import android.location.Location;
import java.util.ArrayList;
import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiPacket;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.GpsAndTime;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.HuaweiSupportProvider;
public class SendGpsDataRequest extends Request {
Location location;
GpsAndTime.GpsParameters.Response gpsParametersResponse;
public SendGpsDataRequest(HuaweiSupportProvider support, Location location, GpsAndTime.GpsParameters.Response gpsParametersResponse) {
super(support);
this.serviceId = GpsAndTime.id;
this.commandId = GpsAndTime.GpsData.id;
this.location = location;
this.gpsParametersResponse = gpsParametersResponse;
}
@Override
protected List<byte[]> createRequest() throws RequestCreationException {
ArrayList<GpsAndTime.GpsData.Request.GpsDataContainer> gpsList = new ArrayList<>();
GpsAndTime.GpsData.Request.GpsDataContainer gpsData = new GpsAndTime.GpsData.Request.GpsDataContainer();
if (this.gpsParametersResponse.supportsSpeed && location.hasSpeed()) {
gpsData.hasSpeed = true;
gpsData.speed = (short) location.getSpeed();
}
if (this.gpsParametersResponse.supportsAltitude && location.hasAltitude()) {
gpsData.hasAltitude = true;
gpsData.altitude = (short) location.getAltitude();
}
if (this.gpsParametersResponse.supportsLatLon) {
gpsData.hasLatLon = true;
gpsData.lat = location.getLatitude();
gpsData.lon = location.getLongitude();
}
if (this.gpsParametersResponse.supportsDirection && location.hasBearing()) {
gpsData.hasBearing = true;
gpsData.bearing = location.getBearing();
}
if (this.gpsParametersResponse.supportsPrecision && location.hasAccuracy()) {
gpsData.hasAccuracy = true;
gpsData.accuracy = location.getAccuracy();
}
gpsList.add(gpsData);
try {
return new GpsAndTime.GpsData.Request(
this.paramsProvider,
gpsList
).serialize();
} catch (HuaweiPacket.CryptoException e) {
throw new RequestCreationException(e);
}
}
}