mirror of
https://github.com/YTVanced/VancedMicroG
synced 2024-11-24 20:25:14 +00:00
Add GCM register API client
Add generic HttpFormClient
This commit is contained in:
parent
d3f7688516
commit
bc532d132c
4 changed files with 293 additions and 0 deletions
152
src/org/microg/gms/common/HttpFormClient.java
Normal file
152
src/org/microg/gms/common/HttpFormClient.java
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013-2015 µg Project Team
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.microg.gms.common;
|
||||||
|
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
public class HttpFormClient {
|
||||||
|
private static final String TAG = "GmsHttpFormClient";
|
||||||
|
|
||||||
|
public static <T> T request(String url, Request request, Class<T> tClass) throws IOException {
|
||||||
|
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
|
||||||
|
connection.setRequestMethod("POST");
|
||||||
|
connection.setDoInput(true);
|
||||||
|
connection.setDoOutput(true);
|
||||||
|
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
|
||||||
|
StringBuilder content = new StringBuilder();
|
||||||
|
request.prepare();
|
||||||
|
for (Field field : request.getClass().getDeclaredFields()) {
|
||||||
|
try {
|
||||||
|
field.setAccessible(true);
|
||||||
|
String value = String.valueOf(field.get(request));
|
||||||
|
if (field.isAnnotationPresent(RequestHeader.class)) {
|
||||||
|
for (String key : field.getAnnotation(RequestHeader.class).value()) {
|
||||||
|
connection.setRequestProperty(key, value);
|
||||||
|
}
|
||||||
|
} else if (field.isAnnotationPresent(RequestContent.class)) {
|
||||||
|
for (String key : field.getAnnotation(RequestHeader.class).value()) {
|
||||||
|
if (content.length() > 0)
|
||||||
|
content.append("&");
|
||||||
|
content.append(Uri.encode(key)).append("=").append(Uri.encode(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.d(TAG, "-- Request --\n" + content);
|
||||||
|
OutputStream os = connection.getOutputStream();
|
||||||
|
os.write(content.toString().getBytes());
|
||||||
|
os.close();
|
||||||
|
|
||||||
|
if (connection.getResponseCode() != 200) {
|
||||||
|
throw new IOException(connection.getResponseMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
String result = new String(Utils.readStreamToEnd(connection.getInputStream()));
|
||||||
|
Log.d(TAG, "-- Response --\n" + result);
|
||||||
|
return parseResponse(tClass, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T> T parseResponse(Class<T> tClass, String result) {
|
||||||
|
T response;
|
||||||
|
try {
|
||||||
|
response = tClass.getConstructor().newInstance();
|
||||||
|
} catch (Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String[] entries = result.split("\n");
|
||||||
|
for (String s : entries) {
|
||||||
|
String[] keyValuePair = s.split("=", 2);
|
||||||
|
String key = keyValuePair[0].trim();
|
||||||
|
String value = keyValuePair[1].trim();
|
||||||
|
try {
|
||||||
|
for (Field field : tClass.getDeclaredFields()) {
|
||||||
|
if (field.isAnnotationPresent(ResponseField.class) &&
|
||||||
|
key.equals(field.getAnnotation(ResponseField.class).value())) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> void requestAsync(final String url, final Request request, final Class<T> tClass,
|
||||||
|
final Callback<T> callback) {
|
||||||
|
new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
callback.onResponse(request(url, request, tClass));
|
||||||
|
} catch (Exception e) {
|
||||||
|
callback.onException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static abstract class Request {
|
||||||
|
protected void prepare() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Callback<T> {
|
||||||
|
void onResponse(T response);
|
||||||
|
|
||||||
|
void onException(Exception exception);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.FIELD)
|
||||||
|
public @interface RequestHeader {
|
||||||
|
public String[] value();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.FIELD)
|
||||||
|
public @interface RequestContent {
|
||||||
|
public String[] value();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.FIELD)
|
||||||
|
public @interface ResponseField {
|
||||||
|
public String value();
|
||||||
|
}
|
||||||
|
}
|
22
src/org/microg/gms/gcm/Constants.java
Normal file
22
src/org/microg/gms/gcm/Constants.java
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013-2015 µg Project Team
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.microg.gms.gcm;
|
||||||
|
|
||||||
|
public class Constants {
|
||||||
|
public static final String REGISTER_URL = "https://android.clients.google.com/c2dm/register3";
|
||||||
|
|
||||||
|
}
|
95
src/org/microg/gms/gcm/RegisterRequest.java
Normal file
95
src/org/microg/gms/gcm/RegisterRequest.java
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013-2015 µg Project Team
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.microg.gms.gcm;
|
||||||
|
|
||||||
|
import org.microg.gms.checkin.LastCheckinInfo;
|
||||||
|
import org.microg.gms.common.Build;
|
||||||
|
import org.microg.gms.common.HttpFormClient;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import static org.microg.gms.common.HttpFormClient.RequestContent;
|
||||||
|
import static org.microg.gms.common.HttpFormClient.RequestHeader;
|
||||||
|
|
||||||
|
public class RegisterRequest extends HttpFormClient.Request {
|
||||||
|
private static final String USER_AGENT = "Android-GCM/1.3 (%s %s)";
|
||||||
|
|
||||||
|
@RequestHeader("Authorization")
|
||||||
|
private String auth;
|
||||||
|
@RequestHeader("User-Agent")
|
||||||
|
private String userAgent;
|
||||||
|
|
||||||
|
@RequestHeader("app")
|
||||||
|
@RequestContent("app")
|
||||||
|
public String app;
|
||||||
|
@RequestContent("cert")
|
||||||
|
public String appSignature;
|
||||||
|
@RequestContent("app_ver")
|
||||||
|
public int appVersion;
|
||||||
|
@RequestContent("info")
|
||||||
|
public String info;
|
||||||
|
@RequestContent("sender")
|
||||||
|
public String sender;
|
||||||
|
@RequestContent({"X-GOOG.USER_AID", "device"})
|
||||||
|
public long androidId;
|
||||||
|
public long securityToken;
|
||||||
|
public String deviceName;
|
||||||
|
public String buildVersion;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void prepare() {
|
||||||
|
userAgent = String.format(USER_AGENT, deviceName, buildVersion);
|
||||||
|
auth = "AidLogin " + androidId + ":" + securityToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RegisterRequest checkin(LastCheckinInfo lastCheckinInfo) {
|
||||||
|
androidId = lastCheckinInfo.androidId;
|
||||||
|
securityToken = lastCheckinInfo.securityToken;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RegisterRequest app(String app, String appSignature, int appVersion) {
|
||||||
|
this.app = app;
|
||||||
|
this.appSignature = appSignature;
|
||||||
|
this.appVersion = appVersion;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RegisterRequest info(String info) {
|
||||||
|
this.info = info;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RegisterRequest sender(String sender) {
|
||||||
|
this.sender = sender;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RegisterRequest build(Build build) {
|
||||||
|
deviceName = build.device;
|
||||||
|
buildVersion = build.id;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RegisterResponse getResponse() throws IOException {
|
||||||
|
return HttpFormClient.request(Constants.REGISTER_URL, this, RegisterResponse.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void getResponseAsync(HttpFormClient.Callback<RegisterResponse> callback) {
|
||||||
|
HttpFormClient.requestAsync(Constants.REGISTER_URL, this, RegisterResponse.class, callback);
|
||||||
|
}
|
||||||
|
}
|
24
src/org/microg/gms/gcm/RegisterResponse.java
Normal file
24
src/org/microg/gms/gcm/RegisterResponse.java
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013-2015 µg Project Team
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.microg.gms.gcm;
|
||||||
|
|
||||||
|
import static org.microg.gms.common.HttpFormClient.ResponseField;
|
||||||
|
|
||||||
|
public class RegisterResponse {
|
||||||
|
@ResponseField("token")
|
||||||
|
public String token;
|
||||||
|
}
|
Loading…
Reference in a new issue