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 58c9a14b..00000000
Binary files a/play-services-core/src/main/res/drawable-hdpi/ic_map_marker.png and /dev/null differ
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 c84ada96..00000000
Binary files a/play-services-core/src/main/res/drawable-ldpi/add_account.png and /dev/null differ
diff --git a/play-services-core/src/main/res/drawable-mdpi/add_account.png b/play-services-core/src/main/res/drawable-mdpi/add_account.png
deleted file mode 100644
index 7cbdff98..00000000
Binary files a/play-services-core/src/main/res/drawable-mdpi/add_account.png and /dev/null differ
diff --git a/play-services-core/src/main/res/drawable-mdpi/ic_map_marker.png b/play-services-core/src/main/res/drawable-mdpi/ic_map_marker.png
deleted file mode 100644
index f66ef501..00000000
Binary files a/play-services-core/src/main/res/drawable-mdpi/ic_map_marker.png and /dev/null differ
diff --git a/play-services-core/src/main/res/drawable-xhdpi/add_account.png b/play-services-core/src/main/res/drawable-xhdpi/add_account.png
deleted file mode 100644
index bf14e0a7..00000000
Binary files a/play-services-core/src/main/res/drawable-xhdpi/add_account.png and /dev/null differ
diff --git a/play-services-core/src/main/res/drawable-xhdpi/ic_map_marker.png b/play-services-core/src/main/res/drawable-xhdpi/ic_map_marker.png
deleted file mode 100644
index 00d32aa4..00000000
Binary files a/play-services-core/src/main/res/drawable-xhdpi/ic_map_marker.png and /dev/null differ
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 53264c28..00000000
Binary files a/play-services-core/src/main/res/drawable-xxhdpi/add_account.png and /dev/null differ
diff --git a/play-services-core/src/main/res/drawable-xxhdpi/ic_map_marker.png b/play-services-core/src/main/res/drawable-xxhdpi/ic_map_marker.png
deleted file mode 100644
index 78a7dbe2..00000000
Binary files a/play-services-core/src/main/res/drawable-xxhdpi/ic_map_marker.png and /dev/null differ
diff --git a/play-services-core/src/main/res/drawable-xxxhdpi/add_account.png b/play-services-core/src/main/res/drawable-xxxhdpi/add_account.png
deleted file mode 100644
index a03e2eaa..00000000
Binary files a/play-services-core/src/main/res/drawable-xxxhdpi/add_account.png and /dev/null differ
diff --git a/play-services-core/src/main/res/drawable-xxxhdpi/ic_map_marker.png b/play-services-core/src/main/res/drawable-xxxhdpi/ic_map_marker.png
deleted file mode 100644
index 66945c5a..00000000
Binary files a/play-services-core/src/main/res/drawable-xxxhdpi/ic_map_marker.png and /dev/null differ
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" />