From e56aefd09896949829a0682d7c20594605fee86b Mon Sep 17 00:00:00 2001 From: mar-v-in Date: Thu, 26 Feb 2015 23:59:37 +0100 Subject: [PATCH] Extending checkin --- src/org/microg/gms/checkin/CheckinClient.java | 4 +- .../microg/gms/checkin/CheckinManager.java | 52 +++++++++++++++++++ .../microg/gms/checkin/CheckinService.java | 46 ++++++++++++++++ .../microg/gms/checkin/LastCheckinInfo.java | 28 ++++++++++ src/org/microg/gms/gservices/GServices.java | 43 ++++++++++++++- 5 files changed, 169 insertions(+), 4 deletions(-) create mode 100644 src/org/microg/gms/checkin/CheckinManager.java create mode 100644 src/org/microg/gms/checkin/CheckinService.java diff --git a/src/org/microg/gms/checkin/CheckinClient.java b/src/org/microg/gms/checkin/CheckinClient.java index b40f52e9..70e86733 100644 --- a/src/org/microg/gms/checkin/CheckinClient.java +++ b/src/org/microg/gms/checkin/CheckinClient.java @@ -35,7 +35,7 @@ import java.util.List; public class CheckinClient { private static final String TAG = "GmsCheckinClient"; - private static final Object TODO = null; + private static final Object TODO = null; // TODO private static final String SERVICE_URL = "https://android.clients.google.com/checkin"; public static CheckinResponse request(CheckinRequest request) throws IOException { @@ -146,7 +146,7 @@ public class CheckinClient { } - private static CheckinRequest makeRequest(Build build, DeviceConfiguration deviceConfiguration, + public static CheckinRequest makeRequest(Build build, DeviceConfiguration deviceConfiguration, DeviceIdentifier deviceIdent, PhoneInfo phoneInfo, LastCheckinInfo checkinInfo) { return makeRequest(makeCheckin(makeBuild(build), phoneInfo, checkinInfo), diff --git a/src/org/microg/gms/checkin/CheckinManager.java b/src/org/microg/gms/checkin/CheckinManager.java new file mode 100644 index 00000000..bf6c70fd --- /dev/null +++ b/src/org/microg/gms/checkin/CheckinManager.java @@ -0,0 +1,52 @@ +/* + * 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.checkin; + +import android.content.ContentResolver; +import android.content.Context; + +import org.microg.gms.common.Utils; +import org.microg.gms.gservices.GServices; + +import java.io.IOException; + +public class CheckinManager { + private static final long MIN_CHECKIN_INTERVAL = 3 * 60 * 60 * 1000; // 3 hours + + public static synchronized LastCheckinInfo checkin(Context context) throws IOException { + LastCheckinInfo info = LastCheckinInfo.read(context); + if (info.lastCheckin > System.currentTimeMillis() - MIN_CHECKIN_INTERVAL) return null; + CheckinRequest request = CheckinClient.makeRequest(Utils.getBuild(context), null, null, null, info); + return handleResponse(context, CheckinClient.request(request)); + } + + private static LastCheckinInfo handleResponse(Context context, CheckinResponse response) { + LastCheckinInfo info = new LastCheckinInfo(); + info.androidId = response.androidId; + info.lastCheckin = response.timeMs; + info.securityToken = response.securityToken; + info.digest = response.digest; + info.write(context); + + ContentResolver resolver = context.getContentResolver(); + for (CheckinResponse.GservicesSetting setting : response.setting) { + GServices.setString(resolver, setting.name.utf8(), setting.value.utf8()); + } + + return info; + } +} diff --git a/src/org/microg/gms/checkin/CheckinService.java b/src/org/microg/gms/checkin/CheckinService.java new file mode 100644 index 00000000..95d17d34 --- /dev/null +++ b/src/org/microg/gms/checkin/CheckinService.java @@ -0,0 +1,46 @@ +/* + * 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.checkin; + +import android.app.IntentService; +import android.content.Intent; +import android.util.Log; + +import java.io.IOException; + +public class CheckinService extends IntentService { + private static final String TAG = "GmsCheckinService"; + public static final String CHECKIN_ACTION = "com.google.android.gsf.checkin.CHECKIN"; + + public CheckinService() { + super(TAG); + } + + @Override + protected void onHandleIntent(Intent intent) { + if (CHECKIN_ACTION.equals(intent.getAction())) { + try { + LastCheckinInfo info = CheckinManager.checkin(this); + if (info != null) { + Log.d(TAG, "Checked in as " + Long.toHexString(info.androidId)); + } + } catch (IOException e) { + Log.w(TAG, e); + } + } + } +} diff --git a/src/org/microg/gms/checkin/LastCheckinInfo.java b/src/org/microg/gms/checkin/LastCheckinInfo.java index a20a7de2..13a58b38 100644 --- a/src/org/microg/gms/checkin/LastCheckinInfo.java +++ b/src/org/microg/gms/checkin/LastCheckinInfo.java @@ -16,8 +16,36 @@ package org.microg.gms.checkin; +import android.content.Context; +import android.content.SharedPreferences; + public class LastCheckinInfo { + public static final String PREFERENCES_NAME = "checkin"; + public static final String PREF_ANDROID_ID = "androidId"; + public static final String PREF_DIGEST = "digest"; + public static final String PREF_LAST_CHECKIN = "lastCheckin"; + public static final String PREF_SECURITY_TOKEN = "securityToken"; public long lastCheckin; public long androidId; public long securityToken; + public String digest; + + public static LastCheckinInfo read(Context context) { + LastCheckinInfo info = new LastCheckinInfo(); + SharedPreferences preferences = context.getSharedPreferences(PREFERENCES_NAME, Context.MODE_PRIVATE); + info.androidId = preferences.getLong(PREF_ANDROID_ID, 0); + info.digest = preferences.getString(PREF_DIGEST, null); + info.lastCheckin = preferences.getLong(PREF_LAST_CHECKIN, 0); + info.securityToken = preferences.getLong(PREF_SECURITY_TOKEN, 0); + return info; + } + + public void write(Context context) { + context.getSharedPreferences(PREFERENCES_NAME, Context.MODE_PRIVATE).edit() + .putLong(PREF_ANDROID_ID, androidId) + .putString(PREF_DIGEST, digest) + .putLong(PREF_LAST_CHECKIN, lastCheckin) + .putLong(PREF_SECURITY_TOKEN, securityToken) + .apply(); + } } diff --git a/src/org/microg/gms/gservices/GServices.java b/src/org/microg/gms/gservices/GServices.java index 0d8a2989..ed5f7355 100644 --- a/src/org/microg/gms/gservices/GServices.java +++ b/src/org/microg/gms/gservices/GServices.java @@ -18,6 +18,7 @@ package org.microg.gms.gservices; import android.content.ContentResolver; import android.content.ContentValues; +import android.database.Cursor; import android.net.Uri; public class GServices { @@ -25,10 +26,48 @@ public class GServices { public static final Uri MAIN_URI = Uri.parse("content://com.google.android.gsf.gservices/main"); public static final Uri OVERRIDE_URI = Uri.parse("content://com.google.android.gsf.gservices/override"); - public static void setString(ContentResolver resolver, String key, String value) { + public static int setString(ContentResolver resolver, String key, String value) { ContentValues values = new ContentValues(); values.put("name", key); values.put("value", value); - resolver.update(MAIN_URI, values, null, null); + return resolver.update(MAIN_URI, values, null, null); + } + + public static String getString(ContentResolver resolver, String key) { + return getString(resolver, key, null); + } + + public static String getString(ContentResolver resolver, String key, String defaultValue) { + String result = defaultValue; + Cursor cursor = resolver.query(CONTENT_URI, null, null, new String[]{key}, null); + if (cursor != null) { + if (cursor.moveToNext()) { + result = cursor.getString(1); + } + cursor.close(); + } + return result; + } + + public static int getInt(ContentResolver resolver, String key, int defaultValue) { + String result = getString(resolver, key); + if (result != null) { + try { + return Integer.parseInt(result); + } catch (NumberFormatException ignored) { + } + } + return defaultValue; + } + + public static long getLong(ContentResolver resolver, String key, long defaultValue) { + String result = getString(resolver, key); + if (result != null) { + try { + return Long.parseLong(result); + } catch (NumberFormatException ignored) { + } + } + return defaultValue; } }