diff --git a/play-services-core/src/main/java/org/microg/gms/common/HttpFormClient.java b/play-services-core/src/main/java/org/microg/gms/common/HttpFormClient.java index b50aeb714b..31e6bbc6b2 100644 --- a/play-services-core/src/main/java/org/microg/gms/common/HttpFormClient.java +++ b/play-services-core/src/main/java/org/microg/gms/common/HttpFormClient.java @@ -28,6 +28,8 @@ import java.lang.reflect.Field; import java.net.HttpURLConnection; import java.net.URL; +import java.util.List; +import java.util.Map; public class HttpFormClient { private static final String TAG = "GmsHttpFormClient"; @@ -84,7 +86,7 @@ public static T request(String url, Request request, Class tClass) throws String result = new String(Utils.readStreamToEnd(connection.getInputStream())); Log.d(TAG, "-- Response --\n" + result); - return parseResponse(tClass, result); + return parseResponse(tClass, connection.getHeaderFields(), result); } private static String valueFromBoolVal(String value, Boolean boolVal, boolean truePresent, boolean falsePresent) { @@ -101,7 +103,7 @@ private static String valueFromBoolVal(String value, Boolean boolVal, boolean tr } } - private static T parseResponse(Class tClass, String result) { + private static T parseResponse(Class tClass, Map> headerFields, String result) { T response; try { response = tClass.getConstructor().newInstance(); @@ -132,6 +134,26 @@ private static T parseResponse(Class tClass, String result) { Log.w(TAG, e); } } + for (Field field : tClass.getDeclaredFields()) { + if (field.isAnnotationPresent(ResponseHeader.class)) { + List strings = headerFields.get(field.getAnnotation(ResponseHeader.class).value()); + if (strings == null || strings.size() != 1) continue; + String value = strings.get(0); + try { + if (field.getType().equals(String.class)) { + field.set(response, value); + } else if (field.getType().equals(boolean.class)) { + field.setBoolean(response, value.equals("1")); + } else if (field.getType().equals(long.class)) { + field.setLong(response, Long.parseLong(value)); + } else if (field.getType().equals(int.class)) { + field.setInt(response, Integer.parseInt(value)); + } + } catch (Exception e) { + Log.w(TAG, e); + } + } + } return response; } @@ -189,4 +211,10 @@ public interface Callback { public @interface ResponseField { public String value(); } + + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.FIELD) + public @interface ResponseHeader { + public String value(); + } } diff --git a/play-services-core/src/main/java/org/microg/gms/gcm/PushRegisterService.java b/play-services-core/src/main/java/org/microg/gms/gcm/PushRegisterService.java index 7dfa7e84b7..5477bd7d08 100644 --- a/play-services-core/src/main/java/org/microg/gms/gcm/PushRegisterService.java +++ b/play-services-core/src/main/java/org/microg/gms/gcm/PushRegisterService.java @@ -73,13 +73,13 @@ private void register(Intent intent) { Log.d(TAG, "register[req]: " + extras); Intent outIntent = new Intent("com.google.android.c2dm.intent.REGISTRATION"); outIntent.setPackage(app); - String regId = register(this, app, sender, null); + String regId = register(this, app, sender, null, false).token; if (regId != null) { outIntent.putExtra("registration_id", regId); } else { outIntent.putExtra("error", "SERVICE_NOT_AVAILABLE"); } - Log.d(TAG, "register[res]: " + outIntent); + Log.d(TAG, "register[res]: " + outIntent + " extras=" + outIntent.getExtras()); try { if (intent.hasExtra("google.messenger")) { Messenger messenger = intent.getParcelableExtra("google.messenger"); @@ -94,24 +94,60 @@ private void register(Intent intent) { sendOrderedBroadcast(outIntent, null); } - public static String register(Context context, String app, String sender, String info) { + public static RegisterResponse register(Context context, String app, String sender, String info, boolean delete) { try { - return new RegisterRequest() + RegisterResponse response = new RegisterRequest() .build(Utils.getBuild(context)) .sender(sender) .info(info) .checkin(LastCheckinInfo.read(context)) .app(app, PackageUtils.firstSignatureDigest(context, app), PackageUtils.versionCode(context, app)) - .getResponse() - .token; + .delete(delete) + .getResponse(); + Log.d(TAG, "received response: " + response); + return response; } catch (IOException e) { Log.w(TAG, e); } - return null; + return new RegisterResponse(); } private void unregister(Intent intent) { + PendingIntent pendingIntent = intent.getParcelableExtra("app"); + String app = packageFromPendingIntent(pendingIntent); + + Intent outIntent = new Intent("com.google.android.c2dm.intent.REGISTRATION"); + outIntent.setPackage(app); + + RegisterResponse response = register(this, app, null, null, true); + if (!app.equals(response.deleted)) { + outIntent.putExtra("error", "SERVICE_NOT_AVAILABLE"); + + long retry = 0; + if (response.retryAfter != null && !response.retryAfter.contains(":")) { + retry = Long.parseLong(response.retryAfter); + } + + if (retry > 0) { + outIntent.putExtra("Retry-After", retry); + } + } else { + outIntent.putExtra("unregistered", app); + } + Log.d(TAG, "unregister[res]: " + outIntent.toString() + " extras=" + outIntent.getExtras()); + try { + if (intent.hasExtra("google.messenger")) { + Messenger messenger = intent.getParcelableExtra("google.messenger"); + Message message = Message.obtain(); + message.obj = outIntent; + messenger.send(message); + return; + } + } catch (Exception e) { + Log.w(TAG, e); + } + sendOrderedBroadcast(outIntent, null); } } diff --git a/play-services-core/src/main/java/org/microg/gms/gcm/RegisterRequest.java b/play-services-core/src/main/java/org/microg/gms/gcm/RegisterRequest.java index a4265f0984..ed3d0fb0e2 100644 --- a/play-services-core/src/main/java/org/microg/gms/gcm/RegisterRequest.java +++ b/play-services-core/src/main/java/org/microg/gms/gcm/RegisterRequest.java @@ -47,6 +47,8 @@ public class RegisterRequest extends HttpFormClient.Request { public String sender; @RequestContent({"X-GOOG.USER_AID", "device"}) public long androidId; + @RequestContent("delete") + public boolean delete; public long securityToken; public String deviceName; public String buildVersion; @@ -86,6 +88,15 @@ public RegisterRequest build(Build build) { return this; } + public RegisterRequest delete() { + return delete(true); + } + + public RegisterRequest delete(boolean delete) { + this.delete = delete; + return this; + } + public RegisterResponse getResponse() throws IOException { return HttpFormClient.request(SERVICE_URL, this, RegisterResponse.class); } diff --git a/play-services-core/src/main/java/org/microg/gms/gcm/RegisterResponse.java b/play-services-core/src/main/java/org/microg/gms/gcm/RegisterResponse.java index 88afd2ce86..4557b479be 100644 --- a/play-services-core/src/main/java/org/microg/gms/gcm/RegisterResponse.java +++ b/play-services-core/src/main/java/org/microg/gms/gcm/RegisterResponse.java @@ -16,9 +16,24 @@ package org.microg.gms.gcm; +import org.microg.gms.common.HttpFormClient.ResponseHeader; + import static org.microg.gms.common.HttpFormClient.ResponseField; public class RegisterResponse { @ResponseField("token") public String token; + @ResponseHeader("Retry-After") + public String retryAfter; + @ResponseField("deleted") + public String deleted; + + @Override + public String toString() { + return "RegisterResponse{" + + "token='" + token + '\'' + + ", retryAfter='" + retryAfter + '\'' + + ", deleted='" + deleted + '\'' + + '}'; + } }