diff --git a/play-services-base-core/src/main/java/org/microg/gms/common/HttpFormClient.java b/play-services-base-core/src/main/java/org/microg/gms/common/HttpFormClient.java index 73115992..8aee1df7 100644 --- a/play-services-base-core/src/main/java/org/microg/gms/common/HttpFormClient.java +++ b/play-services-base-core/src/main/java/org/microg/gms/common/HttpFormClient.java @@ -46,6 +46,13 @@ public class HttpFormClient { try { field.setAccessible(true); Object objVal = field.get(request); + if (field.isAnnotationPresent(RequestContentDynamic.class)) { + Map contentParams = (Map) objVal; + for (Map.Entry param : contentParams.entrySet()) { + appendParam(content, param.getKey(), param.getValue()); + } + continue; + } String value = objVal != null ? String.valueOf(objVal) : null; Boolean boolVal = null; if (field.getType().equals(boolean.class)) { @@ -65,9 +72,7 @@ public class HttpFormClient { value = valueFromBoolVal(value, boolVal, annotation.truePresent(), annotation.falsePresent()); if (value != null || annotation.nullPresent()) { for (String key : annotation.value()) { - if (content.length() > 0) - content.append("&"); - content.append(Uri.encode(key)).append("=").append(Uri.encode(String.valueOf(value))); + appendParam(content, key, value); } } } @@ -109,6 +114,12 @@ public class HttpFormClient { } } + private static void appendParam(StringBuilder content, String key, String value) { + if (content.length() > 0) + content.append("&"); + content.append(Uri.encode(key)).append("=").append(Uri.encode(String.valueOf(value))); + } + private static T parseResponse(Class tClass, HttpURLConnection connection, String result) throws IOException { Map> headerFields = connection.getHeaderFields(); T response; @@ -227,6 +238,11 @@ public class HttpFormClient { public boolean nullPresent() default false; } + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.FIELD) + public @interface RequestContentDynamic { + } + @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface ResponseField { diff --git a/play-services-base-core/src/main/java/org/microg/gms/common/PackageUtils.java b/play-services-base-core/src/main/java/org/microg/gms/common/PackageUtils.java index 8cb7c0eb..9f1f2cc8 100644 --- a/play-services-base-core/src/main/java/org/microg/gms/common/PackageUtils.java +++ b/play-services-base-core/src/main/java/org/microg/gms/common/PackageUtils.java @@ -264,4 +264,12 @@ public class PackageUtils { return null; } } + + public static int targetSdkVersion(Context context, String packageName) { + try { + return context.getPackageManager().getApplicationInfo(packageName, 0).targetSdkVersion; + } catch (PackageManager.NameNotFoundException e) { + return -1; + } + } } diff --git a/play-services-core/src/main/java/org/microg/gms/gcm/PushRegisterHandler.java b/play-services-core/src/main/java/org/microg/gms/gcm/PushRegisterHandler.java index f161533c..e95c98f0 100644 --- a/play-services-core/src/main/java/org/microg/gms/gcm/PushRegisterHandler.java +++ b/play-services-core/src/main/java/org/microg/gms/gcm/PushRegisterHandler.java @@ -145,7 +145,7 @@ class PushRegisterHandler extends Handler { .checkin(LastCheckinInfo.read(context)) .app(packageName) .delete(delete) - .appid(subdata.getString("appid"), subdata.getString("gmp_app_id")), + .extraParams(subdata), bundle -> sendReply(what, id, replyTo, bundle)); } } diff --git a/play-services-core/src/main/java/org/microg/gms/gcm/PushRegisterManager.java b/play-services-core/src/main/java/org/microg/gms/gcm/PushRegisterManager.java index 7ae7d648..b3ffca9e 100644 --- a/play-services-core/src/main/java/org/microg/gms/gcm/PushRegisterManager.java +++ b/play-services-core/src/main/java/org/microg/gms/gcm/PushRegisterManager.java @@ -70,12 +70,16 @@ public class PushRegisterManager { public static void completeRegisterRequest(Context context, GcmDatabase database, String requestId, RegisterRequest request, BundleCallback callback) { if (request.app != null) { - if (request.appSignature == null) - request.appSignature = PackageUtils.firstSignatureDigest(context, request.app); if (request.appVersion <= 0) request.appVersion = PackageUtils.versionCode(context, request.app); - if (request.appVersionName == null) - request.appVersionName = PackageUtils.versionName(context, request.app); + if (!request.delete) { + if (request.appSignature == null) { + request.appSignature = PackageUtils.firstSignatureDigest(context, request.app); + } + request.sdkVersion = PackageUtils.targetSdkVersion(context, request.app); + if (!request.hasExtraParam(GcmConstants.EXTRA_APP_VERSION_NAME)) + request.extraParam(GcmConstants.EXTRA_APP_VERSION_NAME, PackageUtils.versionName(context, request.app)); + } } GcmDatabase.App app = database.getApp(request.app); 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 21bdd21e..96024409 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 @@ -20,7 +20,6 @@ import android.app.IntentService; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; -import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.os.IBinder; import android.os.Message; @@ -140,7 +139,8 @@ public class PushRegisterService extends IntentService { .build(Utils.getBuild(context)) .sender(intent.getStringExtra(EXTRA_SENDER)) .checkin(LastCheckinInfo.read(context)) - .app(packageName), + .app(packageName) + .extraParams(intent.getExtras()), bundle -> { Intent outIntent = new Intent(ACTION_C2DM_REGISTRATION); outIntent.putExtras(bundle); @@ -176,7 +176,8 @@ public class PushRegisterService extends IntentService { .build(Utils.getBuild(this)) .sender(intent.getStringExtra(EXTRA_SENDER)) .checkin(LastCheckinInfo.read(this)) - .app(packageName), + .app(packageName) + .extraParams(intent.getExtras()), bundle -> { Intent outIntent = new Intent(ACTION_C2DM_REGISTRATION); outIntent.putExtras(bundle); 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 6e0d7871..e4cfb851 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 @@ -16,19 +16,24 @@ package org.microg.gms.gcm; +import android.os.Bundle; +import android.text.TextUtils; + import org.microg.gms.checkin.LastCheckinInfo; import org.microg.gms.common.Build; -import org.microg.gms.common.Constants; import org.microg.gms.common.HttpFormClient; import java.io.IOException; +import java.util.LinkedHashMap; +import java.util.Map; import static org.microg.gms.common.HttpFormClient.RequestContent; +import static org.microg.gms.common.HttpFormClient.RequestContentDynamic; import static org.microg.gms.common.HttpFormClient.RequestHeader; public class RegisterRequest extends HttpFormClient.Request { private static final String SERVICE_URL = "https://android.clients.google.com/c2dm/register3"; - private static final String USER_AGENT = "Android-GCM/1.3 (%s %s)"; + private static final String USER_AGENT = "Android-GCM/1.5 (%s %s)"; @RequestHeader("Authorization") private String auth; @@ -42,35 +47,26 @@ public class RegisterRequest extends HttpFormClient.Request { public String appSignature; @RequestContent("app_ver") public int appVersion; - @RequestContent("app_ver_name") - public String appVersionName; @RequestContent("info") public String info; - @RequestContent({"sender", "subtype"}) + @RequestContent("sender") public String sender; - @RequestContent({"X-GOOG.USER_AID", "device"}) + @RequestContent("device") public long androidId; @RequestContent("delete") public boolean delete; public long securityToken; public String deviceName; public String buildVersion; - @RequestContent("osv") - public int sdkVersion; - @RequestContent("gmsv") - public int gmsVersion; - @RequestContent("scope") - public String scope = "*"; - @RequestContent("appid") - public String appId; - @RequestContent("gmp_app_id") - public String gmpAppId; + @RequestContent("target_ver") + public Integer sdkVersion; + @RequestContentDynamic + private Map extraParams = new LinkedHashMap<>(); @Override public void prepare() { userAgent = String.format(USER_AGENT, deviceName, buildVersion); auth = "AidLogin " + androidId + ":" + securityToken; - gmsVersion = Constants.MAX_REFERENCE_VERSION; } public RegisterRequest checkin(LastCheckinInfo lastCheckinInfo) { @@ -90,17 +86,10 @@ public class RegisterRequest extends HttpFormClient.Request { return this; } - public RegisterRequest app(String app, String appSignature, int appVersion, String appVersionName) { + public RegisterRequest app(String app, String appSignature, int appVersion) { this.app = app; this.appSignature = appSignature; this.appVersion = appVersion; - this.appVersionName = appVersionName; - return this; - } - - public RegisterRequest appid(String appid, String gmpAppId) { - this.appId = appid; - this.gmpAppId = gmpAppId; return this; } @@ -117,7 +106,6 @@ public class RegisterRequest extends HttpFormClient.Request { public RegisterRequest build(Build build) { deviceName = build.device; buildVersion = build.id; - sdkVersion = build.sdk; return this; } @@ -130,6 +118,31 @@ public class RegisterRequest extends HttpFormClient.Request { return this; } + public RegisterRequest extraParams(Bundle extraBundle) { + for (String key : extraBundle.keySet()) { + if (!key.equals(GcmConstants.EXTRA_SENDER) && !key.equals(GcmConstants.EXTRA_DELETE)) { + extraParam(key, extraBundle.getString(key)); + } + } + return this; + } + + public RegisterRequest extraParam(String key, String value) { + // Ignore empty registration extras + if (!TextUtils.isEmpty(value)) { + extraParams.put(extraParamKey(key), value); + } + return this; + } + + public boolean hasExtraParam(String key) { + return extraParams.containsKey(extraParamKey(key)); + } + + private static String extraParamKey(String key) { + return "X-" + key; + } + public RegisterResponse getResponse() throws IOException { return HttpFormClient.request(SERVICE_URL, this, RegisterResponse.class); }