0
0
Fork 0
mirror of https://github.com/YTVanced/VancedMicroG synced 2024-11-30 23:23:01 +00:00

Fix HttpFormClient, migrate AuthClient to HttpFormClient

This commit is contained in:
mar-v-in 2015-02-22 18:57:08 +01:00
parent bc532d132c
commit 84c0f2b6a0
7 changed files with 113 additions and 227 deletions

View file

@ -1,84 +0,0 @@
/*
* 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.auth;
import android.net.Uri;
import android.util.Log;
import org.microg.gms.common.Utils;
import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;
public class AuthClient {
private static final String TAG = "GmsAuthClient";
private static final String SERVICE_URL = "https://android.clients.google.com/auth";
public static AuthResponse request(AuthRequest request) throws IOException {
HttpURLConnection connection = (HttpURLConnection) new URL(SERVICE_URL).openConnection();
connection.setRequestMethod("POST");
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
Map<String, String> httpHeaders = request.getHttpHeaders();
for (String key : httpHeaders.keySet()) {
connection.setRequestProperty(key, httpHeaders.get(key));
}
StringBuilder content = new StringBuilder();
Map<String, String> formContent = request.getFormContent();
for (String key : formContent.keySet()) {
if (content.length() > 0)
content.append("&");
content.append(Uri.encode(key)).append("=").append(Uri.encode(formContent.get(key)));
}
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 AuthResponse.parse(result);
}
public static void request(final AuthRequest request, final GmsAuthCallback callback) {
new Thread(new Runnable() {
@Override
public void run() {
try {
callback.onResponse(request(request));
} catch (Exception e) {
callback.onException(e);
}
}
}).start();
}
public static interface GmsAuthCallback {
void onResponse(AuthResponse response);
void onException(Exception exception);
}
}

View file

@ -20,110 +20,74 @@ import android.content.Context;
import org.microg.gms.common.Build; import org.microg.gms.common.Build;
import org.microg.gms.common.Constants; import org.microg.gms.common.Constants;
import org.microg.gms.common.HttpFormClient;
import org.microg.gms.common.Utils; import org.microg.gms.common.Utils;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap;
import java.util.Locale; import java.util.Locale;
import java.util.Map;
public class AuthRequest { import static org.microg.gms.common.HttpFormClient.RequestContent;
import static org.microg.gms.common.HttpFormClient.RequestHeader;
public class AuthRequest extends HttpFormClient.Request {
private static final String SERVICE_URL = "https://android.clients.google.com/auth";
private static final String USER_AGENT = "GoogleAuth/1.4 (%s %s)"; private static final String USER_AGENT = "GoogleAuth/1.4 (%s %s)";
@RequestHeader("User-Agent")
private String userAgent;
@RequestHeader("app")
@RequestContent("app")
public String app; public String app;
@RequestContent("client_sig")
public String appSignature; public String appSignature;
@RequestContent("callerPkg")
public String caller; public String caller;
@RequestContent("callerSig")
public String callerSignature; public String callerSignature;
@RequestHeader(value = "device", nullPresent = true)
@RequestContent(value = "androidId", nullPresent = true)
public String androidIdHex; public String androidIdHex;
@RequestContent("sdk_version")
public int sdkVersion;
@RequestContent("device_country")
public String countryCode;
@RequestContent("operatorCountry")
public String operatorCountryCode;
@RequestContent("lang")
public String locale;
@RequestContent("google_play_services_version")
public int gmsVersion = Constants.MAX_REFERENCE_VERSION;
@RequestContent("accountType")
public String accountType = "HOSTED_OR_GOOGLE";
@RequestContent("Email")
public String email;
@RequestContent("service")
public String service;
@RequestContent("source")
public String source = "android";
@RequestContent({"is_called_from_account_manager", "_opt_is_called_from_account_manager"})
public boolean isCalledFromAccountManager;
@RequestContent("Token")
public String token;
@RequestContent("system_partition")
public boolean systemPartition;
@RequestContent("get_accountid")
public boolean getAccountId;
@RequestContent("ACCESS_TOKEN")
public boolean isAccessToken;
@RequestContent("droidguard_results")
public String droidguardResults;
@RequestContent("has_permission")
public boolean hasPermission;
@RequestContent("add_account")
public boolean addAccount;
public String deviceName; public String deviceName;
public String buildVersion; public String buildVersion;
public int sdkVersion;
public String countryCode;
public String operatorCountryCode;
public String locale;
public int gmsVersion = Constants.MAX_REFERENCE_VERSION;
public String accountType = "HOSTED_OR_GOOGLE";
public String email;
public String service;
public String source = "android";
public boolean isCalledFromAccountManager;
public String token;
public boolean systemPartition;
public boolean getAccountId;
public boolean isAccessToken;
public String droidguardResults;
public boolean hasPermission;
public boolean addAccount;
public AuthRequest() { @Override
protected void prepare() {
} userAgent = String.format(USER_AGENT, deviceName, buildVersion);
@Deprecated
public AuthRequest(Context context, String token) {
this(Utils.getLocale(context), Utils.getBuild(context), Utils.getAndroidIdHex(context), token);
}
@Deprecated
public AuthRequest(Locale locale, Build build, String androidIdHex, String token) {
this(locale, build.sdk, Constants.MAX_REFERENCE_VERSION, build.device, build.id, androidIdHex, token);
}
@Deprecated
public AuthRequest(Locale locale, int sdkVersion, int gmsVersion, String deviceName,
String buildVersion, String androidIdHex, String token) {
this.androidIdHex = androidIdHex;
this.deviceName = deviceName;
this.buildVersion = buildVersion;
this.countryCode = locale.getCountry();
this.gmsVersion = gmsVersion;
this.operatorCountryCode = locale.getCountry();
this.locale = locale.toString();
this.sdkVersion = sdkVersion;
this.token = token;
}
public Map<String, String> getHttpHeaders() {
Map<String, String> map = new HashMap<>();
map.put("app", app);
map.put("device", androidIdHex);
map.put("User-Agent", String.format(USER_AGENT, deviceName, buildVersion));
map.put("Content-Type", "application/x-www-form-urlencoded");
return map;
}
public Map<String, String> getFormContent() {
Map<String, String> map = new HashMap<>();
map.put("device_country", countryCode);
map.put("operatorCountry", operatorCountryCode);
map.put("lang", locale);
map.put("sdk_version", Integer.toString(sdkVersion));
map.put("google_play_services_version", Integer.toString(gmsVersion));
map.put("accountType", accountType);
if (systemPartition) map.put("system_partition", "1");
if (hasPermission) map.put("has_permission", "1");
if (addAccount) map.put("add_account", "1");
if (email != null) map.put("Email", email);
map.put("service", service);
map.put("source", source);
map.put("androidId", androidIdHex);
if (getAccountId) map.put("get_accountid", "1");
map.put("app", app);
map.put("client_sig", appSignature);
if (caller != null) {
map.put("callerPkg", caller);
map.put("callerSig", callerSignature);
}
if (isCalledFromAccountManager) {
map.put("is_called_from_account_manager", "1");
map.put("_opt_is_called_from_account_manager", "1");
}
if (isAccessToken) map.put("ACCESS_TOKEN", "1");
map.put("Token", token);
if (droidguardResults != null) map.put("droidguard_results", droidguardResults);
return map;
} }
public AuthRequest build(Build build) { public AuthRequest build(Build build) {
@ -222,10 +186,10 @@ public class AuthRequest {
} }
public AuthResponse getResponse() throws IOException { public AuthResponse getResponse() throws IOException {
return AuthClient.request(this); return HttpFormClient.request(SERVICE_URL, this, AuthResponse.class);
} }
public void getResponseAsync(AuthClient.GmsAuthCallback callback) { public void getResponseAsync(HttpFormClient.Callback<AuthResponse> callback) {
AuthClient.request(this, callback); HttpFormClient.requestAsync(SERVICE_URL, this, AuthResponse.class, callback);
} }
} }

View file

@ -18,14 +18,9 @@ package org.microg.gms.auth;
import android.util.Log; import android.util.Log;
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.lang.reflect.Field;
import java.util.Arrays;
import java.util.HashSet; import static org.microg.gms.common.HttpFormClient.ResponseField;
import java.util.Set;
public class AuthResponse { public class AuthResponse {
private static final String TAG = "GmsAuthResponse"; private static final String TAG = "GmsAuthResponse";
@ -91,12 +86,4 @@ public class AuthResponse {
} }
return response; return response;
} }
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
private @interface ResponseField {
public String value();
}
} }

View file

@ -37,11 +37,11 @@ import android.widget.RelativeLayout;
import com.google.android.gms.R; import com.google.android.gms.R;
import org.microg.gms.auth.AuthClient;
import org.microg.gms.auth.AuthManager; import org.microg.gms.auth.AuthManager;
import org.microg.gms.auth.AuthRequest; import org.microg.gms.auth.AuthRequest;
import org.microg.gms.auth.AuthResponse; import org.microg.gms.auth.AuthResponse;
import org.microg.gms.common.Constants; import org.microg.gms.common.Constants;
import org.microg.gms.common.HttpFormClient;
import org.microg.gms.common.Utils; import org.microg.gms.common.Utils;
import org.microg.gms.userinfo.ProfileManager; import org.microg.gms.userinfo.ProfileManager;
@ -161,7 +161,7 @@ public class LoginActivity extends AssistantActivity {
.systemPartition() .systemPartition()
.hasPermission() .hasPermission()
.droidguardResults(null /*TODO*/) .droidguardResults(null /*TODO*/)
.getResponseAsync(new AuthClient.GmsAuthCallback() { .getResponseAsync(new HttpFormClient.Callback<AuthResponse>() {
@Override @Override
public void onResponse(AuthResponse response) { public void onResponse(AuthResponse response) {
AccountManager accountManager = AccountManager.get(LoginActivity.this); AccountManager accountManager = AccountManager.get(LoginActivity.this);
@ -202,7 +202,7 @@ public class LoginActivity extends AssistantActivity {
.hasPermission() .hasPermission()
.addAccount() .addAccount()
.getAccountId() .getAccountId()
.getResponseAsync(new AuthClient.GmsAuthCallback() { .getResponseAsync(new HttpFormClient.Callback<AuthResponse>() {
@Override @Override
public void onResponse(AuthResponse response) { public void onResponse(AuthResponse response) {
AuthManager.storeResponse(LoginActivity.this, account, AuthManager.storeResponse(LoginActivity.this, account,
@ -220,7 +220,7 @@ public class LoginActivity extends AssistantActivity {
private void retrieveGmsKeyUserinfoProfile(final Account account) { private void retrieveGmsKeyUserinfoProfile(final Account account) {
ProfileManager.getAuthKeyRequest(this, account) ProfileManager.getAuthKeyRequest(this, account)
.getResponseAsync(new AuthClient.GmsAuthCallback() { .getResponseAsync(new HttpFormClient.Callback<AuthResponse>() {
@Override @Override
public void onResponse(AuthResponse response) { public void onResponse(AuthResponse response) {
AuthManager.storeResponse(LoginActivity.this, account, AuthManager.storeResponse(LoginActivity.this, account,

View file

@ -43,16 +43,30 @@ public class HttpFormClient {
for (Field field : request.getClass().getDeclaredFields()) { for (Field field : request.getClass().getDeclaredFields()) {
try { try {
field.setAccessible(true); field.setAccessible(true);
String value = String.valueOf(field.get(request)); Object objVal = field.get(request);
if (field.isAnnotationPresent(RequestHeader.class)) { String value = objVal != null ? String.valueOf(objVal) : null;
for (String key : field.getAnnotation(RequestHeader.class).value()) { Boolean boolVal = null;
connection.setRequestProperty(key, value); if (field.getType().equals(boolean.class)) {
boolVal = field.getBoolean(request);
} }
} else if (field.isAnnotationPresent(RequestContent.class)) { if (field.isAnnotationPresent(RequestHeader.class)) {
for (String key : field.getAnnotation(RequestHeader.class).value()) { RequestHeader annotation = field.getAnnotation(RequestHeader.class);
value = valueFromBoolVal(value, boolVal, annotation.truePresent(), annotation.falsePresent());
if (value != null || annotation.nullPresent()) {
for (String key : annotation.value()) {
connection.setRequestProperty(key, String.valueOf(value));
}
}
}
if (field.isAnnotationPresent(RequestContent.class)) {
RequestContent annotation = field.getAnnotation(RequestContent.class);
value = valueFromBoolVal(value, boolVal, annotation.truePresent(), annotation.falsePresent());
if (value != null || annotation.nullPresent()) {
for (String key : annotation.value()) {
if (content.length() > 0) if (content.length() > 0)
content.append("&"); content.append("&");
content.append(Uri.encode(key)).append("=").append(Uri.encode(value)); content.append(Uri.encode(key)).append("=").append(Uri.encode(String.valueOf(value)));
}
} }
} }
} catch (Exception ignored) { } catch (Exception ignored) {
@ -73,6 +87,20 @@ public class HttpFormClient {
return parseResponse(tClass, result); return parseResponse(tClass, result);
} }
private static String valueFromBoolVal(String value, Boolean boolVal, boolean truePresent, boolean falsePresent) {
if (boolVal != null) {
if (boolVal && truePresent) {
return "1";
} else if (!boolVal && falsePresent) {
return "0";
} else {
return null;
}
} else {
return value;
}
}
private static <T> T parseResponse(Class<T> tClass, String result) { private static <T> T parseResponse(Class<T> tClass, String result) {
T response; T response;
try { try {
@ -136,12 +164,24 @@ public class HttpFormClient {
@Target(ElementType.FIELD) @Target(ElementType.FIELD)
public @interface RequestHeader { public @interface RequestHeader {
public String[] value(); public String[] value();
public boolean truePresent() default true;
public boolean falsePresent() default false;
public boolean nullPresent() default false;
} }
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD) @Target(ElementType.FIELD)
public @interface RequestContent { public @interface RequestContent {
public String[] value(); public String[] value();
public boolean truePresent() default true;
public boolean falsePresent() default false;
public boolean nullPresent() default false;
} }
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)

View file

@ -1,22 +0,0 @@
/*
* 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";
}

View file

@ -26,6 +26,7 @@ import static org.microg.gms.common.HttpFormClient.RequestContent;
import static org.microg.gms.common.HttpFormClient.RequestHeader; import static org.microg.gms.common.HttpFormClient.RequestHeader;
public class RegisterRequest extends HttpFormClient.Request { 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.3 (%s %s)";
@RequestHeader("Authorization") @RequestHeader("Authorization")
@ -86,10 +87,10 @@ public class RegisterRequest extends HttpFormClient.Request {
} }
public RegisterResponse getResponse() throws IOException { public RegisterResponse getResponse() throws IOException {
return HttpFormClient.request(Constants.REGISTER_URL, this, RegisterResponse.class); return HttpFormClient.request(SERVICE_URL, this, RegisterResponse.class);
} }
public void getResponseAsync(HttpFormClient.Callback<RegisterResponse> callback) { public void getResponseAsync(HttpFormClient.Callback<RegisterResponse> callback) {
HttpFormClient.requestAsync(Constants.REGISTER_URL, this, RegisterResponse.class, callback); HttpFormClient.requestAsync(SERVICE_URL, this, RegisterResponse.class, callback);
} }
} }