From 501866bb7d930cf6397ecb1576df4bf70108b648 Mon Sep 17 00:00:00 2001 From: mar-v-in Date: Sun, 4 Oct 2015 17:53:52 +0200 Subject: [PATCH] Add support for push notification unregistering --- .../org/microg/gms/common/HttpFormClient.java | 32 +++++++++++- .../microg/gms/gcm/PushRegisterService.java | 50 ++++++++++++++++--- .../org/microg/gms/gcm/RegisterRequest.java | 11 ++++ .../org/microg/gms/gcm/RegisterResponse.java | 15 ++++++ 4 files changed, 99 insertions(+), 9 deletions(-) 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 b50aeb71..31e6bbc6 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.annotation.Target; 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 class HttpFormClient { 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 @@ public class HttpFormClient { } } - 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 @@ public class HttpFormClient { 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 class HttpFormClient { 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 7dfa7e84..5477bd7d 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 @@ public class PushRegisterService extends IntentService { 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 @@ public class PushRegisterService extends IntentService { 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 a4265f09..ed3d0fb0 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 class RegisterRequest extends HttpFormClient.Request { 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 88afd2ce..4557b479 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 + '\'' + + '}'; + } }