mirror of
https://github.com/whyorean/AuroraStore.git
synced 2026-06-16 03:31:02 -04:00
Token dispenser extracted to play-store-api, wrapper builder introduced
This commit is contained in:
@@ -24,6 +24,6 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile 'com.github.yeriomin:play-store-api:7c9171e'
|
||||
compile 'com.github.yeriomin:play-store-api:73a06ec'
|
||||
compile 'eu.chainfire:libsuperuser:1.0.0.201608240809'
|
||||
}
|
||||
|
||||
@@ -61,8 +61,7 @@ public class AccountTypeDialogBuilder extends CredentialsDialogBuilder {
|
||||
@Override
|
||||
protected Throwable doInBackground(String[] params) {
|
||||
try {
|
||||
PlayStoreApiWrapper wrapper = new PlayStoreApiWrapper(context);
|
||||
wrapper.login(params[0]);
|
||||
new PlayStoreApiAuthenticator(context).login(params[0]);
|
||||
} catch (Throwable e) {
|
||||
return e;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.github.yeriomin.playstoreapi.AuthException;
|
||||
import com.github.yeriomin.playstoreapi.TokenDispenserException;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ abstract class GoogleApiAsyncTask extends AsyncTask<String, Void, Throwable> {
|
||||
Log.w(getClass().getName(), "Credentials empty");
|
||||
} else {
|
||||
toast(this.context, R.string.error_incorrect_password);
|
||||
new PlayStoreApiWrapper(this.context).forceTokenRefresh();
|
||||
new PlayStoreApiAuthenticator(context).logout();
|
||||
}
|
||||
AccountTypeDialogBuilder builder = new AccountTypeDialogBuilder(this.context);
|
||||
builder.setTaskClone(this.taskClone);
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
package com.github.yeriomin.yalpstore;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
|
||||
import com.github.yeriomin.playstoreapi.ApiBuilderException;
|
||||
import com.github.yeriomin.playstoreapi.GooglePlayAPI;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
|
||||
public class PlayStoreApiAuthenticator {
|
||||
|
||||
private Context context;
|
||||
|
||||
private static GooglePlayAPI api;
|
||||
|
||||
public PlayStoreApiAuthenticator(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public GooglePlayAPI getApi() throws IOException {
|
||||
if (api == null) {
|
||||
api = build();
|
||||
}
|
||||
return api;
|
||||
}
|
||||
|
||||
public void login(String email) throws IOException {
|
||||
build(email);
|
||||
}
|
||||
|
||||
public void login(String email, String password) throws IOException {
|
||||
build(email, password);
|
||||
}
|
||||
|
||||
public void logout() {
|
||||
SharedPreferences.Editor prefs = PreferenceManager.getDefaultSharedPreferences(context).edit();
|
||||
prefs.remove(PreferenceActivity.PREFERENCE_EMAIL);
|
||||
prefs.remove(PreferenceActivity.PREFERENCE_AUTH_TOKEN);
|
||||
prefs.apply();
|
||||
api = null;
|
||||
}
|
||||
|
||||
private GooglePlayAPI build() throws IOException {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
String email = prefs.getString(PreferenceActivity.PREFERENCE_EMAIL, "");
|
||||
return build(email);
|
||||
}
|
||||
|
||||
private GooglePlayAPI build(String email) throws IOException {
|
||||
return build(email, null);
|
||||
}
|
||||
|
||||
private GooglePlayAPI build(String email, String password) throws IOException {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
String gsfId = prefs.getString(PreferenceActivity.PREFERENCE_GSF_ID, "");
|
||||
String token = prefs.getString(PreferenceActivity.PREFERENCE_AUTH_TOKEN, "");
|
||||
if (email.isEmpty()) {
|
||||
throw new CredentialsEmptyException();
|
||||
}
|
||||
|
||||
NativeDeviceInfoProvider deviceInfoProvider = new NativeDeviceInfoProvider();
|
||||
deviceInfoProvider.setContext(context);
|
||||
deviceInfoProvider.setLocaleString(Locale.getDefault().toString());
|
||||
com.github.yeriomin.playstoreapi.PlayStoreApiBuilder builder = new com.github.yeriomin.playstoreapi.PlayStoreApiBuilder()
|
||||
.setDeviceInfoProvider(deviceInfoProvider)
|
||||
.setEmail(email)
|
||||
;
|
||||
if (null != password) {
|
||||
builder.setPassword(password);
|
||||
}
|
||||
if (!gsfId.isEmpty()) {
|
||||
builder.setGsfId(gsfId);
|
||||
}
|
||||
if (!token.isEmpty()) {
|
||||
builder.setToken(token);
|
||||
}
|
||||
try {
|
||||
api = builder.build();
|
||||
} catch (ApiBuilderException e) {
|
||||
// Should not happen
|
||||
}
|
||||
|
||||
SharedPreferences.Editor prefsEditor = prefs.edit();
|
||||
prefsEditor.putString(PreferenceActivity.PREFERENCE_EMAIL, email);
|
||||
prefsEditor.putString(PreferenceActivity.PREFERENCE_GSF_ID, gsfId);
|
||||
prefsEditor.putString(PreferenceActivity.PREFERENCE_AUTH_TOKEN, token);
|
||||
prefsEditor.apply();
|
||||
return api;
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,6 @@ import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@@ -42,64 +41,10 @@ public class PlayStoreApiWrapper {
|
||||
private static final String BACKEND_DOCID_SIMILAR_APPS = "similar_apps";
|
||||
private static final String BACKEND_DOCID_USERS_ALSO_INSTALLED = "users_also_installed";
|
||||
|
||||
private Context context;
|
||||
private String email;
|
||||
private String password;
|
||||
|
||||
private static GooglePlayAPI api;
|
||||
private static AppSearchResultIterator searchResultIterator;
|
||||
private static CategoryAppsIterator categoryAppsIterator;
|
||||
|
||||
private GooglePlayAPI getApi() throws IOException {
|
||||
if (api == null) {
|
||||
api = buildApi();
|
||||
}
|
||||
return api;
|
||||
}
|
||||
|
||||
private GooglePlayAPI constructApi() throws IOException {
|
||||
NativeDeviceInfoProvider deviceInfoProvider = new NativeDeviceInfoProvider();
|
||||
deviceInfoProvider.setContext(context);
|
||||
deviceInfoProvider.setLocaleString(Locale.getDefault().toString());
|
||||
GooglePlayAPI api = new GooglePlayAPI(email);
|
||||
api.setDeviceInfoProvider(deviceInfoProvider);
|
||||
api.setLocale(Locale.getDefault());
|
||||
return api;
|
||||
}
|
||||
|
||||
private GooglePlayAPI buildApi() throws IOException {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
String email = this.email == null ? prefs.getString(PreferenceActivity.PREFERENCE_EMAIL, "") : this.email;
|
||||
String gsfId = prefs.getString(PreferenceActivity.PREFERENCE_GSF_ID, "");
|
||||
String token = prefs.getString(PreferenceActivity.PREFERENCE_AUTH_TOKEN, "");
|
||||
if (email.isEmpty()) {
|
||||
throw new CredentialsEmptyException();
|
||||
}
|
||||
|
||||
GooglePlayAPI api = constructApi();
|
||||
|
||||
SharedPreferences.Editor prefsEditor = prefs.edit();
|
||||
boolean needToUploadDeviceConfig = false;
|
||||
if (gsfId.isEmpty()) {
|
||||
needToUploadDeviceConfig = true;
|
||||
String ac2dmToken = null == password ? TokenDispenser.getTokenAc2dm(email) : api.getAC2DMToken(password);
|
||||
gsfId = api.getGsfId(ac2dmToken);
|
||||
prefsEditor.putString(PreferenceActivity.PREFERENCE_GSF_ID, gsfId);
|
||||
prefsEditor.apply();
|
||||
}
|
||||
api.setGsfId(gsfId);
|
||||
if (token.isEmpty()) {
|
||||
token = null == password ? TokenDispenser.getToken(email) : api.getToken(password);
|
||||
prefsEditor.putString(PreferenceActivity.PREFERENCE_EMAIL, email);
|
||||
prefsEditor.putString(PreferenceActivity.PREFERENCE_AUTH_TOKEN, token);
|
||||
prefsEditor.apply();
|
||||
}
|
||||
api.setToken(token);
|
||||
if (needToUploadDeviceConfig) {
|
||||
api.uploadDeviceConfig();
|
||||
}
|
||||
return api;
|
||||
}
|
||||
private Context context;
|
||||
|
||||
public PlayStoreApiWrapper(Context context) {
|
||||
this.context = context;
|
||||
@@ -107,39 +52,9 @@ public class PlayStoreApiWrapper {
|
||||
AppBuilder.suffixBil = context.getString(R.string.suffix_billion);
|
||||
}
|
||||
|
||||
public GooglePlayAPI login(String email) throws IOException {
|
||||
this.email = email;
|
||||
PlayStoreApiWrapper.api = null;
|
||||
return getApi();
|
||||
}
|
||||
|
||||
public GooglePlayAPI login(String email, String password) throws IOException {
|
||||
this.password = password;
|
||||
return login(email);
|
||||
}
|
||||
|
||||
public void logout() {
|
||||
this.email = null;
|
||||
this.password = null;
|
||||
SharedPreferences.Editor prefs = PreferenceManager.getDefaultSharedPreferences(context).edit();
|
||||
prefs.remove(PreferenceActivity.PREFERENCE_EMAIL);
|
||||
prefs.remove(PreferenceActivity.PREFERENCE_GSF_ID);
|
||||
prefs.remove(PreferenceActivity.PREFERENCE_AUTH_TOKEN);
|
||||
prefs.apply();
|
||||
PlayStoreApiWrapper.api = null;
|
||||
}
|
||||
|
||||
public void forceTokenRefresh() {
|
||||
this.password = null;
|
||||
SharedPreferences.Editor prefs = PreferenceManager.getDefaultSharedPreferences(context).edit();
|
||||
prefs.remove(PreferenceActivity.PREFERENCE_AUTH_TOKEN);
|
||||
prefs.apply();
|
||||
PlayStoreApiWrapper.api = null;
|
||||
}
|
||||
|
||||
public List<Review> getReviews(String packageId, int offset, int numberOfResults) throws IOException {
|
||||
List<Review> reviews = new ArrayList<>();
|
||||
for (com.github.yeriomin.playstoreapi.Review review: getApi().reviews(
|
||||
for (com.github.yeriomin.playstoreapi.Review review: new PlayStoreApiAuthenticator(context).getApi().reviews(
|
||||
packageId,
|
||||
GooglePlayAPI.REVIEW_SORT.HELPFUL,
|
||||
offset,
|
||||
@@ -151,7 +66,7 @@ public class PlayStoreApiWrapper {
|
||||
}
|
||||
|
||||
public Review addOrEditReview(String packageId, Review inputReview) throws IOException {
|
||||
ReviewResponse response = getApi().addOrEditReview(
|
||||
ReviewResponse response = new PlayStoreApiAuthenticator(context).getApi().addOrEditReview(
|
||||
packageId,
|
||||
inputReview.getComment(),
|
||||
inputReview.getTitle(),
|
||||
@@ -161,11 +76,11 @@ public class PlayStoreApiWrapper {
|
||||
}
|
||||
|
||||
public void deleteReview(String packageId) throws IOException {
|
||||
getApi().deleteReview(packageId);
|
||||
new PlayStoreApiAuthenticator(context).getApi().deleteReview(packageId);
|
||||
}
|
||||
|
||||
public App getDetails(String packageId) throws IOException {
|
||||
DetailsResponse response = getApi().details(packageId);
|
||||
DetailsResponse response = new PlayStoreApiAuthenticator(context).getApi().details(packageId);
|
||||
App app = AppBuilder.build(response.getDocV2());
|
||||
if (response.hasUserReview()) {
|
||||
app.setUserReview(ReviewBuilder.build(response.getUserReview()));
|
||||
@@ -192,7 +107,7 @@ public class PlayStoreApiWrapper {
|
||||
List<App> apps = new ArrayList<>();
|
||||
int i = -1;
|
||||
boolean hideNonFree = hideNonFree();
|
||||
for (BulkDetailsEntry details: getApi().bulkDetails(packageIds).getEntryList()) {
|
||||
for (BulkDetailsEntry details: new PlayStoreApiAuthenticator(context).getApi().bulkDetails(packageIds).getEntryList()) {
|
||||
i++;
|
||||
if (!details.hasDoc()) {
|
||||
Log.i(this.getClass().getName(), "Empty response for " + packageIds.get(i));
|
||||
@@ -222,7 +137,7 @@ public class PlayStoreApiWrapper {
|
||||
|| !searchResultIterator.getQuery().equals(query)
|
||||
|| !searchResultIterator.getCategoryId().equals(categoryId)
|
||||
) {
|
||||
searchResultIterator = new AppSearchResultIterator(new SearchIterator(getApi(), query));
|
||||
searchResultIterator = new AppSearchResultIterator(new SearchIterator(new PlayStoreApiAuthenticator(context).getApi(), query));
|
||||
searchResultIterator.setHideNonfreeApps(hideNonFree());
|
||||
searchResultIterator.setCategoryId(categoryId);
|
||||
}
|
||||
@@ -235,7 +150,7 @@ public class PlayStoreApiWrapper {
|
||||
) {
|
||||
categoryAppsIterator = new CategoryAppsIterator(
|
||||
new com.github.yeriomin.playstoreapi.CategoryAppsIterator(
|
||||
getApi(),
|
||||
new PlayStoreApiAuthenticator(context).getApi(),
|
||||
categoryId,
|
||||
GooglePlayAPI.SUBCATEGORY.TOP_FREE
|
||||
)
|
||||
@@ -246,18 +161,18 @@ public class PlayStoreApiWrapper {
|
||||
|
||||
public List<String> getSearchSuggestions(String query) throws IOException {
|
||||
List<String> suggestions = new ArrayList<>();
|
||||
for (SearchSuggestEntry suggestion: api.searchSuggest(query).getEntryList()) {
|
||||
for (SearchSuggestEntry suggestion: new PlayStoreApiAuthenticator(context).getApi().searchSuggest(query).getEntryList()) {
|
||||
suggestions.add(suggestion.getSuggestedQuery());
|
||||
}
|
||||
return suggestions;
|
||||
}
|
||||
|
||||
public Map<String, String> getCategories() throws IOException {
|
||||
return buildCategoryMap(getApi().categories());
|
||||
return buildCategoryMap(new PlayStoreApiAuthenticator(context).getApi().categories());
|
||||
}
|
||||
|
||||
public Map<String, String> getCategories(String category) throws IOException {
|
||||
return buildCategoryMap(getApi().categories(category));
|
||||
return buildCategoryMap(new PlayStoreApiAuthenticator(context).getApi().categories(category));
|
||||
}
|
||||
|
||||
private Map<String, String> buildCategoryMap(BrowseResponse response) {
|
||||
@@ -274,12 +189,13 @@ public class PlayStoreApiWrapper {
|
||||
|
||||
public AndroidAppDeliveryData purchaseOrDeliver(App app) throws IOException, NotPurchasedException {
|
||||
if (app.isFree()) {
|
||||
return getApi()
|
||||
return new PlayStoreApiAuthenticator(context).getApi()
|
||||
.purchase(app.getPackageName(), app.getVersionCode(), app.getOfferType())
|
||||
.getPurchaseStatusResponse()
|
||||
.getAppDeliveryData();
|
||||
}
|
||||
DeliveryResponse response = getApi().delivery(app.getPackageName(), app.getVersionCode(), app.getOfferType());
|
||||
DeliveryResponse response = new PlayStoreApiAuthenticator(context).getApi().delivery(
|
||||
app.getPackageName(), app.getVersionCode(), app.getOfferType());
|
||||
if (response.hasAppDeliveryData()) {
|
||||
return response.getAppDeliveryData();
|
||||
} else {
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
package com.github.yeriomin.yalpstore;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.github.yeriomin.playstoreapi.AuthException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
|
||||
public class TokenDispenser {
|
||||
|
||||
static private final String DISPENSER_URL = "http://tokendispenser-yeriomin.rhcloud.com/";
|
||||
|
||||
static private final String RESOURCE_TOKEN = "token";
|
||||
static private final String RESOURCE_TOKEN_AC2DM = "token-ac2dm";
|
||||
|
||||
static private final String PARAMETER_EMAIL = "email";
|
||||
|
||||
static public String getToken(String email) throws IOException {
|
||||
return request(getUrl(email, RESOURCE_TOKEN));
|
||||
}
|
||||
|
||||
static public String getTokenAc2dm(String email) throws IOException {
|
||||
return request(getUrl(email, RESOURCE_TOKEN_AC2DM));
|
||||
}
|
||||
|
||||
static private HttpUrl getUrl(String email, String path) {
|
||||
HttpUrl.Builder urlBuilder = HttpUrl.parse(DISPENSER_URL).newBuilder();
|
||||
urlBuilder.addPathSegment(path);
|
||||
urlBuilder.addPathSegment(PARAMETER_EMAIL);
|
||||
urlBuilder.addPathSegment(email);
|
||||
return urlBuilder.build();
|
||||
}
|
||||
|
||||
static private String request(HttpUrl url) throws IOException {
|
||||
Log.i(TokenDispenser.class.getName(), "Requesting " + url.toString());
|
||||
Request.Builder requestBuilder = new Request.Builder();
|
||||
Request request = requestBuilder.url(url).build();
|
||||
OkHttpClient.Builder builder = new OkHttpClient.Builder();
|
||||
OkHttpClient client = builder
|
||||
.connectTimeout(1, TimeUnit.MINUTES)
|
||||
.readTimeout(1, TimeUnit.MINUTES)
|
||||
.writeTimeout(1, TimeUnit.MINUTES)
|
||||
.build();
|
||||
Response response;
|
||||
try {
|
||||
response = client.newCall(request).execute();
|
||||
} catch (Throwable e) {
|
||||
throw new TokenDispenserException(e);
|
||||
}
|
||||
int code = response.code();
|
||||
if (code == 401 || code == 403) {
|
||||
throw new AuthException("TokenDispenser failed to get a token");
|
||||
} else if (code >= 400) {
|
||||
throw new TokenDispenserException("Error " + code);
|
||||
}
|
||||
return new String(response.body().bytes());
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
package com.github.yeriomin.yalpstore;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class TokenDispenserException extends IOException {
|
||||
|
||||
public TokenDispenserException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public TokenDispenserException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
@@ -82,13 +82,12 @@ public class UserProvidedAccountDialogBuilder extends CredentialsDialogBuilder {
|
||||
|| params[1] == null
|
||||
|| params[0].isEmpty()
|
||||
|| params[1].isEmpty()
|
||||
) {
|
||||
) {
|
||||
return new CredentialsEmptyException();
|
||||
}
|
||||
previousEmail = params[0];
|
||||
try {
|
||||
PlayStoreApiWrapper wrapper = new PlayStoreApiWrapper(this.context);
|
||||
wrapper.login(params[0], params[1]);
|
||||
new PlayStoreApiAuthenticator(context).login(params[0], params[1]);
|
||||
} catch (Throwable e) {
|
||||
return e;
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ public abstract class YalpStoreActivity extends Activity {
|
||||
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
new PlayStoreApiWrapper(getApplicationContext()).logout();
|
||||
new PlayStoreApiAuthenticator(getApplicationContext()).logout();
|
||||
dialogInterface.dismiss();
|
||||
finishAll();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user