Add support for push notification unregistering

This commit is contained in:
mar-v-in 2015-10-04 17:53:52 +02:00
parent 575b0230ab
commit 501866bb7d
4 changed files with 99 additions and 9 deletions

View File

@ -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> T parseResponse(Class<T> tClass, String result) {
private static <T> T parseResponse(Class<T> tClass, Map<String, List<String>> 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<String> 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();
}
}

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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 + '\'' +
'}';
}
}