Garmin: Handle HTTP requests for image service

This commit is contained in:
José Rebelo
2025-11-21 22:03:53 +00:00
parent e6b92b6757
commit a38fe4eaa3
2 changed files with 65 additions and 3 deletions
@@ -21,11 +21,13 @@ public class HttpHandler {
private final AgpsHandler agpsHandler;
private final ContactsHandler contactsHandler;
private final OauthHandler oauthHandler;
private final ImageServiceHandler imageServiceHandler;
public HttpHandler(GarminSupport deviceSupport) {
agpsHandler = new AgpsHandler(deviceSupport);
contactsHandler = new ContactsHandler(deviceSupport);
oauthHandler = new OauthHandler(deviceSupport);
imageServiceHandler = new ImageServiceHandler();
}
public GdiHttpService.HttpService handle(final GdiHttpService.HttpService httpService) {
@@ -62,6 +64,9 @@ public class HttpHandler {
} else if (request.getPath().startsWith("/api/oauth") || request.getPath().startsWith("/oauthTokenExchangeService")) {
LOG.info("Got OAuth request for {}", request.getPath());
response = oauthHandler.handleRequest(request);
} else if (request.getPath().startsWith("/image-service/")) {
LOG.info("Got image service request for {}", request.getPath());
response = imageServiceHandler.handleRequest(request);
} else {
LOG.warn("Unhandled path {}", request.getPath());
response = null;
@@ -92,9 +97,9 @@ public class HttpHandler {
);
}
if (response.getStatus() == 200 && request.getRawRequest().hasUseDataXfer() && request.getRawRequest().getUseDataXfer()) {
if (request.getRawRequest().hasUseDataXfer() && request.getRawRequest().getUseDataXfer()) {
LOG.debug("Data will be returned using data_xfer");
int id = DataTransferHandler.registerData(response.getBody());
final int id = DataTransferHandler.registerData(response.getBody());
if (response.getOnDataSuccessfullySentListener() != null) {
DataTransferHandler.addOnDataSuccessfullySentListener(id, response.getOnDataSuccessfullySentListener());
}
@@ -136,7 +141,7 @@ public class HttpHandler {
}
return GdiHttpService.HttpService.RawResponse.newBuilder()
.setStatus(response.getStatus() / 100 == 2 ? GdiHttpService.HttpService.Status.OK : GdiHttpService.HttpService.Status.UNKNOWN_STATUS)
.setStatus(GdiHttpService.HttpService.Status.OK)
.setHttpStatus(response.getStatus())
.setBody(ByteString.copyFrom(responseBody))
.addAllHeader(responseHeaders)
@@ -0,0 +1,57 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.http;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.proto.garmin.GdiHttpService;
public class ImageServiceHandler {
private static final Logger LOG = LoggerFactory.getLogger(ImageServiceHandler.class);
private static final Gson GSON = new GsonBuilder()
//.serializeNulls()
.create();
public GarminHttpResponse handleRequest(final GarminHttpRequest request) {
if (request.getRawRequest().getMethod() != GdiHttpService.HttpService.Method.GET) {
LOG.warn("Known image service requests should be GET");
return null;
}
if (!request.getPath().equals("/image-service/v2/device/images/details")) {
LOG.warn("Unknown image service path {}", request.getPath());
return null;
}
final String ownerAliasId = request.getQuery().get("ownerAliasId");
final String requestId = UUID.randomUUID().toString();
final ErrorResponse errorResponse = new ErrorResponse(requestId, Collections.singletonList(new Error(
"Owner alias (" + ownerAliasId + ") not found",
"NOT_FOUND"
)));
final GarminHttpResponse response = new GarminHttpResponse();
response.setStatus(404);
response.setBody(GSON.toJson(errorResponse).getBytes(StandardCharsets.UTF_8));
response.getHeaders().put("Content-Type", "application/json");
response.getHeaders().put("x-request-id", requestId);
return response;
}
public record ErrorResponse(String requestId, List<Error> errors) {
}
public record Error(String message, String type) {
}
}