From 396965f4077a916ec0d42e8c4f1acdc9b174bd28 Mon Sep 17 00:00:00 2001 From: Marvin W Date: Sun, 26 Jul 2020 11:59:27 +0200 Subject: [PATCH] Major changes to core and settings ui --- .../gms/common/ForegroundServiceContext.java | 2 +- play-services-core/build.gradle | 5 + .../ui/SwitchBarResourceSettingsFragment.java | 14 +- .../src/main/res/drawable/self_check.xml | 13 +- .../src/main/AndroidManifest.xml | 62 ++--- .../microg/gms/checkin/CheckinManager.java | 4 +- .../org/microg/gms/checkin/CheckinPrefs.java | 47 ++++ .../microg/gms/checkin/CheckinService.java | 4 +- .../microg/gms/checkin/TriggerReceiver.java | 3 +- .../gms/snet/SafetyNetClientServiceImpl.java | 1 + .../org/microg/gms/ui/CheckinFragment.java | 60 ----- .../microg/gms/ui/GcmAdvancedFragment.java | 11 - .../org/microg/gms/ui/GcmAppFragment.java | 224 ---------------- .../java/org/microg/gms/ui/GcmFragment.java | 240 ------------------ .../org/microg/gms/ui/SafetyNetFragment.java | 82 ------ .../org/microg/gms/ui/SettingsActivity.java | 114 ++------- .../gms/ui/SettingsDashboardActivity.java | 39 +++ .../org/microg/gms/ui/SettingsFragment.java | 97 +++++++ .../gms/ui/UnifiedBackendDetailsActivity.java | 18 -- .../gms/ui/UnifiedBackendListActivity.java | 32 --- .../org/microg/gms/ui/AppIconPreference.kt | 24 ++ .../gms/ui/DeviceRegistrationFragment.kt | 45 ++++ .../DeviceRegistrationPreferencesFragment.kt | 57 +++++ .../org/microg/gms/ui/PreferenceSwitchBar.kt | 10 + .../gms/ui/PushNotificationAllAppsFragment.kt | 115 +++++++++ .../gms/ui/PushNotificationAppFragment.kt | 58 +++++ .../PushNotificationAppPreferencesFragment.kt | 134 ++++++++++ .../microg/gms/ui/PushNotificationFragment.kt | 72 ++++++ .../ui/PushNotificationPreferencesFragment.kt | 121 +++++++++ .../org/microg/gms/ui/SafetyNetFragment.kt | 61 +++++ .../gms/ui/SafetyNetPreferencesFragment.kt | 17 ++ .../main/res/drawable-hdpi/ic_map_marker.png | Bin 1171 -> 0 bytes .../main/res/drawable-ldpi/add_account.png | Bin 169 -> 0 bytes .../main/res/drawable-mdpi/add_account.png | Bin 195 -> 0 bytes .../main/res/drawable-mdpi/ic_map_marker.png | Bin 791 -> 0 bytes .../main/res/drawable-xhdpi/add_account.png | Bin 328 -> 0 bytes .../main/res/drawable-xhdpi/ic_map_marker.png | Bin 1587 -> 0 bytes .../main/res/drawable-xxhdpi/add_account.png | Bin 428 -> 0 bytes .../res/drawable-xxhdpi/ic_map_marker.png | Bin 2388 -> 0 bytes .../main/res/drawable-xxxhdpi/add_account.png | Bin 586 -> 0 bytes .../res/drawable-xxxhdpi/ic_map_marker.png | Bin 3228 -> 0 bytes .../src/main/res/drawable/dots_horizontal.xml | 11 +- .../ic_add_account.xml} | 3 +- .../{certificate.xml => ic_certificate.xml} | 11 +- .../{gcm_bell.xml => ic_cloud_bell.xml} | 13 +- .../{device_login.xml => ic_device_login.xml} | 13 +- .../src/main/res/drawable/ic_expand_apps.xml | 19 ++ .../src/main/res/drawable/ic_info_outline.xml | 17 ++ .../src/main/res/drawable/ic_map_marker.xml | 17 ++ .../src/main/res/layout/ask_gcm.xml | 2 +- .../layout/device_registration_fragment.xml | 41 +++ .../layout/preference_category_no_label.xml | 9 + .../res/layout/preference_progress_bar.xml | 17 ++ .../main/res/layout/preference_switch_bar.xml | 73 ++++++ .../layout/push_notification_app_fragment.xml | 82 ++++++ .../res/layout/push_notification_fragment.xml | 45 ++++ .../main/res/layout/safety_net_fragment.xml | 45 ++++ .../res/layout/settings_root_activity.xml | 19 ++ .../src/main/res/navigation/nav_settings.xml | 152 +++++++++++ .../src/main/res/values/strings.xml | 2 + .../src/main/res/xml/preferences_checkin.xml | 22 -- .../xml/preferences_device_registration.xml | 24 ++ .../res/xml/preferences_gcm_app_detail.xml | 35 --- .../xml/preferences_push_notifications.xml | 40 +++ ...references_push_notifications_all_apps.xml | 39 +++ .../preferences_push_notifications_app.xml | 43 ++++ ...ces_snet.xml => preferences_safetynet.xml} | 16 +- .../src/main/res/xml/preferences_start.xml | 80 +++--- 68 files changed, 1712 insertions(+), 964 deletions(-) create mode 100644 play-services-core/src/main/java/org/microg/gms/checkin/CheckinPrefs.java delete mode 100644 play-services-core/src/main/java/org/microg/gms/ui/CheckinFragment.java delete mode 100644 play-services-core/src/main/java/org/microg/gms/ui/GcmAppFragment.java delete mode 100644 play-services-core/src/main/java/org/microg/gms/ui/GcmFragment.java delete mode 100644 play-services-core/src/main/java/org/microg/gms/ui/SafetyNetFragment.java create mode 100644 play-services-core/src/main/java/org/microg/gms/ui/SettingsDashboardActivity.java create mode 100644 play-services-core/src/main/java/org/microg/gms/ui/SettingsFragment.java delete mode 100644 play-services-core/src/main/java/org/microg/gms/ui/UnifiedBackendDetailsActivity.java delete mode 100644 play-services-core/src/main/java/org/microg/gms/ui/UnifiedBackendListActivity.java create mode 100644 play-services-core/src/main/kotlin/org/microg/gms/ui/AppIconPreference.kt create mode 100644 play-services-core/src/main/kotlin/org/microg/gms/ui/DeviceRegistrationFragment.kt create mode 100644 play-services-core/src/main/kotlin/org/microg/gms/ui/DeviceRegistrationPreferencesFragment.kt create mode 100644 play-services-core/src/main/kotlin/org/microg/gms/ui/PreferenceSwitchBar.kt create mode 100644 play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationAllAppsFragment.kt create mode 100644 play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationAppFragment.kt create mode 100644 play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationAppPreferencesFragment.kt create mode 100644 play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationFragment.kt create mode 100644 play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationPreferencesFragment.kt create mode 100644 play-services-core/src/main/kotlin/org/microg/gms/ui/SafetyNetFragment.kt create mode 100644 play-services-core/src/main/kotlin/org/microg/gms/ui/SafetyNetPreferencesFragment.kt delete mode 100644 play-services-core/src/main/res/drawable-hdpi/ic_map_marker.png delete mode 100644 play-services-core/src/main/res/drawable-ldpi/add_account.png delete mode 100644 play-services-core/src/main/res/drawable-mdpi/add_account.png delete mode 100644 play-services-core/src/main/res/drawable-mdpi/ic_map_marker.png delete mode 100644 play-services-core/src/main/res/drawable-xhdpi/add_account.png delete mode 100644 play-services-core/src/main/res/drawable-xhdpi/ic_map_marker.png delete mode 100644 play-services-core/src/main/res/drawable-xxhdpi/add_account.png delete mode 100644 play-services-core/src/main/res/drawable-xxhdpi/ic_map_marker.png delete mode 100644 play-services-core/src/main/res/drawable-xxxhdpi/add_account.png delete mode 100644 play-services-core/src/main/res/drawable-xxxhdpi/ic_map_marker.png rename play-services-core/src/main/res/{drawable-anydpi-v21/add_account.xml => drawable/ic_add_account.xml} (92%) rename play-services-core/src/main/res/drawable/{certificate.xml => ic_certificate.xml} (71%) rename play-services-core/src/main/res/drawable/{gcm_bell.xml => ic_cloud_bell.xml} (79%) rename play-services-core/src/main/res/drawable/{device_login.xml => ic_device_login.xml} (58%) create mode 100644 play-services-core/src/main/res/drawable/ic_expand_apps.xml create mode 100644 play-services-core/src/main/res/drawable/ic_info_outline.xml create mode 100644 play-services-core/src/main/res/drawable/ic_map_marker.xml create mode 100644 play-services-core/src/main/res/layout/device_registration_fragment.xml create mode 100644 play-services-core/src/main/res/layout/preference_category_no_label.xml create mode 100644 play-services-core/src/main/res/layout/preference_progress_bar.xml create mode 100644 play-services-core/src/main/res/layout/preference_switch_bar.xml create mode 100644 play-services-core/src/main/res/layout/push_notification_app_fragment.xml create mode 100644 play-services-core/src/main/res/layout/push_notification_fragment.xml create mode 100644 play-services-core/src/main/res/layout/safety_net_fragment.xml create mode 100644 play-services-core/src/main/res/layout/settings_root_activity.xml create mode 100644 play-services-core/src/main/res/navigation/nav_settings.xml delete mode 100644 play-services-core/src/main/res/xml/preferences_checkin.xml create mode 100644 play-services-core/src/main/res/xml/preferences_device_registration.xml delete mode 100644 play-services-core/src/main/res/xml/preferences_gcm_app_detail.xml create mode 100644 play-services-core/src/main/res/xml/preferences_push_notifications.xml create mode 100644 play-services-core/src/main/res/xml/preferences_push_notifications_all_apps.xml create mode 100644 play-services-core/src/main/res/xml/preferences_push_notifications_app.xml rename play-services-core/src/main/res/xml/{preferences_snet.xml => preferences_safetynet.xml} (70%) diff --git a/play-services-base-core/src/main/java/org/microg/gms/common/ForegroundServiceContext.java b/play-services-base-core/src/main/java/org/microg/gms/common/ForegroundServiceContext.java index 50c3445f..3c2a7dbe 100644 --- a/play-services-base-core/src/main/java/org/microg/gms/common/ForegroundServiceContext.java +++ b/play-services-base-core/src/main/java/org/microg/gms/common/ForegroundServiceContext.java @@ -73,7 +73,7 @@ public class ForegroundServiceContext extends ContextWrapper { return new Notification.Builder(context, channel.getId()) .setOngoing(true) .setContentTitle("Running in background") - //.setSmallIcon(R.drawable.gcm_bell) + //.setSmallIcon(R.drawable.ic_cloud_bell) .build(); } } diff --git a/play-services-core/build.gradle b/play-services-core/build.gradle index b55d79ef..8ee555cb 100644 --- a/play-services-core/build.gradle +++ b/play-services-core/build.gradle @@ -15,6 +15,8 @@ */ apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' +apply plugin: 'kotlin-android-extensions' configurations { mapboxImplementation @@ -58,6 +60,8 @@ dependencies { implementation "androidx.navigation:navigation-ui:$navigationVersion" implementation "androidx.navigation:navigation-fragment-ktx:$navigationVersion" implementation "androidx.navigation:navigation-ui-ktx:$navigationVersion" + + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion" } android { @@ -87,6 +91,7 @@ android { sourceSets { main { java.srcDirs += 'src/main/protos-java' + java.srcDirs += 'src/main/kotlin' } } diff --git a/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/SwitchBarResourceSettingsFragment.java b/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/SwitchBarResourceSettingsFragment.java index 950ac8b2..b2b33e3b 100644 --- a/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/SwitchBarResourceSettingsFragment.java +++ b/play-services-core/microg-ui-tools/src/main/java/org/microg/tools/ui/SwitchBarResourceSettingsFragment.java @@ -29,24 +29,22 @@ public abstract class SwitchBarResourceSettingsFragment extends ResourceSettings public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); - AbstractSettingsActivity activity = (AbstractSettingsActivity) getActivity(); - - switchBar = activity.getSwitchBar(); - switchBar.show(); - switchCompat = switchBar.getSwitch(); +// switchBar = activity.getSwitchBar(); +// switchBar.show(); +// switchCompat = switchBar.getSwitch(); } @Override public void onDestroyView() { super.onDestroyView(); - switchBar.hide(); +// switchBar.hide(); } @Override public void onResume() { super.onResume(); if (!listenerSetup) { - switchBar.addOnSwitchChangeListener(this); +// switchBar.addOnSwitchChangeListener(this); listenerSetup = true; } } @@ -54,7 +52,7 @@ public abstract class SwitchBarResourceSettingsFragment extends ResourceSettings @Override public void onPause() { if (listenerSetup) { - switchBar.removeOnSwitchChangeListener(this); +// switchBar.removeOnSwitchChangeListener(this); listenerSetup = false; } super.onPause(); diff --git a/play-services-core/microg-ui-tools/src/main/res/drawable/self_check.xml b/play-services-core/microg-ui-tools/src/main/res/drawable/self_check.xml index 92b47890..714b5e11 100644 --- a/play-services-core/microg-ui-tools/src/main/res/drawable/self_check.xml +++ b/play-services-core/microg-ui-tools/src/main/res/drawable/self_check.xml @@ -16,12 +16,13 @@ --> + android:width="24dp" + android:height="24dp" + android:tint="?attr/colorAccent" + android:viewportWidth="24" + android:viewportHeight="24"> - \ No newline at end of file + diff --git a/play-services-core/src/main/AndroidManifest.xml b/play-services-core/src/main/AndroidManifest.xml index e6dee201..6b58afd7 100644 --- a/play-services-core/src/main/AndroidManifest.xml +++ b/play-services-core/src/main/AndroidManifest.xml @@ -106,15 +106,15 @@ android:allowBackup="false" android:extractNativeLibs="false" android:icon="@mipmap/ic_core_service_app" - android:label="@string/gms_app_name"> + android:label="@string/gms_app_name" + android:theme="@style/Theme.AppCompat.DayNight"> - + + @@ -410,8 +411,7 @@ android:name="org.microg.gms.ui.SettingsActivity" android:icon="@mipmap/ic_microg_settings" android:label="@string/gms_settings_name" - android:roundIcon="@mipmap/ic_microg_settings" - android:theme="@style/Theme.AppCompat.DayNight"> + android:roundIcon="@mipmap/ic_microg_settings"> @@ -423,13 +423,18 @@ + + + android:targetActivity="org.microg.gms.ui.SettingsActivity"> @@ -452,52 +457,25 @@ - - - - - - - - + android:label="@string/pref_about_title" /> + android:label="@string/gms_settings_name" /> + android:label="@string/service_name_snet" /> + android:label="@string/service_name_snet" /> + android:label="@string/self_check_title" /> - + @@ -507,9 +485,7 @@ - + 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 4b67bdd5..631db813 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 @@ -33,8 +33,6 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; -import static org.microg.gms.checkin.TriggerReceiver.PREF_ENABLE_CHECKIN; - public class CheckinManager { private static final long MIN_CHECKIN_INTERVAL = 3 * 60 * 60 * 1000; // 3 hours @@ -43,7 +41,7 @@ public class CheckinManager { LastCheckinInfo info = LastCheckinInfo.read(context); if (!force && info.lastCheckin > System.currentTimeMillis() - MIN_CHECKIN_INTERVAL) return null; - if (!PreferenceManager.getDefaultSharedPreferences(context).getBoolean(PREF_ENABLE_CHECKIN, false)) + if (!CheckinPrefs.get(context).isEnabled()) return null; List accounts = new ArrayList(); AccountManager accountManager = AccountManager.get(context); diff --git a/play-services-core/src/main/java/org/microg/gms/checkin/CheckinPrefs.java b/play-services-core/src/main/java/org/microg/gms/checkin/CheckinPrefs.java new file mode 100644 index 00000000..d18914b6 --- /dev/null +++ b/play-services-core/src/main/java/org/microg/gms/checkin/CheckinPrefs.java @@ -0,0 +1,47 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.checkin; + +import android.content.Context; +import android.content.SharedPreferences; +import android.preference.PreferenceManager; + +public class CheckinPrefs implements SharedPreferences.OnSharedPreferenceChangeListener { + public static final String PREF_ENABLE_CHECKIN = "checkin_enable_service"; + private static CheckinPrefs INSTANCE; + + public static CheckinPrefs get(Context context) { + if (INSTANCE == null) { + if (context == null) return new CheckinPrefs(null); + INSTANCE = new CheckinPrefs(context.getApplicationContext()); + } + return INSTANCE; + } + + private SharedPreferences preferences; + private boolean checkinEnabled = false; + + private CheckinPrefs(Context context) { + if (context != null) { + preferences = PreferenceManager.getDefaultSharedPreferences(context); + preferences.registerOnSharedPreferenceChangeListener(this); + update(); + } + } + + private void update() { + checkinEnabled = preferences.getBoolean(PREF_ENABLE_CHECKIN, false); + } + + @Override + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { + update(); + } + + public boolean isEnabled() { + return checkinEnabled; + } +} diff --git a/play-services-core/src/main/java/org/microg/gms/checkin/CheckinService.java b/play-services-core/src/main/java/org/microg/gms/checkin/CheckinService.java index fd31234a..1f775a93 100644 --- a/play-services-core/src/main/java/org/microg/gms/checkin/CheckinService.java +++ b/play-services-core/src/main/java/org/microg/gms/checkin/CheckinService.java @@ -34,8 +34,6 @@ import org.microg.gms.common.ForegroundServiceContext; import org.microg.gms.gcm.McsService; import org.microg.gms.people.PeopleManager; -import static org.microg.gms.checkin.TriggerReceiver.PREF_ENABLE_CHECKIN; - public class CheckinService extends IntentService { private static final String TAG = "GmsCheckinSvc"; public static final String BIND_ACTION = "com.google.android.gms.checkin.BIND_TO_SERVICE"; @@ -58,7 +56,7 @@ public class CheckinService extends IntentService { protected void onHandleIntent(Intent intent) { try { ForegroundServiceContext.completeForegroundService(this, intent, TAG); - if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean(PREF_ENABLE_CHECKIN, false)) { + if (CheckinPrefs.get(this).isEnabled()) { LastCheckinInfo info = CheckinManager.checkin(this, intent.getBooleanExtra(EXTRA_FORCE_CHECKIN, false)); if (info != null) { Log.d(TAG, "Checked in as " + Long.toHexString(info.androidId)); diff --git a/play-services-core/src/main/java/org/microg/gms/checkin/TriggerReceiver.java b/play-services-core/src/main/java/org/microg/gms/checkin/TriggerReceiver.java index b52a7133..123d76d3 100644 --- a/play-services-core/src/main/java/org/microg/gms/checkin/TriggerReceiver.java +++ b/play-services-core/src/main/java/org/microg/gms/checkin/TriggerReceiver.java @@ -31,7 +31,6 @@ import static org.microg.gms.checkin.CheckinService.EXTRA_FORCE_CHECKIN; public class TriggerReceiver extends WakefulBroadcastReceiver { private static final String TAG = "GmsCheckinTrigger"; - public static final String PREF_ENABLE_CHECKIN = "checkin_enable_service"; private static final long REGULAR_CHECKIN_INTERVAL = 12 * 60 * 60 * 1000; // 12 hours @Override @@ -40,7 +39,7 @@ public class TriggerReceiver extends WakefulBroadcastReceiver { boolean force = "android.provider.Telephony.SECRET_CODE".equals(intent.getAction()); ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); - if (PreferenceManager.getDefaultSharedPreferences(context).getBoolean(PREF_ENABLE_CHECKIN, false) || force) { + if (CheckinPrefs.get(context).isEnabled() || force) { if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction()) && LastCheckinInfo.read(context).lastCheckin > System.currentTimeMillis() - REGULAR_CHECKIN_INTERVAL) { return; diff --git a/play-services-core/src/main/java/org/microg/gms/snet/SafetyNetClientServiceImpl.java b/play-services-core/src/main/java/org/microg/gms/snet/SafetyNetClientServiceImpl.java index 848d1343..8cae71e7 100644 --- a/play-services-core/src/main/java/org/microg/gms/snet/SafetyNetClientServiceImpl.java +++ b/play-services-core/src/main/java/org/microg/gms/snet/SafetyNetClientServiceImpl.java @@ -80,6 +80,7 @@ public class SafetyNetClientServiceImpl extends ISafetyNetService.Stub { bundle.putString("contentBinding", attestation.getPayloadHashBase64()); RemoteDroidGuardConnector.Result dg = conn.guard("attest", Long.toString(LastCheckinInfo.read(context).androidId), bundle); if (!SafetyNetPrefs.get(context).isOfficial() || dg != null && dg.getStatusCode() == 0 && dg.getResult() != null) { + Log.d(TAG, dg == null ? "No dg result" : ("Status: " + dg.getStatusCode() + ", error:" + dg.getErrorMsg())); if (dg != null && dg.getStatusCode() == 0 && dg.getResult() != null) { attestation.setDroidGaurdResult(Base64.encodeToString(dg.getResult(), Base64.NO_WRAP + Base64.NO_PADDING + Base64.URL_SAFE)); } diff --git a/play-services-core/src/main/java/org/microg/gms/ui/CheckinFragment.java b/play-services-core/src/main/java/org/microg/gms/ui/CheckinFragment.java deleted file mode 100644 index aee8642f..00000000 --- a/play-services-core/src/main/java/org/microg/gms/ui/CheckinFragment.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2017 microG 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.ui; - -import android.os.Bundle; -import android.preference.PreferenceManager; - -import androidx.fragment.app.Fragment; - -import com.google.android.gms.R; - -import org.microg.tools.ui.AbstractSettingsActivity; -import org.microg.tools.ui.SwitchBarResourceSettingsFragment; - -import static org.microg.gms.checkin.TriggerReceiver.PREF_ENABLE_CHECKIN; - -public class CheckinFragment extends SwitchBarResourceSettingsFragment { - - public CheckinFragment() { - preferencesResource = R.xml.preferences_checkin; - } - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - - switchBar.setChecked(PreferenceManager.getDefaultSharedPreferences(getContext()).getBoolean(PREF_ENABLE_CHECKIN, false)); - } - - @Override - public void onSwitchBarChanged(boolean isChecked) { - PreferenceManager.getDefaultSharedPreferences(getContext()).edit().putBoolean(PREF_ENABLE_CHECKIN, isChecked).apply(); - } - - - public static class AsActivity extends AbstractSettingsActivity { - public AsActivity() { - showHomeAsUp = true; - } - - @Override - protected Fragment getFragment() { - return new CheckinFragment(); - } - } -} diff --git a/play-services-core/src/main/java/org/microg/gms/ui/GcmAdvancedFragment.java b/play-services-core/src/main/java/org/microg/gms/ui/GcmAdvancedFragment.java index e7c846f2..0b66c013 100644 --- a/play-services-core/src/main/java/org/microg/gms/ui/GcmAdvancedFragment.java +++ b/play-services-core/src/main/java/org/microg/gms/ui/GcmAdvancedFragment.java @@ -94,15 +94,4 @@ public class GcmAdvancedFragment extends ResourceSettingsFragment { } return (heartbeatMs / 60000) + " minutes"; } - - public static class AsActivity extends AbstractSettingsActivity { - public AsActivity() { - showHomeAsUp = true; - } - - @Override - protected Fragment getFragment() { - return new GcmAdvancedFragment(); - } - } } diff --git a/play-services-core/src/main/java/org/microg/gms/ui/GcmAppFragment.java b/play-services-core/src/main/java/org/microg/gms/ui/GcmAppFragment.java deleted file mode 100644 index 232a2d65..00000000 --- a/play-services-core/src/main/java/org/microg/gms/ui/GcmAppFragment.java +++ /dev/null @@ -1,224 +0,0 @@ -package org.microg.gms.ui; - -import android.content.DialogInterface; -import android.content.Intent; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.net.Uri; -import android.os.Bundle; -import android.provider.Settings; -import android.text.format.DateUtils; -import android.view.View; -import android.widget.ImageView; -import android.widget.TextView; - -import androidx.appcompat.app.AlertDialog; -import androidx.fragment.app.Fragment; -import androidx.preference.Preference; -import androidx.preference.PreferenceScreen; -import androidx.preference.SwitchPreference; - -import com.google.android.gms.R; - -import org.microg.gms.gcm.GcmDatabase; -import org.microg.gms.gcm.PushRegisterManager; -import org.microg.tools.ui.AbstractSettingsActivity; -import org.microg.tools.ui.ResourceSettingsFragment; - -import java.util.List; - -import static android.text.format.DateUtils.FORMAT_SHOW_TIME; -import static android.text.format.DateUtils.MINUTE_IN_MILLIS; -import static android.text.format.DateUtils.WEEK_IN_MILLIS; - -public class GcmAppFragment extends ResourceSettingsFragment { - public static final String EXTRA_PACKAGE_NAME = "package_name"; - - public static final String PREF_WAKE_FOR_DELIVERY = "gcm_app_wake_for_delivery"; - public static final String PREF_ALLOW_REGISTER = "gcm_app_allow_register"; - public static final String PREF_REGISTER_DETAILS = "gcm_app_register_details"; - public static final String PREF_MESSAGE_DETAILS = "gcm_app_message_details"; - - protected String packageName; - private String appName; - private GcmDatabase database; - - public GcmAppFragment() { - preferencesResource = R.xml.preferences_gcm_app_detail; - } - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - packageName = getArguments().getString(EXTRA_PACKAGE_NAME); - - AbstractSettingsActivity activity = (AbstractSettingsActivity) getActivity(); - - if (packageName != null && activity != null) { - activity.setCustomBarLayout(R.layout.app_bar); - try { - PackageManager pm = activity.getPackageManager(); - ApplicationInfo info = pm.getApplicationInfo(packageName, 0); - ((ImageView) activity.findViewById(R.id.app_icon)).setImageDrawable(pm.getApplicationIcon(info)); - appName = pm.getApplicationLabel(info).toString(); - ((TextView) activity.findViewById(R.id.app_name)).setText(appName); - View view = activity.findViewById(R.id.app_bar); - view.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Intent intent = new Intent(); - intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); - Uri uri = Uri.fromParts("package", packageName, null); - intent.setData(uri); - getContext().startActivity(intent); - } - }); - view.setClickable(true); - } catch (Exception e) { - appName = packageName; - ((TextView) activity.findViewById(R.id.app_name)).setText(packageName); - } - } - - database = new GcmDatabase(getContext()); - updateAppDetails(); - } - - @Override - public void onPause() { - super.onPause(); - database.close(); - } - - @Override - public void onResume() { - super.onResume(); - if (database != null) { - updateAppDetails(); - } - } - - private void updateAppDetails() { - GcmDatabase.App app = database.getApp(packageName); - if (app == null) { - getActivity().finish(); - return; - } - PreferenceScreen root = getPreferenceScreen(); - - SwitchPreference wakeForDelivery = (SwitchPreference) root.findPreference(PREF_WAKE_FOR_DELIVERY); - wakeForDelivery.setChecked(app.wakeForDelivery); - wakeForDelivery.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - if (newValue instanceof Boolean) { - database.setAppWakeForDelivery(packageName, (Boolean) newValue); - return true; - } - return false; - } - }); - - SwitchPreference allowRegister = (SwitchPreference) root.findPreference(PREF_ALLOW_REGISTER); - allowRegister.setChecked(app.allowRegister); - allowRegister.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - if (newValue instanceof Boolean) { - if (!(boolean) newValue) { - final List registrations = database.getRegistrationsByApp(packageName); - if (!registrations.isEmpty()) { - showUnregisterConfirm(registrations, getString(R.string.gcm_unregister_after_deny_message)); - } - } - database.setAppAllowRegister(packageName, (Boolean) newValue); - return true; - } - return false; - } - }); - - Preference registerDetails = root.findPreference(PREF_REGISTER_DETAILS); - final List registrations = database.getRegistrationsByApp(packageName); - if (registrations.isEmpty()) { - registerDetails.setTitle(""); - registerDetails.setSelectable(false); - registerDetails.setSummary(R.string.gcm_not_registered); - } else { - StringBuilder sb = new StringBuilder(); - for (GcmDatabase.Registration registration : registrations) { - if (sb.length() != 0) sb.append("\n"); - if (registration.timestamp == 0) { - sb.append(getString(R.string.gcm_registered)); - } else { - sb.append(getString(R.string.gcm_registered_since, DateUtils.getRelativeDateTimeString(getContext(), registration.timestamp, MINUTE_IN_MILLIS, WEEK_IN_MILLIS, FORMAT_SHOW_TIME))); - } - } - registerDetails.setTitle(R.string.gcm_unregister_app); - registerDetails.setSummary(sb.toString()); - registerDetails.setSelectable(true); - registerDetails.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - showUnregisterConfirm(registrations, getString(R.string.gcm_unregister_confirm_message)); - return true; - } - }); - } - - Preference messageDetails = root.findPreference(PREF_MESSAGE_DETAILS); - if (app.totalMessageCount == 0) { - messageDetails.setSummary(R.string.gcm_no_message_yet); - } else { - String s = getString(R.string.gcm_messages_counter, app.totalMessageCount, app.totalMessageBytes); - if (app.lastMessageTimestamp != 0) { - s += "\n" + getString(R.string.gcm_last_message_at, DateUtils.getRelativeDateTimeString(getContext(), app.lastMessageTimestamp, MINUTE_IN_MILLIS, WEEK_IN_MILLIS, FORMAT_SHOW_TIME)); - } - messageDetails.setSummary(s); - } - } - - private void showUnregisterConfirm(final List registrations, String unregisterConfirmDesc) { - new AlertDialog.Builder(getContext()) - .setTitle(getString(R.string.gcm_unregister_confirm_title, appName)) - .setMessage(unregisterConfirmDesc) - .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - new Thread(new Runnable() { - @Override - public void run() { - for (GcmDatabase.Registration registration : registrations) { - PushRegisterManager.unregister(getContext(), registration.packageName, registration.signature, null, null); - } - getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - updateAppDetails(); - } - }); - } - }).start(); - } - }) - .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - // Do nothing - } - }).show(); - } - - public static class AsActivity extends AbstractSettingsActivity { - public AsActivity() { - showHomeAsUp = true; - } - - @Override - protected Fragment getFragment() { - GcmAppFragment fragment = new GcmAppFragment(); - fragment.setArguments(getIntent().getExtras()); - return fragment; - } - } -} diff --git a/play-services-core/src/main/java/org/microg/gms/ui/GcmFragment.java b/play-services-core/src/main/java/org/microg/gms/ui/GcmFragment.java deleted file mode 100644 index 6c4ee0db..00000000 --- a/play-services-core/src/main/java/org/microg/gms/ui/GcmFragment.java +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Copyright (C) 2013-2017 microG 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.ui; - -import android.content.Context; -import android.content.Intent; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.os.Bundle; -import android.text.format.DateUtils; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; - -import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; -import androidx.preference.Preference; -import androidx.preference.PreferenceCategory; -import androidx.preference.PreferenceGroup; -import androidx.preference.PreferenceScreen; -import androidx.preference.PreferenceViewHolder; - -import com.google.android.gms.R; - -import org.microg.gms.gcm.GcmDatabase; -import org.microg.gms.gcm.GcmPrefs; -import org.microg.gms.gcm.McsConstants; -import org.microg.gms.gcm.McsService; -import org.microg.gms.gcm.TriggerReceiver; -import org.microg.tools.ui.AbstractSettingsActivity; -import org.microg.tools.ui.DimmableIconPreference; -import org.microg.tools.ui.SwitchBarResourceSettingsFragment; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; - -import static android.text.format.DateUtils.FORMAT_SHOW_TIME; -import static android.text.format.DateUtils.MINUTE_IN_MILLIS; -import static android.text.format.DateUtils.WEEK_IN_MILLIS; - -public class GcmFragment extends SwitchBarResourceSettingsFragment { - - public static final String PREF_GCM_STATUS = "pref_gcm_status"; - public static final String PREF_GCM_APPS = "gcm_apps"; - - private GcmDatabase database; - - private final int MENU_ADVANCED = Menu.FIRST; - - public GcmFragment() { - preferencesResource = R.xml.preferences_gcm; - } - - @Override - public void onActivityCreated(@Nullable Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - - setHasOptionsMenu(true); - switchBar.setChecked(GcmPrefs.get(getContext()).isEnabled()); - } - - @Override - public void onCreatePreferences(@Nullable Bundle savedInstanceState, String rootKey) { - super.onCreatePreferences(savedInstanceState, rootKey); - - database = new GcmDatabase(getContext()); - - updateContent(); - } - - @Override - public void onResume() { - super.onResume(); - updateContent(); - } - - @Override - public void onPause() { - super.onPause(); - database.close(); - } - - @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - menu.add(0, MENU_ADVANCED, 0, R.string.menu_advanced); - super.onCreateOptionsMenu(menu, inflater); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case MENU_ADVANCED: - Intent intent = new Intent(getContext(), GcmAdvancedFragment.AsActivity.class); - startActivity(intent); - return true; - default: - return super.onOptionsItemSelected(item); - } - } - - @Override - public void onSwitchBarChanged(boolean isChecked) { - getPreferenceManager().getSharedPreferences().edit().putBoolean(GcmPrefs.PREF_ENABLE_GCM, isChecked).apply(); - if (!isChecked) { - McsService.stop(getContext()); - } else { - getContext().sendBroadcast(new Intent(TriggerReceiver.FORCE_TRY_RECONNECT, null, getContext(), TriggerReceiver.class)); - } - updateContent(); - } - - private static void addPreferencesSorted(List prefs, PreferenceGroup container) { - // If there's some items to display, sort the items and add them to the container. - Collections.sort(prefs, new Comparator() { - @Override - public int compare(Preference lhs, Preference rhs) { - return lhs.getTitle().toString().toLowerCase().compareTo(rhs.getTitle().toString().toLowerCase()); - } - }); - for (Preference entry : prefs) { - container.addPreference(entry); - } - } - - private void updateContent() { - PreferenceScreen root = getPreferenceScreen(); - - if (McsService.isConnected()) { - root.findPreference(PREF_GCM_STATUS).setSummary(getString(R.string.gcm_state_connected, DateUtils.getRelativeTimeSpanString(McsService.getStartTimestamp(), System.currentTimeMillis(), 0))); - } else { - root.findPreference(PREF_GCM_STATUS).setSummary(getString(R.string.gcm_state_disconnected)); - } - - PreferenceCategory appList = (PreferenceCategory) root.findPreference(PREF_GCM_APPS); - appList.removeAll(); - List list = database.getAppList(); - if (!list.isEmpty()) { - List appListPrefs = new ArrayList<>(); - PackageManager pm = getContext().getPackageManager(); - for (GcmDatabase.App app : list) { - try { - pm.getApplicationInfo(app.packageName, 0); - appListPrefs.add(new GcmAppPreference(getPreferenceManager().getContext(), app)); - } catch (PackageManager.NameNotFoundException e) { - final List registrations = database.getRegistrationsByApp(app.packageName); - if (registrations.isEmpty()) { - database.removeApp(app.packageName); - } else { - appListPrefs.add(new GcmAppPreference(getPreferenceManager().getContext(), app)); - } - } - } - addPreferencesSorted(appListPrefs, appList); - } else { - // If there's no item to display, add a "None" item. - Preference banner = new Preference(getPreferenceManager().getContext()); - banner.setLayoutResource(R.layout.list_no_item); - banner.setTitle(R.string.list_no_item_none); - banner.setSelectable(false); - appList.addPreference(banner); - } - } - - public static class GcmAppPreference extends DimmableIconPreference implements Preference.OnPreferenceClickListener { - - private GcmDatabase database; - private GcmDatabase.App app; - - public GcmAppPreference(Context context, GcmDatabase.App app) { - super(context); - this.app = app; - this.database = new GcmDatabase(context); - setKey(app.packageName); - - PackageManager packageManager = context.getPackageManager(); - try { - ApplicationInfo applicationInfo = packageManager.getApplicationInfo(app.packageName, 0); - setTitle(packageManager.getApplicationLabel(applicationInfo)); - setIcon(packageManager.getApplicationIcon(applicationInfo)); - } catch (PackageManager.NameNotFoundException e) { - setTitle(app.packageName); - setIcon(android.R.drawable.sym_def_app_icon); - } - setOnPreferenceClickListener(this); - updateViewDetails(); - } - - private void updateViewDetails() { - if (database.getRegistrationsByApp(app.packageName).isEmpty()) { - setSummary(R.string.gcm_not_registered); - } else if (app.lastMessageTimestamp > 0) { - setSummary(getContext().getString(R.string.gcm_last_message_at, DateUtils.getRelativeDateTimeString(getContext(), app.lastMessageTimestamp, MINUTE_IN_MILLIS, WEEK_IN_MILLIS, FORMAT_SHOW_TIME))); - } else { - setSummary(R.string.gcm_no_message_yet); - } - database.close(); - } - - @Override - public void onBindViewHolder(PreferenceViewHolder view) { - updateViewDetails(); - super.onBindViewHolder(view); - } - - @Override - public boolean onPreferenceClick(Preference preference) { - Intent intent = new Intent(getContext(), GcmAppFragment.AsActivity.class); - intent.putExtra(GcmAppFragment.EXTRA_PACKAGE_NAME, app.packageName); - getContext().startActivity(intent); - return true; - } - } - - public static class AsActivity extends AbstractSettingsActivity { - public AsActivity() { - showHomeAsUp = true; - } - - @Override - protected Fragment getFragment() { - return new GcmFragment(); - } - } -} \ No newline at end of file diff --git a/play-services-core/src/main/java/org/microg/gms/ui/SafetyNetFragment.java b/play-services-core/src/main/java/org/microg/gms/ui/SafetyNetFragment.java deleted file mode 100644 index 3756aff8..00000000 --- a/play-services-core/src/main/java/org/microg/gms/ui/SafetyNetFragment.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2017 microG 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.ui; - -import android.content.Intent; -import android.os.Bundle; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; - -import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; - -import com.google.android.gms.R; - -import org.microg.gms.snet.SafetyNetPrefs; -import org.microg.tools.ui.AbstractSettingsActivity; -import org.microg.tools.ui.SwitchBarResourceSettingsFragment; - -public class SafetyNetFragment extends SwitchBarResourceSettingsFragment { - private final int MENU_ADVANCED = Menu.FIRST; - - public SafetyNetFragment() { - preferencesResource = R.xml.preferences_snet; - } - - @Override - public void onActivityCreated(@Nullable Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - - setHasOptionsMenu(true); - switchBar.setChecked(SafetyNetPrefs.get(getContext()).isEnabled()); - } - - @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - menu.add(0, MENU_ADVANCED, 0, R.string.menu_advanced); - super.onCreateOptionsMenu(menu, inflater); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case MENU_ADVANCED: - Intent intent = new Intent(getContext(), SafetyNetAdvancedFragment.AsActivity.class); - startActivity(intent); - return true; - default: - return super.onOptionsItemSelected(item); - } - } - - @Override - public void onSwitchBarChanged(boolean isChecked) { - SafetyNetPrefs.get(getContext()).setEnabled(isChecked); - } - - public static class AsActivity extends AbstractSettingsActivity { - public AsActivity() { - showHomeAsUp = true; - } - - @Override - protected Fragment getFragment() { - return new SafetyNetFragment(); - } - } -} \ No newline at end of file diff --git a/play-services-core/src/main/java/org/microg/gms/ui/SettingsActivity.java b/play-services-core/src/main/java/org/microg/gms/ui/SettingsActivity.java index 965872ff..05befb86 100644 --- a/play-services-core/src/main/java/org/microg/gms/ui/SettingsActivity.java +++ b/play-services-core/src/main/java/org/microg/gms/ui/SettingsActivity.java @@ -1,112 +1,34 @@ -/* - * Copyright (C) 2013-2017 microG 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.ui; import android.os.Bundle; -import android.preference.PreferenceManager; -import android.text.TextUtils; import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; +import androidx.appcompat.app.AppCompatActivity; +import androidx.navigation.NavController; +import androidx.navigation.fragment.NavHostFragment; +import androidx.navigation.ui.AppBarConfiguration; +import androidx.navigation.ui.NavigationUI; import com.google.android.gms.R; -import org.microg.gms.gcm.GcmDatabase; -import org.microg.gms.gcm.GcmPrefs; -import org.microg.gms.snet.SafetyNetPrefs; -//import org.microg.nlp.Preferences; -import org.microg.tools.ui.AbstractDashboardActivity; -import org.microg.tools.ui.ResourceSettingsFragment; +public class SettingsActivity extends AppCompatActivity { + private AppBarConfiguration appBarConfiguration; -import static org.microg.gms.checkin.TriggerReceiver.PREF_ENABLE_CHECKIN; - -public class SettingsActivity extends AbstractDashboardActivity { - - public SettingsActivity() { - preferencesResource = R.xml.preferences_start; - addCondition(Conditions.GCM_BATTERY_OPTIMIZATIONS); - addCondition(Conditions.PERMISSIONS); + private NavController getNavController() { + return ((NavHostFragment)getSupportFragmentManager().findFragmentById(R.id.navhost)).getNavController(); } @Override - protected Fragment getFragment() { - return new FragmentImpl(); + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.settings_root_activity); + + appBarConfiguration = new AppBarConfiguration.Builder(getNavController().getGraph()).build(); + NavigationUI.setupActionBarWithNavController(this, getNavController(), appBarConfiguration); } - public static class FragmentImpl extends ResourceSettingsFragment { - - public static final String PREF_ABOUT = "pref_about"; - public static final String PREF_GCM = "pref_gcm"; - public static final String PREF_SNET = "pref_snet"; -// public static final String PREF_UNIFIEDNLP = "pref_unifiednlp"; - public static final String PREF_CHECKIN = "pref_checkin"; - - public FragmentImpl() { - preferencesResource = R.xml.preferences_start; - } - - @Override - public void onCreatePreferences(@Nullable Bundle savedInstanceState, String rootKey) { - super.onCreatePreferences(savedInstanceState, rootKey); - updateDetails(); - } - - @Override - public void onResume() { - super.onResume(); - updateDetails(); - } - - private void updateDetails() { - findPreference(PREF_ABOUT).setSummary(getString(R.string.about_version_str, AboutFragment.getSelfVersion(getContext()))); - if (GcmPrefs.get(getContext()).isEnabled()) { - GcmDatabase database = new GcmDatabase(getContext()); - int regCount = database.getRegistrationList().size(); - database.close(); - findPreference(PREF_GCM).setSummary(getString(R.string.abc_capital_on) + " / " + getResources().getQuantityString(R.plurals.gcm_registered_apps_counter, regCount, regCount)); - } else { - findPreference(PREF_GCM).setSummary(R.string.abc_capital_off); - } - - if (SafetyNetPrefs.get(getContext()).isEnabled()) { - String snet_info = ""; - - if (SafetyNetPrefs.get(getContext()).isOfficial()) { - snet_info = getString(R.string.pref_snet_status_official_info); - } else if (SafetyNetPrefs.get(getContext()).isSelfSigned()) { - snet_info = getString(R.string.pref_snet_status_self_signed_info); - } else if (SafetyNetPrefs.get(getContext()).isThirdParty()) { - snet_info = getString(R.string.pref_snet_status_third_party_info); - } - - findPreference(PREF_SNET).setSummary(getString(R.string.service_status_enabled) + " / " + snet_info); - } else { - findPreference(PREF_SNET).setSummary(R.string.service_status_disabled); - } - -// Preferences unifiedNlPrefs = new Preferences(getContext()); -// int backendCount = TextUtils.isEmpty(unifiedNlPrefs.getLocationBackends()) ? 0 : -// Preferences.splitBackendString(unifiedNlPrefs.getLocationBackends()).length; -// backendCount += TextUtils.isEmpty(unifiedNlPrefs.getGeocoderBackends()) ? 0 : -// Preferences.splitBackendString(unifiedNlPrefs.getGeocoderBackends()).length; -// findPreference(PREF_UNIFIEDNLP).setSummary(getResources().getQuantityString(R.plurals.pref_unifiednlp_summary, backendCount, backendCount)); - - boolean checkinEnabled = PreferenceManager.getDefaultSharedPreferences(getContext()).getBoolean(PREF_ENABLE_CHECKIN, false); - findPreference(PREF_CHECKIN).setSummary(checkinEnabled ? R.string.service_status_enabled : R.string.service_status_disabled); - } + @Override + public boolean onSupportNavigateUp() { + return NavigationUI.navigateUp(getNavController(), appBarConfiguration) || super.onSupportNavigateUp(); } } diff --git a/play-services-core/src/main/java/org/microg/gms/ui/SettingsDashboardActivity.java b/play-services-core/src/main/java/org/microg/gms/ui/SettingsDashboardActivity.java new file mode 100644 index 00000000..f3b62c1d --- /dev/null +++ b/play-services-core/src/main/java/org/microg/gms/ui/SettingsDashboardActivity.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2013-2017 microG 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.ui; + +import androidx.fragment.app.Fragment; + +import com.google.android.gms.R; + +//import org.microg.nlp.Preferences; +import org.microg.tools.ui.AbstractDashboardActivity; + +public class SettingsDashboardActivity extends AbstractDashboardActivity { + + public SettingsDashboardActivity() { + preferencesResource = R.xml.preferences_start; + addCondition(Conditions.GCM_BATTERY_OPTIMIZATIONS); + addCondition(Conditions.PERMISSIONS); + } + + @Override + protected Fragment getFragment() { + return new SettingsFragment(); + } + +} diff --git a/play-services-core/src/main/java/org/microg/gms/ui/SettingsFragment.java b/play-services-core/src/main/java/org/microg/gms/ui/SettingsFragment.java new file mode 100644 index 00000000..482152e6 --- /dev/null +++ b/play-services-core/src/main/java/org/microg/gms/ui/SettingsFragment.java @@ -0,0 +1,97 @@ +package org.microg.gms.ui; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.navigation.fragment.NavHostFragment; + +import com.google.android.gms.R; + +import org.microg.gms.checkin.CheckinPrefs; +import org.microg.gms.gcm.GcmDatabase; +import org.microg.gms.gcm.GcmPrefs; +import org.microg.gms.snet.SafetyNetPrefs; +import org.microg.tools.ui.ResourceSettingsFragment; + +public class SettingsFragment extends ResourceSettingsFragment { + + public static final String PREF_ABOUT = "pref_about"; + public static final String PREF_GCM = "pref_gcm"; + public static final String PREF_SNET = "pref_snet"; + public static final String PREF_UNIFIEDNLP = "pref_unifiednlp"; + public static final String PREF_CHECKIN = "pref_checkin"; + + public SettingsFragment() { + preferencesResource = R.xml.preferences_start; + } + + @Override + public void onCreatePreferences(@Nullable Bundle savedInstanceState, String rootKey) { + super.onCreatePreferences(savedInstanceState, rootKey); + updateDetails(); + } + + @Override + public void onResume() { + super.onResume(); + updateDetails(); + } + + private void updateDetails() { + findPreference(PREF_ABOUT).setSummary(getString(R.string.about_version_str, AboutFragment.getSelfVersion(getContext()))); + findPreference(PREF_ABOUT).setOnPreferenceClickListener(preference -> { + NavHostFragment.findNavController(SettingsFragment.this).navigate(R.id.openAbout); + return true; + }); + if (GcmPrefs.get(getContext()).isEnabled()) { + GcmDatabase database = new GcmDatabase(getContext()); + int regCount = database.getRegistrationList().size(); + database.close(); + findPreference(PREF_GCM).setSummary(getString(R.string.service_status_enabled_short) + " - " + getResources().getQuantityString(R.plurals.gcm_registered_apps_counter, regCount, regCount)); + } else { + findPreference(PREF_GCM).setSummary(R.string.service_status_disabled_short); + } + findPreference(PREF_GCM).setOnPreferenceClickListener(preference -> { + NavHostFragment.findNavController(SettingsFragment.this).navigate(R.id.openGcmSettings); + return true; + }); + + if (SafetyNetPrefs.get(getContext()).isEnabled()) { + String snet_info = ""; + + if (SafetyNetPrefs.get(getContext()).isOfficial()) { + snet_info = getString(R.string.pref_snet_status_official_info); + } else if (SafetyNetPrefs.get(getContext()).isSelfSigned()) { + snet_info = getString(R.string.pref_snet_status_self_signed_info); + } else if (SafetyNetPrefs.get(getContext()).isThirdParty()) { + snet_info = getString(R.string.pref_snet_status_third_party_info); + } + + findPreference(PREF_SNET).setSummary(getString(R.string.service_status_enabled_short)); + } else { + findPreference(PREF_SNET).setSummary(R.string.service_status_disabled_short); + } + findPreference(PREF_SNET).setOnPreferenceClickListener(preference -> { + NavHostFragment.findNavController(SettingsFragment.this).navigate(R.id.openSafetyNetSettings); + return true; + }); + +// Preferences unifiedNlPrefs = new Preferences(getContext()); +// int backendCount = TextUtils.isEmpty(unifiedNlPrefs.getLocationBackends()) ? 0 : +// Preferences.splitBackendString(unifiedNlPrefs.getLocationBackends()).length; +// backendCount += TextUtils.isEmpty(unifiedNlPrefs.getGeocoderBackends()) ? 0 : +// Preferences.splitBackendString(unifiedNlPrefs.getGeocoderBackends()).length; +// findPreference(PREF_UNIFIEDNLP).setSummary(getResources().getQuantityString(R.plurals.pref_unifiednlp_summary, backendCount, backendCount)); + findPreference(PREF_UNIFIEDNLP).setOnPreferenceClickListener(preference -> { + NavHostFragment.findNavController(SettingsFragment.this).navigate(R.id.openUnifiedNlpSettings); + return true; + }); + + boolean checkinEnabled = CheckinPrefs.get(getContext()).isEnabled(); + findPreference(PREF_CHECKIN).setSummary(checkinEnabled ? R.string.service_status_enabled_short : R.string.service_status_disabled_short); + findPreference(PREF_CHECKIN).setOnPreferenceClickListener(preference -> { + NavHostFragment.findNavController(SettingsFragment.this).navigate(R.id.openCheckinSettings); + return true; + }); + } +} diff --git a/play-services-core/src/main/java/org/microg/gms/ui/UnifiedBackendDetailsActivity.java b/play-services-core/src/main/java/org/microg/gms/ui/UnifiedBackendDetailsActivity.java deleted file mode 100644 index 6f786653..00000000 --- a/play-services-core/src/main/java/org/microg/gms/ui/UnifiedBackendDetailsActivity.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.microg.gms.ui; - -import androidx.fragment.app.Fragment; - -import org.microg.nlp.ui.BackendDetailsFragment; -import org.microg.nlp.ui.BackendListFragment; -import org.microg.tools.ui.AbstractSettingsActivity; - -public class UnifiedBackendDetailsActivity extends AbstractSettingsActivity { - public UnifiedBackendDetailsActivity() { - showHomeAsUp = true; - } - - @Override - protected Fragment getFragment() { - return new BackendDetailsFragment(); - } -} diff --git a/play-services-core/src/main/java/org/microg/gms/ui/UnifiedBackendListActivity.java b/play-services-core/src/main/java/org/microg/gms/ui/UnifiedBackendListActivity.java deleted file mode 100644 index 7bfd0aff..00000000 --- a/play-services-core/src/main/java/org/microg/gms/ui/UnifiedBackendListActivity.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.microg.gms.ui; - -import android.os.Bundle; -import android.util.Log; - -import androidx.annotation.Nullable; -import androidx.appcompat.app.AppCompatActivity; -import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentActivity; - -import org.microg.nlp.ui.BackendListFragment; -import org.microg.tools.ui.AbstractSettingsActivity; - -public class UnifiedBackendListActivity extends AppCompatActivity { - - @Override - protected void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - try { - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - } catch (Exception e) { - Log.w("GmsCoreSettingUi", e); - } - getSupportFragmentManager().beginTransaction().add(new BackendListFragment(), null).commit(); - } - - @Override - public void onBackPressed() { - super.onBackPressed(); - finish(); - } -} diff --git a/play-services-core/src/main/kotlin/org/microg/gms/ui/AppIconPreference.kt b/play-services-core/src/main/kotlin/org/microg/gms/ui/AppIconPreference.kt new file mode 100644 index 00000000..97bcca1d --- /dev/null +++ b/play-services-core/src/main/kotlin/org/microg/gms/ui/AppIconPreference.kt @@ -0,0 +1,24 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.ui + +import android.content.Context +import android.util.DisplayMetrics +import android.widget.ImageView +import androidx.preference.Preference +import androidx.preference.PreferenceViewHolder + +class AppIconPreference(context: Context) : Preference(context) { + override fun onBindViewHolder(holder: PreferenceViewHolder?) { + super.onBindViewHolder(holder) + val icon = holder?.findViewById(android.R.id.icon) + if (icon is ImageView) { + icon.adjustViewBounds = true + icon.scaleType = ImageView.ScaleType.CENTER_INSIDE + icon.maxHeight = (32.0 * context.resources.displayMetrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT).toInt() + } + } +} 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 new file mode 100644 index 00000000..68f30f72 --- /dev/null +++ b/play-services-core/src/main/kotlin/org/microg/gms/ui/DeviceRegistrationFragment.kt @@ -0,0 +1,45 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.ui + +import android.content.Intent +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import androidx.lifecycle.lifecycleScope +import androidx.preference.PreferenceManager +import com.google.android.gms.R +import com.google.android.gms.databinding.DeviceRegistrationFragmentBinding +import org.microg.gms.checkin.CheckinPrefs +import org.microg.gms.checkin.CheckinPrefs.PREF_ENABLE_CHECKIN +import org.microg.gms.checkin.TriggerReceiver + +class DeviceRegistrationFragment : Fragment(R.layout.device_registration_fragment) { + private lateinit var binding: DeviceRegistrationFragmentBinding + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + binding = DeviceRegistrationFragmentBinding.inflate(inflater, container, false) + binding.switchBarCallback = object : PreferenceSwitchBarCallback { + override fun onChecked(newStatus: Boolean) { + PreferenceManager.getDefaultSharedPreferences(context).edit().putBoolean(PREF_ENABLE_CHECKIN, newStatus).commit() + if (newStatus) { + requireContext().sendOrderedBroadcast(Intent(requireContext(), TriggerReceiver::class.java), null) + } + binding.checkinEnabled = newStatus + } + } + return binding.root + } + + override fun onResume() { + super.onResume() + lifecycleScope.launchWhenResumed { + binding.checkinEnabled = CheckinPrefs.get(context).isEnabled + } + } +} diff --git a/play-services-core/src/main/kotlin/org/microg/gms/ui/DeviceRegistrationPreferencesFragment.kt b/play-services-core/src/main/kotlin/org/microg/gms/ui/DeviceRegistrationPreferencesFragment.kt new file mode 100644 index 00000000..9bc63cfe --- /dev/null +++ b/play-services-core/src/main/kotlin/org/microg/gms/ui/DeviceRegistrationPreferencesFragment.kt @@ -0,0 +1,57 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.ui + +import android.os.Bundle +import android.os.Handler +import android.text.format.DateUtils +import androidx.preference.Preference +import androidx.preference.PreferenceCategory +import androidx.preference.PreferenceFragmentCompat +import com.google.android.gms.R +import org.microg.gms.checkin.CheckinPrefs +import org.microg.gms.checkin.LastCheckinInfo + +class DeviceRegistrationPreferencesFragment : PreferenceFragmentCompat() { + private lateinit var statusCategory: PreferenceCategory + private lateinit var status: Preference + private val handler = Handler() + private val updateRunnable = Runnable { updateStatus() } + + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { + addPreferencesFromResource(R.xml.preferences_device_registration) + } + + override fun onBindPreferences() { + statusCategory = preferenceScreen.findPreference("prefcat_device_registration_status") ?: statusCategory + status = preferenceScreen.findPreference("pref_device_registration_status") ?: status + } + + override fun onResume() { + super.onResume() + updateStatus() + } + + override fun onPause() { + super.onPause() + handler.removeCallbacks(updateRunnable) + } + + private fun updateStatus() { + handler.postDelayed(updateRunnable, UPDATE_INTERVAL) + statusCategory.isVisible = CheckinPrefs.get(context).isEnabled + val checkinInfo = LastCheckinInfo.read(requireContext()) + status.summary = if (checkinInfo.lastCheckin > 0) { + "Last registration: " + DateUtils.getRelativeTimeSpanString(checkinInfo.lastCheckin, System.currentTimeMillis(), 0) + } else { + "Not registered" + } + } + + companion object { + private const val UPDATE_INTERVAL = 1000L + } +} diff --git a/play-services-core/src/main/kotlin/org/microg/gms/ui/PreferenceSwitchBar.kt b/play-services-core/src/main/kotlin/org/microg/gms/ui/PreferenceSwitchBar.kt new file mode 100644 index 00000000..b66f1119 --- /dev/null +++ b/play-services-core/src/main/kotlin/org/microg/gms/ui/PreferenceSwitchBar.kt @@ -0,0 +1,10 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.ui + +interface PreferenceSwitchBarCallback { + fun onChecked(newStatus: Boolean) +} diff --git a/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationAllAppsFragment.kt b/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationAllAppsFragment.kt new file mode 100644 index 00000000..a55b007d --- /dev/null +++ b/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationAllAppsFragment.kt @@ -0,0 +1,115 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.ui + +import android.os.Bundle +import android.text.format.DateUtils +import androidx.appcompat.content.res.AppCompatResources +import androidx.core.os.bundleOf +import androidx.lifecycle.lifecycleScope +import androidx.navigation.fragment.findNavController +import androidx.preference.Preference +import androidx.preference.PreferenceCategory +import androidx.preference.PreferenceFragmentCompat +import com.google.android.gms.R +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import org.microg.gms.gcm.GcmDatabase + +class PushNotificationAllAppsFragment : PreferenceFragmentCompat() { + private lateinit var database: GcmDatabase + private lateinit var registered: PreferenceCategory + private lateinit var unregistered: PreferenceCategory + private lateinit var registeredNone: Preference + private lateinit var unregisteredNone: Preference + private lateinit var progress: Preference + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + database = GcmDatabase(context) + } + + override fun onResume() { + super.onResume() + updateContent() + } + + override fun onPause() { + super.onPause() + database.close() + } + + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { + addPreferencesFromResource(R.xml.preferences_push_notifications_all_apps) + registered = preferenceScreen.findPreference("prefcat_push_apps_registered") ?: registered + unregistered = preferenceScreen.findPreference("prefcat_push_apps_unregistered") ?: unregistered + registeredNone = preferenceScreen.findPreference("pref_push_apps_registered_none") ?: registeredNone + unregisteredNone = preferenceScreen.findPreference("pref_push_apps_unregistered_none") ?: unregisteredNone + progress = preferenceScreen.findPreference("pref_push_apps_all_progress") ?: progress + } + + private fun updateContent() { + lifecycleScope.launchWhenResumed { + val context = requireContext() + val apps = withContext(Dispatchers.IO) { + val res = database.appList.map { app -> + try { + app to context.packageManager.getApplicationInfo(app.packageName, 0) + } catch (ignored: Exception) { + app to null + } + }.map { (app, applicationInfo) -> + val pref = AppIconPreference(context) + pref.title = applicationInfo?.loadLabel(context.packageManager) ?: app.packageName + pref.summary = when { + app.lastMessageTimestamp > 0 -> getString(R.string.gcm_last_message_at, DateUtils.getRelativeTimeSpanString(app.lastMessageTimestamp)) + else -> null + } + pref.icon = applicationInfo?.loadIcon(context.packageManager) + ?: AppCompatResources.getDrawable(context, android.R.mipmap.sym_def_app_icon) + pref.onPreferenceClickListener = Preference.OnPreferenceClickListener { + findNavController().navigate(R.id.openGcmAppDetailsFromAll, bundleOf( + "package" to app.packageName + )) + true + } + pref.key = "pref_push_app_" + app.packageName + pref to (database.getRegistrationsByApp(app.packageName)) + }.sortedBy { + it.first.title.toString().toLowerCase() + }.mapIndexed { idx, pair -> + pair.first.order = idx + pair + } + database.close() + res + } + registered.removeAll() + registered.isVisible = true + unregistered.removeAll() + unregistered.isVisible = true + + var hadRegistered = false + var hadUnregistered = false + + for (pair in apps) { + if (pair.second.isEmpty()) { + unregistered.addPreference(pair.first) + hadUnregistered = true + } else { + registered.addPreference(pair.first) + hadRegistered = true + } + } + + registeredNone.isVisible = !hadRegistered + unregisteredNone.isVisible = !hadUnregistered + if (!hadRegistered) registered.addPreference(registeredNone) + if (!hadUnregistered) unregistered.addPreference(unregisteredNone) + progress.isVisible = false + } + } +} diff --git a/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationAppFragment.kt b/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationAppFragment.kt new file mode 100644 index 00000000..5699ec07 --- /dev/null +++ b/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationAppFragment.kt @@ -0,0 +1,58 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.ui + +import android.content.Intent +import android.net.Uri +import android.os.Bundle +import android.provider.Settings +import android.util.Log +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.appcompat.content.res.AppCompatResources +import androidx.fragment.app.Fragment +import androidx.fragment.app.findFragment +import androidx.lifecycle.lifecycleScope +import com.google.android.gms.R +import com.google.android.gms.databinding.PushNotificationAppFragmentBinding + + +class PushNotificationAppFragment : Fragment(R.layout.push_notification_fragment) { + lateinit var binding: PushNotificationAppFragmentBinding + val packageName: String? + get() = arguments?.getString("package") + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + binding = PushNotificationAppFragmentBinding.inflate(inflater, container, false) + binding.callbacks = object : PushNotificationAppFragmentCallbacks { + override fun onAppClicked() { + val intent = Intent() + intent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS + val uri: Uri = Uri.fromParts("package", packageName, null) + intent.data = uri + context!!.startActivity(intent) + } + } + childFragmentManager.findFragmentById(R.id.sub_preferences)?.arguments = arguments + return binding.root + } + + override fun onResume() { + super.onResume() + lifecycleScope.launchWhenResumed { + val pm = requireContext().packageManager + val applicationInfo = packageName?.let { pm.getApplicationInfo(it, 0) } + binding.appName = applicationInfo?.loadLabel(pm)?.toString() ?: packageName + binding.appIcon = applicationInfo?.loadIcon(pm) + ?: AppCompatResources.getDrawable(requireContext(), android.R.mipmap.sym_def_app_icon) + } + } +} + +interface PushNotificationAppFragmentCallbacks { + fun onAppClicked() +} diff --git a/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationAppPreferencesFragment.kt b/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationAppPreferencesFragment.kt new file mode 100644 index 00000000..b327349e --- /dev/null +++ b/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationAppPreferencesFragment.kt @@ -0,0 +1,134 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.ui + +import android.os.Bundle +import android.text.format.DateUtils +import androidx.appcompat.app.AlertDialog +import androidx.lifecycle.lifecycleScope +import androidx.preference.Preference +import androidx.preference.PreferenceCategory +import androidx.preference.PreferenceFragmentCompat +import androidx.preference.TwoStatePreference +import com.google.android.gms.R +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import org.microg.gms.gcm.GcmDatabase +import org.microg.gms.gcm.PushRegisterManager + +class PushNotificationAppPreferencesFragment : PreferenceFragmentCompat() { + private lateinit var wakeForDelivery: TwoStatePreference + private lateinit var allowRegister: TwoStatePreference + private lateinit var status: Preference + private lateinit var unregister: Preference + private lateinit var unregisterCat: PreferenceCategory + + private lateinit var database: GcmDatabase + private val packageName: String? + get() = arguments?.getString("package") + + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { + addPreferencesFromResource(R.xml.preferences_push_notifications_app) + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + database = GcmDatabase(context) + } + + override fun onBindPreferences() { + wakeForDelivery = preferenceScreen.findPreference("pref_push_app_wake_for_delivery") ?: wakeForDelivery + allowRegister = preferenceScreen.findPreference("pref_push_app_allow_register") ?: allowRegister + unregister = preferenceScreen.findPreference("pref_push_app_unregister") ?: unregister + unregisterCat = preferenceScreen.findPreference("prefcat_push_app_unregister") ?: unregisterCat + status = preferenceScreen.findPreference("pref_push_app_status") ?: status + wakeForDelivery.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue -> + database.setAppWakeForDelivery(packageName, newValue as Boolean) + database.close() + true + } + allowRegister.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue -> + val enabled = newValue as? Boolean ?: return@OnPreferenceChangeListener false + if (!enabled) { + val registrations = packageName?.let { database.getRegistrationsByApp(it) } ?: emptyList() + if (registrations.isNotEmpty()) { + showUnregisterConfirm(R.string.gcm_unregister_after_deny_message) + } + } + database.setAppAllowRegister(packageName, enabled) + database.close() + true + } + unregister.onPreferenceClickListener = Preference.OnPreferenceClickListener { + showUnregisterConfirm(R.string.gcm_unregister_confirm_message) + true + } + } + + + private fun showUnregisterConfirm(unregisterConfirmDesc: Int) { + val pm = requireContext().packageManager + val applicationInfo = packageName?.let { pm.getApplicationInfo(it, 0) } + AlertDialog.Builder(requireContext()) + .setTitle(getString(R.string.gcm_unregister_confirm_title, applicationInfo?.loadLabel(pm) + ?: packageName)) + .setMessage(unregisterConfirmDesc) + .setPositiveButton(android.R.string.yes) { _, _ -> unregister() } + .setNegativeButton(android.R.string.no) { _, _ -> }.show() + } + + private fun unregister() { + lifecycleScope.launchWhenResumed { + withContext(Dispatchers.IO) { + for (registration in database.getRegistrationsByApp(packageName)) { + PushRegisterManager.unregister(context, registration.packageName, registration.signature, null, null) + } + } + updateDetails() + } + } + + override fun onResume() { + super.onResume() + updateDetails() + } + + private fun updateDetails() { + lifecycleScope.launchWhenResumed { + val app = packageName?.let { database.getApp(it) } + wakeForDelivery.isChecked = app?.wakeForDelivery ?: true + allowRegister.isChecked = app?.allowRegister ?: true + val registrations = packageName?.let { database.getRegistrationsByApp(it) } ?: emptyList() + unregisterCat.isVisible = registrations.isNotEmpty() + + val sb = StringBuilder() + if ((app?.totalMessageCount ?: 0L) == 0L) { + sb.append(getString(R.string.gcm_no_message_yet)) + } else { + sb.append(getString(R.string.gcm_messages_counter, app?.totalMessageCount, app?.totalMessageBytes)) + if (app?.lastMessageTimestamp != 0L) { + sb.append("\n").append(getString(R.string.gcm_last_message_at, DateUtils.getRelativeDateTimeString(context, app?.lastMessageTimestamp ?: 0L, DateUtils.MINUTE_IN_MILLIS, DateUtils.WEEK_IN_MILLIS, DateUtils.FORMAT_SHOW_TIME))) + } + } + for (registration in registrations) { + sb.append("\n") + if (registration.timestamp == 0L) { + sb.append(getString(R.string.gcm_registered)) + } else { + sb.append(getString(R.string.gcm_registered_since, DateUtils.getRelativeDateTimeString(context, registration.timestamp, DateUtils.MINUTE_IN_MILLIS, DateUtils.WEEK_IN_MILLIS, DateUtils.FORMAT_SHOW_TIME))) + } + } + status.summary = sb.toString() + + database.close() + } + } + + override fun onPause() { + super.onPause() + database.close() + } +} diff --git a/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationFragment.kt b/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationFragment.kt new file mode 100644 index 00000000..fcdc6965 --- /dev/null +++ b/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationFragment.kt @@ -0,0 +1,72 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ +package org.microg.gms.ui + +import android.content.Intent +import android.os.Bundle +import android.view.* +import androidx.fragment.app.Fragment +import androidx.lifecycle.lifecycleScope +import androidx.navigation.fragment.findNavController +import androidx.preference.* +import com.google.android.gms.R +import com.google.android.gms.databinding.PushNotificationFragmentBinding +import org.microg.gms.checkin.CheckinPrefs +import org.microg.gms.gcm.GcmPrefs +import org.microg.gms.gcm.McsService +import org.microg.gms.gcm.TriggerReceiver + +class PushNotificationFragment : Fragment(R.layout.push_notification_fragment) { + lateinit var binding: PushNotificationFragmentBinding + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + binding = PushNotificationFragmentBinding.inflate(inflater, container, false) + binding.switchBarCallback = object : PreferenceSwitchBarCallback { + override fun onChecked(newStatus: Boolean) { + PreferenceManager.getDefaultSharedPreferences(context).edit().putBoolean(GcmPrefs.PREF_ENABLE_GCM, newStatus).apply() + if (!newStatus) { + McsService.stop(context) + } else { + requireContext().sendBroadcast(Intent(TriggerReceiver.FORCE_TRY_RECONNECT, null, context, TriggerReceiver::class.java)) + } + binding.gcmEnabled = newStatus + } + } + return binding.root + } + + override fun onResume() { + super.onResume() + lifecycleScope.launchWhenResumed { + binding.gcmEnabled = GcmPrefs.get(context).isEnabled + binding.checkinEnabled = CheckinPrefs.get(context).isEnabled + } + } + + override fun onActivityCreated(savedInstanceState: Bundle?) { + super.onActivityCreated(savedInstanceState) + setHasOptionsMenu(true) + } + + override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { + menu.add(0, MENU_ADVANCED, 0, R.string.menu_advanced) + super.onCreateOptionsMenu(menu, inflater) + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + return when (item.itemId) { + MENU_ADVANCED -> { + findNavController().navigate(R.id.openGcmAdvancedSettings) + true + } + else -> super.onOptionsItemSelected(item) + } + } + + companion object { + private const val MENU_ADVANCED = Menu.FIRST + } +} + diff --git a/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationPreferencesFragment.kt b/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationPreferencesFragment.kt new file mode 100644 index 00000000..f855ea54 --- /dev/null +++ b/play-services-core/src/main/kotlin/org/microg/gms/ui/PushNotificationPreferencesFragment.kt @@ -0,0 +1,121 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.ui + +import android.os.Bundle +import android.os.Handler +import android.text.format.DateUtils +import androidx.core.os.bundleOf +import androidx.lifecycle.lifecycleScope +import androidx.navigation.fragment.findNavController +import androidx.preference.Preference +import androidx.preference.PreferenceCategory +import androidx.preference.PreferenceFragmentCompat +import com.google.android.gms.R +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import org.microg.gms.gcm.GcmDatabase +import org.microg.gms.gcm.GcmPrefs +import org.microg.gms.gcm.McsService + +class PushNotificationPreferencesFragment : PreferenceFragmentCompat() { + private lateinit var pushStatusCategory: PreferenceCategory + private lateinit var pushStatus: Preference + private lateinit var pushApps: PreferenceCategory + private lateinit var pushAppsAll: Preference + private lateinit var pushAppsNone: Preference + private lateinit var database: GcmDatabase + private val handler = Handler() + private val updateRunnable = Runnable { updateStatus() } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + database = GcmDatabase(context) + } + + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { + addPreferencesFromResource(R.xml.preferences_push_notifications) + } + + override fun onBindPreferences() { + pushStatusCategory = preferenceScreen.findPreference("prefcat_push_status") ?: pushStatusCategory + pushStatus = preferenceScreen.findPreference("pref_push_status") ?: pushStatus + pushApps = preferenceScreen.findPreference("prefcat_push_apps") ?: pushApps + pushAppsAll = preferenceScreen.findPreference("pref_push_apps_all") ?: pushAppsAll + pushAppsNone = preferenceScreen.findPreference("pref_push_apps_none") ?: pushAppsNone + pushAppsAll.onPreferenceClickListener = Preference.OnPreferenceClickListener { + findNavController().navigate(R.id.openAllGcmApps) + true + } + } + + override fun onResume() { + super.onResume() + updateStatus() + updateContent() + } + + override fun onPause() { + super.onPause() + database.close() + handler.removeCallbacks(updateRunnable) + } + + private fun updateStatus() { + handler.postDelayed(updateRunnable, UPDATE_INTERVAL) + pushStatusCategory.isVisible = GcmPrefs.get(context).isEnabled + pushStatus.summary = if (McsService.isConnected()) { + "Connected since: " + DateUtils.getRelativeTimeSpanString(McsService.getStartTimestamp(), System.currentTimeMillis(), 0) + } else { + "Disconnected" + } + } + + private fun updateContent() { + lifecycleScope.launchWhenResumed { + val context = requireContext() + val (apps, showAll) = withContext(Dispatchers.IO) { + val apps = database.appList.sortedByDescending { it.lastMessageTimestamp } + val res = apps.map { app -> + try { + app to context.packageManager.getApplicationInfo(app.packageName, 0) + } catch (ignored: Exception) { + null + } + }.filterNotNull().take(3).mapIndexed { idx, (app, applicationInfo) -> + val pref = AppIconPreference(context) + pref.order = idx + pref.title = applicationInfo.loadLabel(context.packageManager) + pref.icon = applicationInfo.loadIcon(context.packageManager) + pref.onPreferenceClickListener = Preference.OnPreferenceClickListener { + findNavController().navigate(R.id.openGcmAppDetails, bundleOf( + "package" to app.packageName + )) + true + } + pref.key = "pref_push_app_" + app.packageName + pref + }.let { it to (it.size < apps.size) } + database.close() + res + } + pushAppsAll.isVisible = showAll + pushApps.removeAll() + for (app in apps) { + pushApps.addPreference(app) + } + if (showAll) { + pushApps.addPreference(pushAppsAll) + } else if (apps.isEmpty()) { + pushApps.addPreference(pushAppsNone) + } + } + } + + companion object { + private const val UPDATE_INTERVAL = 1000L + } +} diff --git a/play-services-core/src/main/kotlin/org/microg/gms/ui/SafetyNetFragment.kt b/play-services-core/src/main/kotlin/org/microg/gms/ui/SafetyNetFragment.kt new file mode 100644 index 00000000..b611a1ac --- /dev/null +++ b/play-services-core/src/main/kotlin/org/microg/gms/ui/SafetyNetFragment.kt @@ -0,0 +1,61 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.ui + +import android.os.Bundle +import android.view.* +import androidx.fragment.app.Fragment +import androidx.navigation.fragment.findNavController +import com.google.android.gms.R +import com.google.android.gms.databinding.SafetyNetFragmentBinding +import org.microg.gms.checkin.CheckinPrefs +import org.microg.gms.snet.SafetyNetPrefs + +class SafetyNetFragment : Fragment(R.layout.safety_net_fragment) { + + private lateinit var binding: SafetyNetFragmentBinding + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + binding = SafetyNetFragmentBinding.inflate(inflater, container, false) + binding.switchBarCallback = object : PreferenceSwitchBarCallback { + override fun onChecked(newStatus: Boolean) { + SafetyNetPrefs.get(requireContext()).isEnabled = newStatus + binding.safetynetEnabled = newStatus + } + } + return binding.root + } + + override fun onResume() { + super.onResume() + binding.checkinEnabled = CheckinPrefs.get(requireContext()).isEnabled + binding.safetynetEnabled = SafetyNetPrefs.get(requireContext()).isEnabled + } + + override fun onActivityCreated(savedInstanceState: Bundle?) { + super.onActivityCreated(savedInstanceState) + setHasOptionsMenu(true) + } + + override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { + menu.add(0, MENU_ADVANCED, 0, R.string.menu_advanced) + super.onCreateOptionsMenu(menu, inflater) + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + return when (item.itemId) { + MENU_ADVANCED -> { + findNavController().navigate(R.id.openSafetyNetAdvancedSettings) + true + } + else -> super.onOptionsItemSelected(item) + } + } + + companion object { + private const val MENU_ADVANCED = Menu.FIRST + } +} diff --git a/play-services-core/src/main/kotlin/org/microg/gms/ui/SafetyNetPreferencesFragment.kt b/play-services-core/src/main/kotlin/org/microg/gms/ui/SafetyNetPreferencesFragment.kt new file mode 100644 index 00000000..2a4b4ab2 --- /dev/null +++ b/play-services-core/src/main/kotlin/org/microg/gms/ui/SafetyNetPreferencesFragment.kt @@ -0,0 +1,17 @@ +/* + * SPDX-FileCopyrightText: 2020, microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.ui + +import android.os.Bundle +import androidx.preference.PreferenceFragmentCompat +import com.google.android.gms.R + +class SafetyNetPreferencesFragment : PreferenceFragmentCompat() { + + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { + addPreferencesFromResource(R.xml.preferences_safetynet) + } +} diff --git a/play-services-core/src/main/res/drawable-hdpi/ic_map_marker.png b/play-services-core/src/main/res/drawable-hdpi/ic_map_marker.png deleted file mode 100644 index 58c9a14bdce994e234e8ace0096ceef307d308e9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1171 zcmV;E1Z?|>P)%*^Z?8ylM-c@V(k>EZh#@@ucxTWPo3cm6kE zN~xzs}FZL{2sujjsjC6Y$~Wc{rwrL{B52+Z@mmoi#=0H&fSy1$npJvWtlUDh@S z1MqA{-xaNO-?@}}t~jo31@=T16Uk22ga+PBwQa#3%jnBI$ql?&Yny|SyqCq7B+0?7 zIkS4R*0ur@k*sgLr>fQJXg^cxIpw&vIT(PSvY1F7isSffKVKZjXGtD%S=$PX4It-uNA43`VGJVgP3nct_H+)_}hAV3&mC zB@vl1h&e{m1ma&JdC3F{uvi3>{36dFEy0XyTD@p0rB(nO9uU`ct@VUykkvaC$#VmO zvaV$X*6Z~?2XK1;T({F&g8^%`S`SFpil!o2YqeSr1_lNIrBdlr05=Qdx|!CnlJ(Zv z;^N{~5Cr!DoGb`zu2!pAZ<^-Xknw&0JjpfJL?qXI-#?!#N8Uk%VfdPeTy>Evm5@9h zMbS5TlH}e(O9!yv2nqle@@@5bOcLBVSGu6BG zdfmDau~RNPnp8@C4dA$C{8g>>>o8pG?j@Jo)Y9wq-h|yFxt_*4fpQIocDsFtv0s)G4XwW7Ju#A_tR?Xb*{qx=P^4w``pOL z$Pd`NkG8S3we@nd*>t{g0SfGKHJi<~biV!97lM$SE(!`Lu73;w=yWqK}HKU3gcrR4Tm>;PQ?`m(yc~s?h&ZZL3G0s!Clk5;SI%|X;1h{7=3 lABN%nhdqv=h8oI^{sctzRI9O@YcT)-002ovPDHLkV1k}U8(jbZ diff --git a/play-services-core/src/main/res/drawable-ldpi/add_account.png b/play-services-core/src/main/res/drawable-ldpi/add_account.png deleted file mode 100644 index c84ada96285da895e3908ea5986386d1c4896e6d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 169 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+0wn(&ce?|m3OrpLLn;`zo?>Kc2oP|+D1FK5 z_6hYBWdRwSxmr`0nlub*PhBu*vErB0+wZ9{<1y2ZtS51uiiOid7hmj8>s1qevEWkt zZ$Xx6I~tZYel^=9Q7kP61T=Nnm>3Pp~8JkPc8 ziiB@K^p?QlD_p7%%64eJJ5(wyvtD5CzjKEhf7LMlsW=}Wy}N49uBge;Sx0y8ZoT5! zW2MdcaIx^>T{Rav0)5Rq{JPdBm{#rDdWJpc&X+22=}D7=KC?%=PmSZ)d+Oq~C3B-R uR=?GhFk0*k}3<^7zS)sXUP@^ z!Nx+cR*w{>GgTV@V6+g#NI(v|1CyHsj@x?{nSf|+XLdFcgnY1Y%=_Lqznj~eodwSI zpNU+Wgb?Au!NDvu&jPpxU__U`1NcNlP2cyMLWs`42BIj6?h?^`X1-i#B>KV352Tcj z0r05<2_eExr}LDEZkPE6%=|nI!#lRCWd$UJxS*8U05Dkw<~O|#f?!Gr(KQ)sHfc(! z)e0~GFsU=DuTT_4Hvqh|g)dMaz=V|YL)8^pG5C4_-s`Jpm}|u}Ss{=RA_Op9VA=FM zZ(K?_A*Gz~JZ~JpW`TcNXSx9?rRo5N2b6b$Aec##WcPR=Ns`?l2xb864CoownQlPL zJTj<8MCnO?Wg$d|h*FnKBM=c?DhU4OQY*?d0s&A3!B<>rMVUsRTCMh_U=@~6xIz`GE46QffVp#S-(X__i#UaLyO%xh_y zDwEIZftly|BLI69c=mLLQC2`%mbHl}bEP4oEX%U?sR04N;o;#bfR+PKOZQsI8mQ4| z>@o9VSsG?uY&06yKX<7^SDL0T05nUqGGWkAsUS)fg%Rj z@jF0~f25Q!d|V-(d4-QK6cNZU;vI(xL0EvoxFj8EDi8)%U+#m}J#Ik~L=rVDbQiG7N4pSzj0&|!mB$W^7fJSq@ akpTe1pLQv<$B6d;0000VfEVKfi2`aQGVwtoiC{EQB=QW&3Lzzt{WD02 znHa$CPN!|M36dIp;LR+NM1nQJC}`S7QSnb~NHIc5Km(|yu&|cSJw9}{T?k5d?!7aG z?C*8weCNAg@4d5gXA3lF(4aws2Dd8|M^ndfn#$$!(?s+vGd~945daSXNCuab0h|Re zNJKv|^B2ivvfpu>(K|YzEnBuMF->y=fL8(BTW9%S0QUL5zo(<4<2cR1o)cF%05H$@{gUH2 z&8h^I1r*$^7RQmw4J;14C_%{*vu%5k5aL^?zmbUyw6wIWXXdvN{?7P!rBZpYSS2$isFpN(CEDX_OPT=v&uw#_kq)pRY9eXlC6F4P(knOHpmz9u zQw+eDtd9aIkFo)sueU%5F+XgxkhOJttVK4Ux^KNiv?7&C&8W97l}gPZq7_kitVQ-V z|67Q%*|TQNT32sTP%}Fsj}u4*L`0#EH;HJ6ZQD~`F1BsYC!!rudQ=jS5F+d$`CK7H zPdc4maH|W`>GT32L=S+u5qkt6`79=cIBFQi6##dKC|_t8#?f3Zr}JU;iV)(c%owH5 zaI)F#M*v=yl+khA0Ra15*L_7sK>9q0i1stHY(OnUG%*k&HD_-`v|m<3`p9*3bo2m# zt4cgpP1=6!LeaU;yUudAzTSXM{XYoB-HjYFR&We4rKT<&{jUJ_p( zHG?8LRwxu6SD~fs#i0d&@nx;yz!-o$G%d*Y_crDUo0*ENJbLY-qlxpfQ zn#p8(iD+3gv5dpaeeLb-mTFz4OKd{aFx~(lw5KwO2zn|<=@P5b+uM7_vaI_7Jf$_3 zNp`!g`<@PAEi(uJDwWDM0B5vCGRc{smlm`IR4f)ph-kAe{VGJXxmYZYXw%m{fNVDV zF@P5}$scfC_a&YFwauU^zVB}eexj=sX1?tE{wCf2wQSP0^!N9VSeA7ez)F?6M3nJ7 zFU+gx`ugZ@Q0lBIHy4CT%e^r93Z-Y;JWS~ z0M<(mi~+0Isb-SYU9N7%2GB!4r1uzhzbRejWl*j|> z?CiWMgjfyWQXOTNgb=GcJ3AwPdlGp-0N{DvaUz=PM$1IB&hxzEad?e%52~fNw|Bs@ zteF6Abu7{m^}bU}EHkLesZ*zH07w4kk|V)2u@P%PrBcaHBob=?oV>}$CliUp8kOhE zVVD;GfMVPBqe6(UF!=+ii-uu5lh5aWj@w(TGpI@s#9EC1;L-=Mb~=PJ?Z{@c8?)K$ l#<+bnXwaZRg9dj7{{m4zB!0b=EolG%002ovPDHLkV1it<)_DK` diff --git a/play-services-core/src/main/res/drawable-xxhdpi/add_account.png b/play-services-core/src/main/res/drawable-xxhdpi/add_account.png deleted file mode 100644 index 53264c28081b15179fa6a094fa09ff5819d6e0fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 428 zcmV;d0aN~oP)JFmPlwE z)$E-K66xR>W$2kslGsKW+aiHpWT+Q+E6C6af22?Su7nJg{0ChjLs$NTUXh`)|DbZC z4Z22#uKfocAwx(0gI1BDRsTVK$WXukAj{LSO-3^IRj2)N^&JEgC`03rY7i`=8ZAT0 zK`==b{ZN$x_z!aYO#*kRoeLGnj7B z01NDLk7{(!4hsx;4jQ4z9Wr*uI-}&Qg&9sz9i1>k3pp9%66Me(W7Msc4U}V>v{Hv5 zZc)zNGRz-!^N1XJpa(meI73dI(u~*6W8~N|W)TRZ5yF z3MXRjcH^TG{ZOhq@9x<`hZMM?3O+O~Z4~wG0|?Ygjl6cKLqjO3Qz_w1Bx;+|IH?my z_Rhlx@0p8<-_AQTyVm}`dhdCj|NJ$xAsqSsTY)S*hH@~&uPzOGx_Vu`$Ag+igDqod<~!!RCT=8aMsf#`@3 z;<3w@FaN4uuV2=!dEQ!e7cdt+Jw2;asnjkaDgwAcQQFhYT=RW@-@w4YCEaasH6m%4 zX_|Kd_$h!JHI;A*zz-b9c~N&;%qCKXmCNNdlarGTBKnT*S^$8V53X9ZYG;%tD3LMD zvaH*f`8NPQp}Uq@{F8{b+O|EcyAS|K=`H{ON~O|v00%KWC65}{0k}Vx%boT-?={`U zXg91>Dm_F*15v1D9t;MZimv?2U~@j7KkIqkt2&ZvG0Zg0EdU-zJbKpExHF&6ANM@(xa!2p8_YD# zbpVcF`eq(y#sF+|9OtCUr0qV7Yl}jm&;j6S#NR9g8lDa`DMP7Y9UUDOfDI~hN@hc# zNg2w9#NOWC8-3sZD}YXw0u?ZkN~JzmtyWK|NT#fZ`My7Zm1hFewJizLl*hbke&9g;$i5z*~SH46Y-*WFJ^2E8`)u3({c?i@G5TVnc?M~Q?b);Eg8;4%IqW+V z6BD5|auDmCkZZg?&@KgOhNaW#o5GGsM2&jAem<;t^?Ln05jEnVy@@o#h$!^cPrmOz z7l)WKv^SAySg7y3nECx$t=9HLV=ij7+6XhhA7$;W$eeUs6KbJ`aT?PPS;K~d*pbzK zMLWm}%*?C8j3NhSFu>!6n34(VsR4@bwycwE7A<}eg9u!$4sSC-;P5}8QPo3 z{KxrC03yto%)GNuC|ny>yh5RHEi>;7S-J?cOF^1peSLjn0KzVOZD(ia-mroNvDSuM z@AR_d4@O|1_0MF^DCuNY1>kNSSppaG4m^sv|L=aVN%z0WHOnN@$vDu5&mly09Z{# zPnf2;V-agQpkhr2fVVT5Oz6)$TamuZ&9bZpGe00Z5A?5^0ueoC+jiKq&MT0B`?OM6^%! z32v=uJv+nq{YL;uTO})j^Fhtp(0YXI(9qDu?(S{|@HL%vEEXbq*md1yZ`WN8+E1rB zckWz2fKlCbEP~OXR;_3^tkGypGV^ZTbu0uk?`||2+9yfc4FdqzbzdT)r*zjb7ew@w z>$=)b(rzUZh5^9jJRAg$qG#ksvaM`wtHfU&!Th<3x0)?pj)5W~;xy{|~zB zXcCzo1^``MT|WabsJo6927{U+L*x#fEEbFF4a0a1`j4BP5JG&ZR;xv71{;|nvB}WT z(AnqEL7#hz4xLajjBKp4Ty1&z{f6n@J7qAefX+8@e^o`?l@SNi~_vqF< zACbI=wUSP!w-eDB*?EZQOgf$3u3PUyMBcDUrSh&2;y%b-Qourp`=a!5(z%H2J**Ya z^G@aS`D*~=B&FzgUH9j@buNa;_pm0}Z1zV0j!Fo9G>9DwB0uS9#j>oMn0W-@P4zDl z(I(rr-_WgXvBai_0f24WZ!q(NVZ~$S2jgTG5R-dYE1u^a%jffJ0NlFFP<7XJWt^%l zm00z#CfRJZ#LQm1zh`DIo6Sb%9oJHb)jh10o}QkMr_<>p06x0JpT0FUHMMbIVBp`n zHMB!4dl&!&4Zami`?`Y0%CX%YsK@te{^?uj|2F|Vy-75%W<4oZz_znVE`~V zI5?co=RXbLmIW?-!f_m>UxbxGY=^`aIGfGx05IRNcZY*(;=E%9K#V6HvniL$Yp15B z4g>hqtUvuNolf6csZ_%L#)=kJjA6jc2j&jpe@E+$8HTZ0<_FkRvl52H83JSO#q?~@ z2XOC7GHbJz8V75Kb+{XAqm4GsHuglju{AO4HmL13wrktA5!9pL)W*)d``)`}lJon= z{ss>hV~jDz7-NiyMTQY}afSz!De{oB>|hQl8bTXuC?bDZku|iT+GGm6L;kaO6qt-s zO&msQ*kPJbXc~8s8h4jzDAUR#q>eqJ14YuDM(W%JvZyg139xx6(L*UvK#5*dSc3%I zS`;7-fp^1*!-ffs{I*)HbP8DIKVY9zz&`&0H=F`)_z!sR6!6Y}z+0z)xBdfe zItASHA8^1a-~g`dGTQJrvIOs49wqz-!0NyOYd}LlN8rclb^;K`h4(@;AG8FdIgix2 z)1>tTKqn9De5r2*O#v{S+b+i{{sW+iV@M4jOQaGqTOc@K%&jPRj3$TC${p6X?7WQ!cr~C1HZm@@K%p*@f34HUyTTxm$gmNKX&cE9vTiOSG43MWgs7K$NX)xSA0f$c3-Pd9 zeo zgzrku0I*NZ9%Y4zA6_a7kGSZ5h_lx-8iT_grugMu;5n0+!`bDdC$zV77m*X9o1E zgl$+Pcbq$0_$Xn1IpO{2>6i5Pto-hT-JZHVi;e%Bo-G#KCzSrm@5I6XgX_Z?OhI(i zpii7pp+i{#il}4oKzt$$I08rrt|kMqt2`HA1uzkq07!C_IU9VkjwEGY_@`(77fj_e z7TzH{1HTdh&lBs@fDSYQpLso5ko^Vq&4k2>YWgdM8SQSc$a5I`GVoM0 z>l@!UNPKU@lJ-1tJC`V4Y2OW3r=KnUvXh)mu7*bZo_kXdKNjZYVO-et=TV>h5a(zi zhcee$y=XOqKWx7@cPFk45W>eFaJdiBxM`sl$=<`opYinz}x4pgXz{5FZILoW&p;;1rctFlE)Jr8L zU}o`j&&YA@z?wOIy9*~e1EXYMOSbXd5I|0`m z8`c@W|IrTjtuQG%W>~b;8ye-$jW(zG*V+y<&Ov{%xYfEBS7b;K^`^z7>X^yb&m*~i zi3AjHA+4%d$QviMz>UzxJ=5FKd-sb}pM#?DLg?D{t=0!T8%OlBw7V4LvDDu?r#iVm z;J}jHexolZU`4d9>D}WR)>(VsFI_)8qoKDB09kZzdO}n9h-27@?`v)sy~${E2mlmg z#f|-IV@nOuVtzA!h&mn&m^lJjHSf6=KpSj<{Wv5rp(;sn<5MBe-OIfe99bD_S(tr5 z_|j`|!g+4X0qde%dLs&vM-4OHd52531ex;EEcl9IVXZBXsr3h;EpF(JrdE?~CL{vm z-_3tJeeB5J-qNXS)zJ#GBfv7Oqy2TD_z{f4hB_Zkpgd4GW7?>C5g)-nLqAo#_~H=W z*R5nt_U=uTczIqi%26eyaW>&))i=hgJ8@!D${|Nyo>*3X+GzHE) zq_flIcDd-kBj9bU(8YsMR-o99f)Gp6!$tZegGWOHQ$7iQf zQH31&a`G?CU=&;r0_z(RZ7YDw%Qs^L#c&$ULlw_yc1lC3w^h5j>GZQRG45;nbnYV8 zyh8J^^gykGJtWE5>v!6B^1_rf2jkJTF{L4MkiCNuL?8-Ak%&jNSei0{QBkX+y?CiI z-%Y{IOM5)O9ODP5JrQLEc1liXNvl&IKc!8h;plChcx@#Q$Ig?H7HS>LxxP(bt$?(dFNe-7nPa%_Y+a@ENK3+_}5>sOEVw` zf%));hMF$Ax4eJebUO9Z5gxo~CH- zZ;Bm#5fg+lLrVlyy?Y}NvbFcgHB}xC-z_nj;-OV)VIN0Pc2+mbG^L~}rVVjIq8=Rg z^Si_8;;ZgT2fgR7pnx6sWkYql?JKL71aM>b&??nWe(|;;I;HH=Mp)=WqEH7;QQaQ* zBReARJ0Y%CSbx!$c7aeV?{$lJT3TiUV!Tf?Sa^aQrX6s%CCJdS0CZoVf z5Mg_zNzSYXue;2B4K^SZ`V9Vj=9jpp=4OR5yW=&_8Pj({AfW6QD1;swH9}8NBNaaE zn-c~UOo_pVNOffOx7Pg_IWs0h95FmFGU9!EKil|2kLeRp1T01)1Kz){&(Eaaig@S)%@Z*K(v#tw_UxwovsS=MF{ zK2rF|J--1C{%fqW)RM&b?-5$tJ3HgI+HsD2iB8xX#{v!L+=n~_HIoK9&u*Xm3EV!? zRjLF{#|Bdxgcg>U5BuY_M;aXNB)G-JZID^iq22)`(EI7r9nREAnZe`AR^lw1u2a3z z5C|k7JUkp&O(1AXO1PNb>kc`!LAPGqF94i7cg`|x;xk`bi{w_RC20$wf8Y zABcWHsN(UlQfD5C5aFe-2)LFdWON4lw$i5 zXOrH6fd*-IP+2_&f_V3$y4eQHu@-iR@{=AtdbE$^51RX#bZBETDj|Hxl$4a3`udnV zx$snY!hxWz))5CPgOxHHEn08vQQ%p4^9?fV<*21Riq+K+etCQv zTcE%cysr+P1}W4xX_75LTa4Mkl}jjAi$(pWD!il`mTg_KdR0p{6o`1tq6tPl0Mlfi zY-DN1HaOMhX1ox)j%O;%u1lTib(0cWn4hQn&3H3bn}^SnBn`%S{rzrIj`}4pGtRlF zOZ)!X0YIWHwo4&w)qF*chtRY+M`UP(jqLJ~MtP>xwq;~Mx5V~&|7jwT_>`p;Dkq)t zxzqgMM$%sXR$?+5i&lM12P2)Hp8nfgT+JDPIO3MSYOc#Vxi9G9jA<{%m-@wAbV8J% z#Fx`leN7dh$+{9kLiQU%bP60UK_ie@VG<;jcGuv5bF+}Or{|yrzSRp0H5mWvshz{bHGT>Xe9L!+4i9#x5X~zB7RKjmaQ3c z{SV`MQ;J14s6TSBwC~b@w@Zi1_=fJg+4UaBS>N!GR*+VU2PwtmE1ohrM_n zkh+c=PHlimj862G{Ls$X9Eyrl2r?t-7EPGEjP}`pf0%P^zxZKPHB2bXYv3052d@`_%9AsC$ zS{X2kIYrSacUCu-GKU+E2Lvof`*@DDy>xf&$)Ae?ld%P`6y0*=$>NL14{I$!$6``M z?(vN@B=xT?W1u;Rae;th!da-MGW~2anZ76LXET)Jt6F+~Hmd0-4<7TH$j}GFl#IW^ z>3hK4ZxG$A*K?L(!&3!S@4TZ{vijw)RW=FQHQAf&c&j diff --git a/play-services-core/src/main/res/drawable/dots_horizontal.xml b/play-services-core/src/main/res/drawable/dots_horizontal.xml index 5c71aeb7..4110aed7 100644 --- a/play-services-core/src/main/res/drawable/dots_horizontal.xml +++ b/play-services-core/src/main/res/drawable/dots_horizontal.xml @@ -1,13 +1,14 @@ + android:width="24dp" + android:height="24dp" + android:tint="?attr/colorControlNormal" + android:viewportWidth="24" + android:viewportHeight="24"> - \ No newline at end of file + diff --git a/play-services-core/src/main/res/drawable-anydpi-v21/add_account.xml b/play-services-core/src/main/res/drawable/ic_add_account.xml similarity index 92% rename from play-services-core/src/main/res/drawable-anydpi-v21/add_account.xml rename to play-services-core/src/main/res/drawable/ic_add_account.xml index aa8b898a..1ff91a0e 100644 --- a/play-services-core/src/main/res/drawable-anydpi-v21/add_account.xml +++ b/play-services-core/src/main/res/drawable/ic_add_account.xml @@ -2,6 +2,7 @@ @@ -10,4 +11,4 @@ - \ No newline at end of file + diff --git a/play-services-core/src/main/res/drawable/certificate.xml b/play-services-core/src/main/res/drawable/ic_certificate.xml similarity index 71% rename from play-services-core/src/main/res/drawable/certificate.xml rename to play-services-core/src/main/res/drawable/ic_certificate.xml index 6091e969..780e4db4 100644 --- a/play-services-core/src/main/res/drawable/certificate.xml +++ b/play-services-core/src/main/res/drawable/ic_certificate.xml @@ -1,13 +1,14 @@ + android:width="24dp" + android:height="24dp" + android:tint="?attr/colorAccent" + android:viewportWidth="24" + android:viewportHeight="24"> - \ No newline at end of file + diff --git a/play-services-core/src/main/res/drawable/gcm_bell.xml b/play-services-core/src/main/res/drawable/ic_cloud_bell.xml similarity index 79% rename from play-services-core/src/main/res/drawable/gcm_bell.xml rename to play-services-core/src/main/res/drawable/ic_cloud_bell.xml index 89a1cae4..0f41c719 100644 --- a/play-services-core/src/main/res/drawable/gcm_bell.xml +++ b/play-services-core/src/main/res/drawable/ic_cloud_bell.xml @@ -1,11 +1,12 @@ + android:width="24dp" + android:height="24dp" + android:tint="?attr/colorAccent" + android:viewportWidth="24" + android:viewportHeight="24"> - \ No newline at end of file + android:pathData="M 12 4 C 9.11 4 6.5996094 5.6392969 5.3496094 8.0292969 C 2.3396094 8.3592969 0 10.9 0 14 A 6 6 0 0 0 6 20 L 19 20 A 5 5 0 0 0 24 15 C 24 12.36 21.949609 10.219297 19.349609 10.029297 C 18.669609 6.5892969 15.64 4 12 4 z M 12 7.5 A 0.5 0.5 0 0 1 12.5 8 L 12.5 8.5390625 C 13.92 8.7790625 15 10.015 15 11.5 L 15 14.5 L 16.5 16 L 7.5 16 L 9 14.5 L 9 11.5 C 9 10.015 10.08 8.7790625 11.5 8.5390625 L 11.5 8 A 0.5 0.5 0 0 1 12 7.5 z M 11 16.5 L 13 16.5 A 1 1 0 0 1 12 17.5 A 1 1 0 0 1 11 16.5 z" /> + diff --git a/play-services-core/src/main/res/drawable/device_login.xml b/play-services-core/src/main/res/drawable/ic_device_login.xml similarity index 58% rename from play-services-core/src/main/res/drawable/device_login.xml rename to play-services-core/src/main/res/drawable/ic_device_login.xml index f1a4e1e4..c0bce50c 100644 --- a/play-services-core/src/main/res/drawable/device_login.xml +++ b/play-services-core/src/main/res/drawable/ic_device_login.xml @@ -1,11 +1,12 @@ + android:width="24dp" + android:height="24dp" + android:tint="?attr/colorAccent" + android:viewportWidth="24" + android:viewportHeight="24"> - \ No newline at end of file + android:pathData="M10,17.25V14H3V10H10V6.75L15.25,12L10,17.25M8,2H17A2,2 0 0,1 19,4V20A2,2 0 0,1 17,22H8A2,2 0 0,1 6,20V16H8V20H17V4H8V8H6V4A2,2 0 0,1 8,2Z" /> + diff --git a/play-services-core/src/main/res/drawable/ic_expand_apps.xml b/play-services-core/src/main/res/drawable/ic_expand_apps.xml new file mode 100644 index 00000000..20634f05 --- /dev/null +++ b/play-services-core/src/main/res/drawable/ic_expand_apps.xml @@ -0,0 +1,19 @@ + + + + + + diff --git a/play-services-core/src/main/res/drawable/ic_info_outline.xml b/play-services-core/src/main/res/drawable/ic_info_outline.xml new file mode 100644 index 00000000..8e049cce --- /dev/null +++ b/play-services-core/src/main/res/drawable/ic_info_outline.xml @@ -0,0 +1,17 @@ + + + + + + diff --git a/play-services-core/src/main/res/drawable/ic_map_marker.xml b/play-services-core/src/main/res/drawable/ic_map_marker.xml new file mode 100644 index 00000000..b97f8b8d --- /dev/null +++ b/play-services-core/src/main/res/drawable/ic_map_marker.xml @@ -0,0 +1,17 @@ + + + + + + diff --git a/play-services-core/src/main/res/layout/ask_gcm.xml b/play-services-core/src/main/res/layout/ask_gcm.xml index 9d3e8be8..a5c20212 100644 --- a/play-services-core/src/main/res/layout/ask_gcm.xml +++ b/play-services-core/src/main/res/layout/ask_gcm.xml @@ -48,7 +48,7 @@ android:layout_width="36dip" android:layout_height="36dip" android:scaleType="fitCenter" - android:src="@drawable/gcm_bell" + android:src="@drawable/ic_cloud_bell" android:tint="?attr/colorAccent"> diff --git a/play-services-core/src/main/res/layout/device_registration_fragment.xml b/play-services-core/src/main/res/layout/device_registration_fragment.xml new file mode 100644 index 00000000..0f0648dc --- /dev/null +++ b/play-services-core/src/main/res/layout/device_registration_fragment.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + diff --git a/play-services-core/src/main/res/layout/preference_category_no_label.xml b/play-services-core/src/main/res/layout/preference_category_no_label.xml new file mode 100644 index 00000000..31b8b654 --- /dev/null +++ b/play-services-core/src/main/res/layout/preference_category_no_label.xml @@ -0,0 +1,9 @@ + + + + diff --git a/play-services-core/src/main/res/layout/preference_progress_bar.xml b/play-services-core/src/main/res/layout/preference_progress_bar.xml new file mode 100644 index 00000000..bd0eb7e0 --- /dev/null +++ b/play-services-core/src/main/res/layout/preference_progress_bar.xml @@ -0,0 +1,17 @@ + + + + + + + diff --git a/play-services-core/src/main/res/layout/preference_switch_bar.xml b/play-services-core/src/main/res/layout/preference_switch_bar.xml new file mode 100644 index 00000000..08ad6530 --- /dev/null +++ b/play-services-core/src/main/res/layout/preference_switch_bar.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/play-services-core/src/main/res/layout/push_notification_app_fragment.xml b/play-services-core/src/main/res/layout/push_notification_app_fragment.xml new file mode 100644 index 00000000..4f63f961 --- /dev/null +++ b/play-services-core/src/main/res/layout/push_notification_app_fragment.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/play-services-core/src/main/res/layout/push_notification_fragment.xml b/play-services-core/src/main/res/layout/push_notification_fragment.xml new file mode 100644 index 00000000..e9611b83 --- /dev/null +++ b/play-services-core/src/main/res/layout/push_notification_fragment.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/play-services-core/src/main/res/layout/safety_net_fragment.xml b/play-services-core/src/main/res/layout/safety_net_fragment.xml new file mode 100644 index 00000000..e97378ae --- /dev/null +++ b/play-services-core/src/main/res/layout/safety_net_fragment.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/play-services-core/src/main/res/layout/settings_root_activity.xml b/play-services-core/src/main/res/layout/settings_root_activity.xml new file mode 100644 index 00000000..a592e38d --- /dev/null +++ b/play-services-core/src/main/res/layout/settings_root_activity.xml @@ -0,0 +1,19 @@ + + + + + + diff --git a/play-services-core/src/main/res/navigation/nav_settings.xml b/play-services-core/src/main/res/navigation/nav_settings.xml new file mode 100644 index 00000000..4a7a5246 --- /dev/null +++ b/play-services-core/src/main/res/navigation/nav_settings.xml @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/play-services-core/src/main/res/values/strings.xml b/play-services-core/src/main/res/values/strings.xml index 66b626ce..cfc7fd85 100644 --- a/play-services-core/src/main/res/values/strings.xml +++ b/play-services-core/src/main/res/values/strings.xml @@ -61,6 +61,8 @@ This can take a couple of minutes." Enabled Automatic Manual + On + Off Advanced None diff --git a/play-services-core/src/main/res/xml/preferences_checkin.xml b/play-services-core/src/main/res/xml/preferences_checkin.xml deleted file mode 100644 index 45c982a7..00000000 --- a/play-services-core/src/main/res/xml/preferences_checkin.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - \ No newline at end of file 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 new file mode 100644 index 00000000..886ec0b7 --- /dev/null +++ b/play-services-core/src/main/res/xml/preferences_device_registration.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + diff --git a/play-services-core/src/main/res/xml/preferences_gcm_app_detail.xml b/play-services-core/src/main/res/xml/preferences_gcm_app_detail.xml deleted file mode 100644 index 3dc8186a..00000000 --- a/play-services-core/src/main/res/xml/preferences_gcm_app_detail.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/play-services-core/src/main/res/xml/preferences_push_notifications.xml b/play-services-core/src/main/res/xml/preferences_push_notifications.xml new file mode 100644 index 00000000..06c8fb8a --- /dev/null +++ b/play-services-core/src/main/res/xml/preferences_push_notifications.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + diff --git a/play-services-core/src/main/res/xml/preferences_push_notifications_all_apps.xml b/play-services-core/src/main/res/xml/preferences_push_notifications_all_apps.xml new file mode 100644 index 00000000..6c0f2d36 --- /dev/null +++ b/play-services-core/src/main/res/xml/preferences_push_notifications_all_apps.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + diff --git a/play-services-core/src/main/res/xml/preferences_push_notifications_app.xml b/play-services-core/src/main/res/xml/preferences_push_notifications_app.xml new file mode 100644 index 00000000..fad13b22 --- /dev/null +++ b/play-services-core/src/main/res/xml/preferences_push_notifications_app.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/play-services-core/src/main/res/xml/preferences_snet.xml b/play-services-core/src/main/res/xml/preferences_safetynet.xml similarity index 70% rename from play-services-core/src/main/res/xml/preferences_snet.xml rename to play-services-core/src/main/res/xml/preferences_safetynet.xml index 8a60cf3e..e0a2ed84 100644 --- a/play-services-core/src/main/res/xml/preferences_snet.xml +++ b/play-services-core/src/main/res/xml/preferences_safetynet.xml @@ -16,16 +16,20 @@ --> + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto"> - + android:selectable="false" + android:summary="@string/snet_intro" /> + + android:title="@string/pref_snet_testdrive_title" /> - \ No newline at end of file + diff --git a/play-services-core/src/main/res/xml/preferences_start.xml b/play-services-core/src/main/res/xml/preferences_start.xml index c51f7dc5..b48d5b7a 100644 --- a/play-services-core/src/main/res/xml/preferences_start.xml +++ b/play-services-core/src/main/res/xml/preferences_start.xml @@ -14,75 +14,59 @@ ~ limitations under the License. --> - - - + + - + android:targetPackage="com.google.android.gms" /> + - - - + + - - - + - - - + - - - + + android:title="@string/pref_more_settings" + app:isPreferenceVisible="false"> - + android:targetPackage="com.google.android.gms" /> + - - + - - + android:title="@string/nlp_backends_title" /> - - + - - + android:title="@string/pref_about_title" />