diff --git a/build.gradle b/build.gradle index 92339b13f2..09ce866bfe 100644 --- a/build.gradle +++ b/build.gradle @@ -15,6 +15,7 @@ buildscript { ext.biometricVersion = '1.1.0' ext.coreVersion = '1.12.0' ext.fragmentVersion = '1.6.2' + ext.gsonVersion = '2.10.1' ext.lifecycleVersion = '2.7.0' ext.loaderVersion = '1.1.0' ext.materialVersion = '1.11.0' diff --git a/play-services-core/build.gradle b/play-services-core/build.gradle index a2bdcd4a8d..1642b050da 100644 --- a/play-services-core/build.gradle +++ b/play-services-core/build.gradle @@ -79,6 +79,9 @@ dependencies { implementation "androidx.preference:preference-ktx:$preferenceVersion" implementation "androidx.webkit:webkit:$webkitVersion" + // Gson + implementation "com.google.code.gson:gson:$gsonVersion" + // Material Components implementation "com.google.android.material:material:$materialVersion" diff --git a/play-services-core/src/main/java/org/microg/gms/checkin/CheckinManager.java b/play-services-core/src/main/java/org/microg/gms/checkin/CheckinManager.java index 1604ed2565..32b5af968a 100644 --- a/play-services-core/src/main/java/org/microg/gms/checkin/CheckinManager.java +++ b/play-services-core/src/main/java/org/microg/gms/checkin/CheckinManager.java @@ -20,6 +20,12 @@ import android.accounts.AccountManager; import android.content.ContentResolver; import android.content.Context; +import android.content.SharedPreferences; + +import androidx.annotation.Nullable; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; import org.microg.gms.auth.AuthConstants; import org.microg.gms.auth.AuthRequest; @@ -33,6 +39,10 @@ import java.util.List; public class CheckinManager { + + private static final String LAST_CHECK_IN_DATA = "LAST_CHECK_IN_DATA"; + private static final String CHECK_IN_PREF = "check_in"; + private static final long MIN_CHECKIN_INTERVAL = 3 * 60 * 60 * 1000; // 3 hours @SuppressWarnings("MissingPermission") @@ -42,7 +52,20 @@ public static synchronized LastCheckinInfo checkin(Context context, boolean forc return null; if (!CheckinPreferences.isEnabled(context)) return null; - List accounts = new ArrayList(); + CheckinRequest checkinRequest = getCheckinRequest(context, info); + saveLastCheckInRequest(context, checkinRequest); + return handleResponse(context, CheckinClient.request(checkinRequest)); + } + + @Nullable + public static String getLastRawCheckInRequest(Context context) { + String rawCheckInRequest = getCheckInSharedPreferences(context) + .getString(LAST_CHECK_IN_DATA, ""); + return !rawCheckInRequest.isEmpty() ? rawCheckInRequest : null; + } + + private static CheckinRequest getCheckinRequest(Context context, LastCheckinInfo info) throws IOException { + List accounts = new ArrayList<>(); AccountManager accountManager = AccountManager.get(context); String accountType = AuthConstants.DEFAULT_ACCOUNT_TYPE; for (Account account : accountManager.getAccountsByType(accountType)) { @@ -55,10 +78,9 @@ public static synchronized LastCheckinInfo checkin(Context context, boolean forc accounts.add(new CheckinClient.Account(account.name, token)); } } - CheckinRequest request = CheckinClient.makeRequest(context, + return CheckinClient.makeRequest(context, new DeviceConfiguration(context), Utils.getDeviceIdentifier(context), Utils.getPhoneInfo(context), info, Utils.getLocale(context), accounts); - return handleResponse(context, CheckinClient.request(request)); } private static LastCheckinInfo handleResponse(Context context, CheckinResponse response) { @@ -72,4 +94,20 @@ private static LastCheckinInfo handleResponse(Context context, CheckinResponse r return info; } + + private static void saveLastCheckInRequest(Context context, CheckinRequest checkinRequest) { + getCheckInSharedPreferences(context).edit() + .putString(LAST_CHECK_IN_DATA, getGsonInstance().toJson(checkinRequest)) + .apply(); + } + + private static SharedPreferences getCheckInSharedPreferences(Context context) { + return context.getSharedPreferences(CHECK_IN_PREF, Context.MODE_PRIVATE); + } + + private static Gson getGsonInstance() { + return new GsonBuilder() + .setPrettyPrinting() + .create(); + } } diff --git a/play-services-core/src/main/kotlin/org/microg/gms/ui/DeviceRegistrationFragment.kt b/play-services-core/src/main/kotlin/org/microg/gms/ui/DeviceRegistrationFragment.kt index b7d7e9c8ad..4e38dcc9bf 100644 --- a/play-services-core/src/main/kotlin/org/microg/gms/ui/DeviceRegistrationFragment.kt +++ b/play-services-core/src/main/kotlin/org/microg/gms/ui/DeviceRegistrationFragment.kt @@ -19,6 +19,8 @@ import androidx.preference.Preference import androidx.preference.PreferenceCategory import androidx.preference.PreferenceFragmentCompat import com.google.android.gms.R +import com.google.android.material.dialog.MaterialAlertDialogBuilder +import org.microg.gms.checkin.CheckinManager import org.microg.gms.checkin.CheckinPreferences import org.microg.gms.checkin.getCheckinServiceInfo import org.microg.gms.profile.ProfileManager @@ -94,6 +96,17 @@ class DeviceRegistrationFragment : PreferenceFragmentCompat() { CheckinPreferences.setEnabled(requireContext(), newStatus) true } + + findPreference("pref_device_registration_data")?.setOnPreferenceClickListener { + val rawCheckInRequest = CheckinManager.getLastRawCheckInRequest(context) + MaterialAlertDialogBuilder(it.context) + .setTitle(R.string.pref_device_registration_data_title) + .setMessage(rawCheckInRequest ?: getString(R.string.data_na)) + .setPositiveButton(android.R.string.ok) { dialog, _ -> dialog.dismiss() } + .create() + .show() + true + } } private fun configureProfilePreference() { diff --git a/play-services-core/src/main/res/values/strings.xml b/play-services-core/src/main/res/values/strings.xml index bbe47e70a9..7f4847b658 100644 --- a/play-services-core/src/main/res/values/strings.xml +++ b/play-services-core/src/main/res/values/strings.xml @@ -116,6 +116,7 @@ This can take a couple of minutes." Touch here to disable battery optimizations. Not doing this may result in misbehaving applications. + No data available right now About Components @@ -146,6 +147,9 @@ This can take a couple of minutes." Registers your device to Google services and creates a unique device identifier. microG strips identifying bits other than your Google account name from registration data. Android ID + Device registration data + Check data shared with Google servers for device registration + Not registered Last registration: %1$s Register device diff --git a/play-services-core/src/main/res/xml/preferences_device_registration.xml b/play-services-core/src/main/res/xml/preferences_device_registration.xml index b4d290b93b..8ab4140371 100644 --- a/play-services-core/src/main/res/xml/preferences_device_registration.xml +++ b/play-services-core/src/main/res/xml/preferences_device_registration.xml @@ -50,6 +50,11 @@ android:title="@string/pref_device_registration_android_id" tools:summary="1953a59d1c1b7e4b" app:iconSpaceReserved="false" /> +