Add initial UI for new features

This commit is contained in:
Marvin W 2022-01-18 18:49:35 +01:00
parent e3b042ccd7
commit fd8ce71a83
No known key found for this signature in database
GPG Key ID: 072E9235DB996F2A
40 changed files with 838 additions and 310 deletions

121
LICENSES/CC0-1.0.txt Normal file
View File

@ -0,0 +1,121 @@
Creative Commons Legal Code
CC0 1.0 Universal
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
HEREUNDER.
Statement of Purpose
The laws of most jurisdictions throughout the world automatically confer
exclusive Copyright and Related Rights (defined below) upon the creator
and subsequent owner(s) (each and all, an "owner") of an original work of
authorship and/or a database (each, a "Work").
Certain owners wish to permanently relinquish those rights to a Work for
the purpose of contributing to a commons of creative, cultural and
scientific works ("Commons") that the public can reliably and without fear
of later claims of infringement build upon, modify, incorporate in other
works, reuse and redistribute as freely as possible in any form whatsoever
and for any purposes, including without limitation commercial purposes.
These owners may contribute to the Commons to promote the ideal of a free
culture and the further production of creative, cultural and scientific
works, or to gain reputation or greater distribution for their Work in
part through the use and efforts of others.
For these and/or other purposes and motivations, and without any
expectation of additional consideration or compensation, the person
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
is an owner of Copyright and Related Rights in the Work, voluntarily
elects to apply CC0 to the Work and publicly distribute the Work under its
terms, with knowledge of his or her Copyright and Related Rights in the
Work and the meaning and intended legal effect of CC0 on those rights.
1. Copyright and Related Rights. A Work made available under CC0 may be
protected by copyright and related or neighboring rights ("Copyright and
Related Rights"). Copyright and Related Rights include, but are not
limited to, the following:
i. the right to reproduce, adapt, distribute, perform, display,
communicate, and translate a Work;
ii. moral rights retained by the original author(s) and/or performer(s);
iii. publicity and privacy rights pertaining to a person's image or
likeness depicted in a Work;
iv. rights protecting against unfair competition in regards to a Work,
subject to the limitations in paragraph 4(a), below;
v. rights protecting the extraction, dissemination, use and reuse of data
in a Work;
vi. database rights (such as those arising under Directive 96/9/EC of the
European Parliament and of the Council of 11 March 1996 on the legal
protection of databases, and under any national implementation
thereof, including any amended or successor version of such
directive); and
vii. other similar, equivalent or corresponding rights throughout the
world based on applicable law or treaty, and any national
implementations thereof.
2. Waiver. To the greatest extent permitted by, but not in contravention
of, applicable law, Affirmer hereby overtly, fully, permanently,
irrevocably and unconditionally waives, abandons, and surrenders all of
Affirmer's Copyright and Related Rights and associated claims and causes
of action, whether now known or unknown (including existing as well as
future claims and causes of action), in the Work (i) in all territories
worldwide, (ii) for the maximum duration provided by applicable law or
treaty (including future time extensions), (iii) in any current or future
medium and for any number of copies, and (iv) for any purpose whatsoever,
including without limitation commercial, advertising or promotional
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
member of the public at large and to the detriment of Affirmer's heirs and
successors, fully intending that such Waiver shall not be subject to
revocation, rescission, cancellation, termination, or any other legal or
equitable action to disrupt the quiet enjoyment of the Work by the public
as contemplated by Affirmer's express Statement of Purpose.
3. Public License Fallback. Should any part of the Waiver for any reason
be judged legally invalid or ineffective under applicable law, then the
Waiver shall be preserved to the maximum extent permitted taking into
account Affirmer's express Statement of Purpose. In addition, to the
extent the Waiver is so judged Affirmer hereby grants to each affected
person a royalty-free, non transferable, non sublicensable, non exclusive,
irrevocable and unconditional license to exercise Affirmer's Copyright and
Related Rights in the Work (i) in all territories worldwide, (ii) for the
maximum duration provided by applicable law or treaty (including future
time extensions), (iii) in any current or future medium and for any number
of copies, and (iv) for any purpose whatsoever, including without
limitation commercial, advertising or promotional purposes (the
"License"). The License shall be deemed effective as of the date CC0 was
applied by Affirmer to the Work. Should any part of the License for any
reason be judged legally invalid or ineffective under applicable law, such
partial invalidity or ineffectiveness shall not invalidate the remainder
of the License, and in such case Affirmer hereby affirms that he or she
will not (i) exercise any of his or her remaining Copyright and Related
Rights in the Work or (ii) assert any associated claims and causes of
action with respect to the Work, in either case contrary to Affirmer's
express Statement of Purpose.
4. Limitations and Disclaimers.
a. No trademark or patent rights held by Affirmer are waived, abandoned,
surrendered, licensed or otherwise affected by this document.
b. Affirmer offers the Work as-is and makes no representations or
warranties of any kind concerning the Work, express, implied,
statutory or otherwise, including without limitation warranties of
title, merchantability, fitness for a particular purpose, non
infringement, or the absence of latent or other defects, accuracy, or
the present or absence of errors, whether or not discoverable, all to
the greatest extent permissible under applicable law.
c. Affirmer disclaims responsibility for clearing rights of other persons
that may apply to the Work or any use thereof, including without
limitation any person's Copyright and Related Rights in the Work.
Further, Affirmer disclaims responsibility for obtaining any necessary
consents, permissions or other rights required for any use of the
Work.
d. Affirmer understands and acknowledges that Creative Commons is not a
party to this document and has no duty or obligation with respect to
this CC0 or use of the Work.

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ SPDX-FileCopyrightText: 2021 microG Project Team
~ SPDX-License-Identifier: Apache-2.0
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/on"
android:drawable="@drawable/ic_radio_checked"
android:state_checked="true" />
<item
android:id="@+id/off"
android:drawable="@drawable/ic_radio_unchecked"
android:state_checked="false" />
</selector>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ SPDX-FileCopyrightText: 2019 The Android Open Source Project
~ SPDX-FileCopyrightText: 2021 microG Project Team
~ SPDX-License-Identifier: Apache-2.0
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorAccent"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M12,7c-2.76,0 -5,2.24 -5,5s2.24,5 5,5 5,-2.24 5,-5 -2.24,-5 -5,-5zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8z" />
</vector>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ SPDX-FileCopyrightText: 2019 The Android Open Source Project
~ SPDX-FileCopyrightText: 2021 microG Project Team
~ SPDX-License-Identifier: Apache-2.0
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8z" />
</vector>

View File

@ -44,11 +44,12 @@ dependencies {
implementation project(':play-services-base-core-ui')
implementation project(':play-services-conscrypt-provider-core')
implementation project(':play-services-cronet-core')
implementation project(':play-services-droidguard') // TODO: Move to play-services-safetynet-core once we have it
implementation project(':play-services-droidguard-core')
implementation project(':play-services-droidguard-core-ui')
implementation project(':play-services-location-core')
withNearbyImplementation project(':play-services-nearby-core')
withNearbyImplementation project(':play-services-nearby-core-ui')
implementation project(':play-services-safetynet-core')
implementation project(':play-services-tapandpay-core')
implementation project(':play-services-vision-core')
@ -58,7 +59,11 @@ dependencies {
implementation project(':play-services-cast-api')
implementation project(':play-services-wearable')
implementation "org.microg:wearable:$wearableVersion"
implementation "org.microg.gms:remote-droid-guard:$remoteDroidGuardVersion"
runtimeOnly "org.microg.nlp:geocode-v1:$nlpVersion"
runtimeOnly "org.microg.nlp:location-v2:$nlpVersion"
runtimeOnly "org.microg.nlp:location-v3:$nlpVersion"
implementation "org.microg.nlp:ui:$nlpVersion"
withMapboxImplementation project(':play-services-maps-core-mapbox')
withVtmImplementation project(':play-services-maps-core-vtm')

View File

@ -28,58 +28,58 @@ import org.microg.tools.ui.AbstractSettingsActivity;
import org.microg.tools.ui.RadioButtonPreference;
import org.microg.tools.ui.ResourceSettingsFragment;
import static org.microg.gms.safetynet.SafetyNetPrefs.PREF_SNET_OFFICIAL;
import static org.microg.gms.safetynet.SafetyNetPrefs.PREF_SNET_SELF_SIGNED;
import static org.microg.gms.safetynet.SafetyNetPrefs.PREF_SNET_THIRD_PARTY;
//import static org.microg.gms.safetynet.SafetyNetPrefs.PREF_SNET_OFFICIAL;
//import static org.microg.gms.safetynet.SafetyNetPrefs.PREF_SNET_SELF_SIGNED;
//import static org.microg.gms.safetynet.SafetyNetPrefs.PREF_SNET_THIRD_PARTY;
public class SafetyNetAdvancedFragment extends ResourceSettingsFragment {
public SafetyNetAdvancedFragment() {
preferencesResource = R.xml.preferences_snet_advanced;
}
private RadioButtonPreference radioOfficial;
private RadioButtonPreference radioSelfSigned;
private RadioButtonPreference radioThirdParty;
@Override
public void onCreatePreferences(@Nullable Bundle savedInstanceState, String rootKey) {
super.onCreatePreferences(savedInstanceState, rootKey);
radioOfficial = (RadioButtonPreference) findPreference(PREF_SNET_OFFICIAL);
radioSelfSigned = (RadioButtonPreference) findPreference(PREF_SNET_SELF_SIGNED);
radioThirdParty = (RadioButtonPreference) findPreference(PREF_SNET_THIRD_PARTY);
}
@Override
public boolean onPreferenceTreeClick(Preference preference) {
if (preference == radioOfficial) {
radioOfficial.setChecked(true);
radioSelfSigned.setChecked(false);
radioThirdParty.setChecked(false);
return true;
} else if (preference == radioSelfSigned) {
radioOfficial.setChecked(false);
radioSelfSigned.setChecked(true);
radioThirdParty.setChecked(false);
return true;
} else if (preference == radioThirdParty) {
radioOfficial.setChecked(false);
radioSelfSigned.setChecked(false);
radioThirdParty.setChecked(true);
return true;
}
return super.onPreferenceTreeClick(preference);
}
public static class AsActivity extends AbstractSettingsActivity {
public AsActivity() {
showHomeAsUp = true;
}
@Override
protected Fragment getFragment() {
return new SafetyNetAdvancedFragment();
}
}
}
//public class SafetyNetAdvancedFragment extends ResourceSettingsFragment {
//
// public SafetyNetAdvancedFragment() {
// preferencesResource = R.xml.preferences_snet_advanced;
// }
//
// private RadioButtonPreference radioOfficial;
// private RadioButtonPreference radioSelfSigned;
// private RadioButtonPreference radioThirdParty;
//
// @Override
// public void onCreatePreferences(@Nullable Bundle savedInstanceState, String rootKey) {
// super.onCreatePreferences(savedInstanceState, rootKey);
//
// radioOfficial = (RadioButtonPreference) findPreference(PREF_SNET_OFFICIAL);
// radioSelfSigned = (RadioButtonPreference) findPreference(PREF_SNET_SELF_SIGNED);
// radioThirdParty = (RadioButtonPreference) findPreference(PREF_SNET_THIRD_PARTY);
// }
//
// @Override
// public boolean onPreferenceTreeClick(Preference preference) {
// if (preference == radioOfficial) {
// radioOfficial.setChecked(true);
// radioSelfSigned.setChecked(false);
// radioThirdParty.setChecked(false);
// return true;
// } else if (preference == radioSelfSigned) {
// radioOfficial.setChecked(false);
// radioSelfSigned.setChecked(true);
// radioThirdParty.setChecked(false);
// return true;
// } else if (preference == radioThirdParty) {
// radioOfficial.setChecked(false);
// radioSelfSigned.setChecked(false);
// radioThirdParty.setChecked(true);
// return true;
// }
// return super.onPreferenceTreeClick(preference);
// }
//
// public static class AsActivity extends AbstractSettingsActivity {
// public AsActivity() {
// showHomeAsUp = true;
// }
//
// @Override
// protected Fragment getFragment() {
// return new SafetyNetAdvancedFragment();
// }
// }
//}

View File

@ -0,0 +1,12 @@
/*
* SPDX-FileCopyrightText: 2021 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package org.microg.gms.ui
import androidx.fragment.app.Fragment
import com.google.android.gms.R
class SafetyNetAdvancedFragment : Fragment(R.layout.safety_net_advanced_fragment) {
}

View File

@ -12,10 +12,9 @@ import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import com.google.android.gms.R
import com.google.android.gms.databinding.SafetyNetFragmentBinding
import org.microg.gms.checkin.getCheckinServiceInfo
import org.microg.gms.safetynet.ServiceInfo
import org.microg.gms.safetynet.getSafetyNetServiceInfo
import org.microg.gms.safetynet.setSafetyNetServiceConfiguration
import org.microg.gms.checkin.CheckinPrefs
import org.microg.gms.droidguard.core.DroidGuardPreferences
import org.microg.gms.safetynet.SafetyNetPreferences
class SafetyNetFragment : Fragment(R.layout.safety_net_fragment) {
@ -34,22 +33,22 @@ class SafetyNetFragment : Fragment(R.layout.safety_net_fragment) {
fun setEnabled(newStatus: Boolean) {
val appContext = requireContext().applicationContext
lifecycleScope.launchWhenResumed {
val info = getSafetyNetServiceInfo(appContext)
val newConfiguration = info.configuration.copy(enabled = newStatus)
displayServiceInfo(setSafetyNetServiceConfiguration(appContext, newConfiguration))
SafetyNetPreferences.setEnabled(appContext, newStatus)
DroidGuardPreferences.setEnabled(appContext, newStatus)
displayServiceInfo()
}
}
fun displayServiceInfo(serviceInfo: ServiceInfo) {
binding.safetynetEnabled = serviceInfo.configuration.enabled
fun displayServiceInfo() {
binding.safetynetEnabled = SafetyNetPreferences.isEnabled(requireContext()) && DroidGuardPreferences.isEnabled(requireContext())
}
override fun onResume() {
super.onResume()
val appContext = requireContext().applicationContext
lifecycleScope.launchWhenResumed {
binding.checkinEnabled = getCheckinServiceInfo(appContext).configuration.enabled
displayServiceInfo(getSafetyNetServiceInfo(appContext))
binding.checkinEnabled = CheckinPrefs.isEnabled(appContext)
displayServiceInfo()
}
}

View File

@ -6,12 +6,117 @@
package org.microg.gms.ui
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.util.Base64
import android.util.Log
import androidx.lifecycle.lifecycleScope
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import com.google.android.gms.R
import com.google.android.gms.common.api.Status
import com.google.android.gms.safetynet.AttestationData
import com.google.android.gms.safetynet.RecaptchaResultData
import com.google.android.gms.safetynet.internal.ISafetyNetCallbacks
import org.json.JSONException
import org.json.JSONObject
import org.microg.gms.safetynet.SafetyNetClientService
import org.microg.gms.safetynet.SafetyNetClientServiceImpl
import kotlin.random.Random
class SafetyNetPreferencesFragment : PreferenceFragmentCompat() {
private lateinit var runAttest: Preference
private lateinit var runReCaptcha: Preference
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
addPreferencesFromResource(R.xml.preferences_safetynet)
}
override fun onBindPreferences() {
runAttest = preferenceScreen.findPreference("pref_snet_run_attest") ?: runAttest
runReCaptcha = preferenceScreen.findPreference("pref_recaptcha_run_test") ?: runReCaptcha
// TODO: Use SafetyNet client library once ready
runAttest.setOnPreferenceClickListener {
val context = context ?: return@setOnPreferenceClickListener false
runAttest.setIcon(R.drawable.ic_circle_pending)
runAttest.setSummary(R.string.pref_test_summary_running)
val handler = Handler(Looper.myLooper()!!)
SafetyNetClientServiceImpl(context, "com.scottyab.safetynet.sample", lifecycle).attestWithApiKey(object : ISafetyNetCallbacks.Default() {
override fun onAttestationData(status: Status?, attestationData: AttestationData?) {
handler.post {
if (status?.isSuccess == true) {
if (attestationData?.jwsResult == null) {
runAttest.setIcon(R.drawable.ic_circle_warn)
runAttest.summary = context.getString(R.string.pref_test_summary_failed, "No result")
} else {
val (_, payload, _) = try {
attestationData.jwsResult.split(".")
} catch (e: Exception) {
runAttest.setIcon(R.drawable.ic_circle_error)
runAttest.summary = context.getString(R.string.pref_test_summary_failed, "Invalid JWS")
return@post
}
val (basicIntegrity, ctsProfileMatch, advice) = try {
JSONObject(Base64.decode(payload, Base64.URL_SAFE).decodeToString()).let {
Triple(it.optBoolean("basicIntegrity", false), it.optBoolean("ctsProfileMatch", false), it.optString("advice", ""))
}
} catch (e: Exception) {
Log.w(TAG, e)
runAttest.setIcon(R.drawable.ic_circle_error)
runAttest.summary = context.getString(R.string.pref_test_summary_failed, "Invalid JSON")
return@post
}
val adviceText = if (advice == "") "" else "\n" + advice.split(",").map {
when (it) {
"LOCK_BOOTLOADER" -> "Bootloader is not locked"
"RESTORE_TO_FACTORY_ROM" -> "ROM is not clean"
else -> it
}
}.joinToString("\n")
when {
basicIntegrity && ctsProfileMatch -> {
runAttest.setIcon(R.drawable.ic_circle_check)
runAttest.setSummary(R.string.pref_test_summary_passed)
}
basicIntegrity -> {
runAttest.setIcon(R.drawable.ic_circle_warn)
runAttest.summary = context.getString(R.string.pref_test_summary_warn, "CTS profile does not match$adviceText")
}
else -> {
runAttest.setIcon(R.drawable.ic_circle_error)
runAttest.summary = context.getString(R.string.pref_test_summary_failed, "integrity check failed$adviceText")
}
}
}
} else {
runAttest.setIcon(R.drawable.ic_circle_error)
runAttest.summary = context.getString(R.string.pref_test_summary_failed, status?.statusMessage)
}
}
}
}, Random.nextBytes(32), "AIzaSyAfcNLBpWkqrt50mluU6GswUmtysmLn9cY")
true
}
runReCaptcha.setOnPreferenceClickListener {
val context = context ?: return@setOnPreferenceClickListener false
runReCaptcha.setIcon(R.drawable.ic_circle_pending)
runReCaptcha.setSummary(R.string.pref_test_summary_running)
val handler = Handler(Looper.myLooper()!!)
SafetyNetClientServiceImpl(context, "com.blogspot.android_er.recaptcha", lifecycle).verifyWithRecaptcha(object : ISafetyNetCallbacks.Default() {
override fun onRecaptchaResult(status: Status?, recaptchaResultData: RecaptchaResultData?) {
handler.post {
if (status?.isSuccess == true) {
runReCaptcha.setIcon(R.drawable.ic_circle_check)
runReCaptcha.setSummary(R.string.pref_test_summary_passed)
} else {
runReCaptcha.setIcon(R.drawable.ic_circle_error)
runReCaptcha.summary = context.getString(R.string.pref_test_summary_failed, status?.statusMessage)
}
}
}
}, "6LdMKyUUAAAAAN0ndw7byI03_qpbpjxKY-mTQnLw")
true
}
}
}

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ SPDX-FileCopyrightText: 2019, The Android Open Source Project
~ SPDX-FileCopyrightText: 2021, microG Project Team
~ SPDX-License-Identifier: Apache-2.0
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorAccent"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM10,17l-5,-5 1.41,-1.41L10,14.17l7.59,-7.59L19,8l-9,9z" />
</vector>

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ SPDX-FileCopyrightText: 2019, Austin Andrews
~ SPDX-FileCopyrightText: 2021, microG Project Team
~ SPDX-License-Identifier: Apache-2.0
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorError"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M12,2C17.53,2 22,6.47 22,12C22,17.53 17.53,22 12,22C6.47,22 2,17.53 2,12C2,6.47 6.47,2 12,2M15.59,7L12,10.59L8.41,7L7,8.41L10.59,12L7,15.59L8.41,17L12,13.41L15.59,17L17,15.59L13.41,12L17,8.41L15.59,7Z" />
</vector>

View File

@ -0,0 +1,19 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorAccent">
<path
android:fillColor="@android:color/white"
android:pathData="M12,2C6.48,2 2,6.48 2,12c0,5.52 4.48,10 10,10s10,-4.48 10,-10C22,6.48 17.52,2 12,2zM12,20c-4.42,0 -8,-3.58 -8,-8c0,-4.42 3.58,-8 8,-8s8,3.58 8,8C20,16.42 16.42,20 12,20z"/>
<path
android:fillColor="@android:color/white"
android:pathData="M7,12m-1.5,0a1.5,1.5 0,1 1,3 0a1.5,1.5 0,1 1,-3 0"/>
<path
android:fillColor="@android:color/white"
android:pathData="M12,12m-1.5,0a1.5,1.5 0,1 1,3 0a1.5,1.5 0,1 1,-3 0"/>
<path
android:fillColor="@android:color/white"
android:pathData="M17,12m-1.5,0a1.5,1.5 0,1 1,3 0a1.5,1.5 0,1 1,-3 0"/>
</vector>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ SPDX-FileCopyrightText: 2019, The Android Open Source Project
~ SPDX-FileCopyrightText: 2021, microG Project Team
~ SPDX-License-Identifier: Apache-2.0
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorError"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M11,15h2v2h-2zM11,7h2v6h-2zM11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10C17.52,22 22,17.52 22,12S17.52,2 11.99,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8z" />
</vector>

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ SPDX-FileCopyrightText: 2021 microG Project Team
~ SPDX-License-Identifier: Apache-2.0
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/droidguard_sub_preferences"
android:name="org.microg.gms.droidguard.core.ui.DroidGuardPreferencesFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
</LinearLayout>

View File

@ -114,7 +114,6 @@
<string name="prefcat_configuration">Канфігурацыя</string>
<string name="prefcat_google_services">Google сэрвісы</string>
<string name="prefcat_location_service">Служба вызначэння месцазнаходжання</string>
<string name="prefcat_operation_mode">Рэжым работы</string>
<string name="prefcat_services">Сэрвісы</string>
<string name="prefcat_test">Тэст</string>
@ -181,21 +180,10 @@
<string name="prefcat_push_apps_unregistered_title">Незарэгістраваныя прыкладанні</string>
<string name="prefcat_push_networks_title">Сеткі для прыёму push-паведамленняў</string>
<string name="snet_intro">Google SafetyNet гэта сістэма сертыфікацыі прылады, якая гарантуе, што прылада карэктна абаронена і сумяшчальна з Android CTS. Пэўныя праграмы выкарыстоўваюць SafetyNet з меркаванняў бяспекі або ў якасці папярэдняй сістэмы абароны ад узлому.\n\nmicroG GmsCore змяшчае свабодную рэалізацыю SafetyNet, але афіцыйны сервер патрабуе, каб запыты былі падпісаны з дапамогай прапрыетарнай сістэмы DroidGuard. Ізаляваная версія DroidGuard даступная як асобнае прыкладанне "DroidGuard Helper".</string>
<string name="snet_intro">Google SafetyNet гэта сістэма сертыфікацыі прылады, якая гарантуе, што прылада карэктна абаронена і сумяшчальна з Android CTS. Пэўныя праграмы выкарыстоўваюць SafetyNet з меркаванняў бяспекі або ў якасці папярэдняй сістэмы абароны ад узлому.\n\nmicroG GmsCore змяшчае свабодную рэалізацыю SafetyNet, але афіцыйны сервер патрабуе, каб запыты былі падпісаны з дапамогай прапрыетарнай сістэмы DroidGuard.</string>
<string name="snet_enable_switch">Дазволіць праверку статусу прылады</string>
<string name="pref_snet_testdrive_title">Тэст верыфікацыі SafetyNet</string>
<string name="pref_snet_status_official_title">Выкарыстоўваць афіцыйны сервер</string>
<string name="pref_snet_status_official_summary">Патрабуецца сістэма без root і ўсталяваны microG DroidGuard Helper</string>
<string name="pref_snet_status_official_info">афіцыйны сервер</string>
<string name="pref_snet_status_third_party_title">Выкарыстоўваць іншы сервер</string>
<string name="pref_snet_status_third_party_summary">Іншыя серверы могуць быць у стане адказаць на запыты SafetyNet без подпісу DroidGuard</string>
<string name="pref_snet_status_third_party_info">іншы сервер</string>
<string name="pref_snet_custom_url_title">URL іншага сервера</string>
<string name="pref_snet_custom_url_summary">Поўны URL іншага сервера, які адказвае на праверачныя запыты SafetyNet</string>
<string name="pref_snet_self_signed_title">Выкарыстоўваць самастойна падпісаны сертыфікат</string>
<string name="pref_snet_self_signed_summary">Замест запытаў на сервер падпісваць SafetyNet лакальна, выкарыстоўваючы самастойна створаны сертыфікат. Большасць прыкладанняў будуць адмаўляцца выкарыстоўваць самастойна падпісаныя адказы.</string>
<string name="pref_snet_status_self_signed_info">самастойна падпісаны сертыфікат</string>
<string name="pref_safetynet_test_title">Тэст верыфікацыі SafetyNet</string>
<string name="pref_droidguard_operation_mode">Рэжым работы</string>
</resources>

View File

@ -114,7 +114,6 @@ Dies kann einige Minuten dauern."</string>
<string name="prefcat_configuration">Einstellungen</string>
<string name="prefcat_google_services">Google-Dienste</string>
<string name="prefcat_location_service">Standortdienst</string>
<string name="prefcat_operation_mode">Modus</string>
<string name="prefcat_services">Dienste</string>
<string name="prefcat_test">Test</string>
@ -180,21 +179,10 @@ Dies kann einige Minuten dauern."</string>
<string name="prefcat_push_apps_unregistered_title">Nicht-registrierte Apps</string>
<string name="prefcat_push_networks_title">Verwendbare Netzwerke</string>
<string name="snet_intro">Google SafetyNet ist ein System, um Geräte zu zertifizieren und so sicherzustellen, dass sie ausreichend geschützt und kompatibel mit Android sind. Einige Anwendungen benutzen SafetyNet aus Sicherheitsgründen oder um einen Kopierschutz zu erzwingen.\n\nmicroG GmsCore enthält eine freie Implementierung von SafetyNet, jedoch verlangen die Google-Server, dass die Anfragen durch das proprietäre DroidGuard signiert sind. Eine unschädliche gemachte Version von DroidGuard ist als separate \"DroidGuard Helper\"-App verfügbar.</string>
<string name="snet_intro">Google SafetyNet ist ein System, um Geräte zu zertifizieren und so sicherzustellen, dass sie ausreichend geschützt und kompatibel mit Android sind. Einige Anwendungen benutzen SafetyNet aus Sicherheitsgründen oder um einen Kopierschutz zu erzwingen.\n\nmicroG GmsCore enthält eine freie Implementierung von SafetyNet, jedoch verlangen die Google-Server, dass die Anfragen durch das proprietäre DroidGuard signiert sind.</string>
<string name="snet_enable_switch">Geräte-Zertifizierung erlauben</string>
<string name="pref_snet_testdrive_title">SafetyNet-Zertifizierung testen</string>
<string name="pref_snet_status_official_title">Offizielle Server nutzen</string>
<string name="pref_snet_status_official_summary">Erfordert eine ungerootetes ROM und den microG DroidGuard Helper</string>
<string name="pref_snet_status_official_info">offizieller Server</string>
<string name="pref_snet_status_third_party_title">Alternativen Server nutzen</string>
<string name="pref_snet_status_third_party_summary">Alternative Server können auch SafetyNet-Anfragen beantworten, die nicht durch DroidGuard signiert wurden</string>
<string name="pref_snet_status_third_party_info">Dritt-Server</string>
<string name="pref_snet_custom_url_title">Alternative Server URL</string>
<string name="pref_snet_custom_url_summary">Vollständige URL des alternativen Servers, der SafetyNet-Anfragen beantwortet</string>
<string name="pref_snet_self_signed_title">Selbst signieren</string>
<string name="pref_snet_self_signed_summary">Statt einen Server zu nutzen, die SafetyNet Signatur lokal mit einem eigens erstellten Zertifikat signieren. Die meisten Apps werden diese Signaturen nicht akzeptieren.</string>
<string name="pref_snet_status_self_signed_info">Selbst-signiertes Zertifikat</string>
<string name="pref_safetynet_test_title">SafetyNet-Zertifizierung testen</string>
<string name="pref_droidguard_operation_mode">Modus</string>
</resources>

View File

@ -112,7 +112,6 @@ Esto podría tardar algunos minutos."</string>
<string name="prefcat_configuration">Configuración</string>
<string name="prefcat_google_services">Servicios de Google</string>
<string name="prefcat_location_service">Servicio de localización</string>
<string name="prefcat_operation_mode">Modo de operación</string>
<string name="prefcat_services">Servicios</string>
<string name="prefcat_test">Prueba</string>
@ -179,21 +178,10 @@ Esto podría tardar algunos minutos."</string>
<string name="prefcat_push_apps_unregistered_title">Aplicaciones no registradas</string>
<string name="prefcat_push_networks_title">Redes a utilizar para las notificaciones push</string>
<string name="snet_intro">Google SafetyNet es un sistema de certificación de dispositivos, que garantiza que el dispositivo está correctamente asegurado y es compatible con Android CTS. Algunas aplicaciones utilizan SafetyNet por razones de seguridad o como un prerrequisito para la protección contra manipulaciones.\n\nmicroG GmsCore contiene una implementación gratuita de SafetyNet, pero el servidor oficial requiere que las solicitudes de SafetyNet sean firmadas utilizando el sistema propietario DroidGuard. Una versión en sandbox de DroidGuard está disponible como una aplicación separada "DroidGuard Helper".</string>
<string name="snet_intro">Google SafetyNet es un sistema de certificación de dispositivos, que garantiza que el dispositivo está correctamente asegurado y es compatible con Android CTS. Algunas aplicaciones utilizan SafetyNet por razones de seguridad o como un prerrequisito para la protección contra manipulaciones.\n\nmicroG GmsCore contiene una implementación gratuita de SafetyNet, pero el servidor oficial requiere que las solicitudes de SafetyNet sean firmadas utilizando el sistema propietario DroidGuard.</string>
<string name="snet_enable_switch">Permitir la certificación del dispositivo</string>
<string name="pref_snet_testdrive_title">Probar el certificado de SafetyNet</string>
<string name="pref_snet_status_official_title">Usar el servidor oficial</string>
<string name="pref_snet_status_official_summary">Requiere un sistema no root y un microG DroidGuard Helper instalado</string>
<string name="pref_snet_status_official_info">servidor oficial</string>
<string name="pref_snet_status_third_party_title">Usar un servidor de terceros</string>
<string name="pref_snet_status_third_party_summary">Los servidores de terceros podrían responder a las solicitudes de SafetyNet sin la firma de DroidGuard</string>
<string name="pref_snet_status_third_party_info">servidor de terceros</string>
<string name="pref_snet_custom_url_title">URL del servidor personalizada</string>
<string name="pref_snet_custom_url_summary">URL completa del servidor de terceros que responde a las solicitudes de certificación de SafetyNet</string>
<string name="pref_snet_self_signed_title">Usar un certificado autofirmado</string>
<string name="pref_snet_self_signed_summary">En lugar de solicitar un servidor, firma las respuestas de SafetyNet localmente usando un certificado autofirmado. La mayoría de las aplicaciones se negarán a usar respuestas autofirmadas.</string>
<string name="pref_snet_status_self_signed_info">certificado autofirmado</string>
<string name="pref_safetynet_test_title">Probar el certificado de SafetyNet</string>
<string name="pref_droidguard_operation_mode">Modo de operación</string>
</resources>

View File

@ -102,7 +102,6 @@ Ceci peut prendre plusieurs minutes."</string>
<string name="prefcat_configuration">Configuration</string>
<string name="prefcat_google_services">Services Google</string>
<string name="prefcat_location_service">Service de localisation</string>
<string name="prefcat_operation_mode">Mode dopération</string>
<string name="prefcat_services">Services</string>
<string name="prefcat_test">Test</string>
@ -149,18 +148,8 @@ Ceci peut prendre plusieurs minutes."</string>
<string name="gcm_network_state_disconnected">Déconnecté</string>
<string name="gcm_network_state_connected">Connecté depuis <xliff:g example="2 hours ago">%1$s</xliff:g></string>
<string name="snet_intro">Google SafetyNet est un système de certification du terminal, assurant que celui-ci est correctement sécurisé et compatible avec Android CTS. Certaines applications utilisent SafetyNet pour des raisons de sécurité ou comme prérequis anti-altérations.\n\nmicroG GmsCore contient une implantation libre de SafetyNet, mais les serveurs officiels requièrent que les requêtes SafetyNet soient signées par le système propriétaire DroidGuard. Une version mise en «bac-à-sable» de DroidGuard est disponible dans une application séparée «DroidGuard Helper».
</string>
<string name="pref_snet_testdrive_title">Tester la certification SafetyNet</string>
<string name="pref_snet_status_official_title">Utiliser les serveurs officiels</string>
<string name="pref_snet_status_official_summary">Nécessite un système non-rooté et microG DroidGuard Helper installé</string>
<string name="pref_snet_status_third_party_title">Utiliser un serveur tiers</string>
<string name="pref_snet_status_third_party_summary">Les serveurs tiers peuvent être capable de répondre aux requêtes SafetyNet sans signature de DroidGuard.</string>
<string name="pref_snet_custom_url_title">URL serveur tiers</string>
<string name="pref_snet_custom_url_summary">URL complète du serveur tiers répondant aux requêtes de certification SafetyNet</string>
<string name="pref_snet_self_signed_title">Utiliser un certificat auto-signé</string>
<string name="pref_snet_self_signed_summary">Au lieu de requérir un serveur, signer les réponses SafetyNet localement en utilisant un certificat auto-signé. La plupart des applications refuseront dutiliser des réponses auto-signées.</string>
<string name="snet_intro">Google SafetyNet est un système de certification du terminal, assurant que celui-ci est correctement sécurisé et compatible avec Android CTS. Certaines applications utilisent SafetyNet pour des raisons de sécurité ou comme prérequis anti-altérations.\n\nmicroG GmsCore contient une implantation libre de SafetyNet, mais les serveurs officiels requièrent que les requêtes SafetyNet soient signées par le système propriétaire DroidGuard.</string>
<string name="pref_safetynet_test_title">Tester la certification SafetyNet</string>
<string name="pref_droidguard_operation_mode">Mode dopération</string>
</resources>

View File

@ -106,7 +106,6 @@ Questa operazione può richiedere alcuni secondi."</string>
<string name="prefcat_configuration">Configurazione</string>
<string name="prefcat_google_services">Servizi Google</string>
<string name="prefcat_location_service">Servizi di localizzazione</string>
<string name="prefcat_operation_mode">Modalità operativa</string>
<string name="prefcat_services">Servizi</string>
<string name="prefcat_test">Sperimentale</string>
@ -174,21 +173,10 @@ Questa operazione può richiedere alcuni secondi."</string>
<string name="prefcat_push_apps_unregistered_title">Applicazioni non registrate</string>
<string name="prefcat_push_networks_title">Reti da utilizzare per le notifiche push</string>
<string name="snet_intro">SafetyNet di Google è un sistema di certificazione del dispositivo che ne garantisce la sicurezza e la compatibilità con Android CTS. Alcune applicazioni utilizzano SafetyNet per ragioni di sicurezza o come prerequisito per la protezione da manomissione.\n\nUn\'implementazione libera di SafetyNet è contenuta in microG, tuttavia i server ufficiali richiedono che le richieste SafetyNet siano firmate utilizzando il sistema proprietario DroidGuard. Una versione isolata di DroidGuard è disponibile all\'interno dell\'applicazione “microG DroidGuard Helper”.</string>
<string name="snet_intro">SafetyNet di Google è un sistema di certificazione del dispositivo che ne garantisce la sicurezza e la compatibilità con Android CTS. Alcune applicazioni utilizzano SafetyNet per ragioni di sicurezza o come prerequisito per la protezione da manomissione.\n\nUn\'implementazione libera di SafetyNet è contenuta in microG, tuttavia i server ufficiali richiedono che le richieste SafetyNet siano firmate utilizzando il sistema proprietario DroidGuard.</string>
<string name="snet_enable_switch">Permetti l\'attestazione del dispositivo</string>
<string name="pref_snet_testdrive_title">Prova l\'attestazione di SafetyNet</string>
<string name="pref_snet_status_official_title">Utilizza i server ufficiali</string>
<string name="pref_snet_status_official_summary">Richiede un sistema senza privilegi di root e con l\'applicazione "microG DroidGuard Helper" installata</string>
<string name="pref_snet_status_official_info">Server ufficiale</string>
<string name="pref_snet_status_third_party_title">Utilizza un server di terze parti</string>
<string name="pref_snet_status_third_party_summary">I server di terze parti potrebbero essere in grado di rispondere alle richieste di SafetyNet senza la firma di DroidGuard</string>
<string name="pref_snet_status_third_party_info">Server di terze parti</string>
<string name="pref_snet_custom_url_title">URL del server personalizzato</string>
<string name="pref_snet_custom_url_summary">URL completo del server personalizzato che risponde alle richieste di attestazione SafetyNet</string>
<string name="pref_snet_self_signed_title">Utilizza un certificato auto-firmato</string>
<string name="pref_snet_self_signed_summary">Anziché inoltrare le richieste a un server, firma localmente le risposte SafetyNet utilizzando un certificato auto-firmato. La maggior parte delle applicazioni rifiuteranno l\'uso di risposte auto-firmate.</string>
<string name="pref_snet_status_self_signed_info">Certificato auto-firmato</string>
<string name="pref_safetynet_test_title">Prova l\'attestazione di SafetyNet</string>
<string name="pref_droidguard_operation_mode">Modalità operativa</string>
</resources>

View File

@ -109,7 +109,6 @@
<string name="prefcat_configuration">設定</string>
<string name="prefcat_google_services">Googleサービス</string>
<string name="prefcat_location_service">位置情報サービス</string>
<string name="prefcat_operation_mode">動作モード</string>
<string name="prefcat_services">サービス</string>
<string name="prefcat_test">テスト</string>
@ -171,20 +170,9 @@
<string name="snet_intro">Google SafetyNetはデバイス認証システムであり、デバイスが適切に保護され、Android CTSと互換性があることを保証します。 一部のアプリケーションは、セキュリティ上の理由または改ざん防止の前提条件としてSafetyNetを使用します。
microG GmsCoreにはSafetyNetのオープンソースな実装が含まれていますが、公式サーバーでは、プロプライエタリなDroidGuardシステムを使用してSafetyNetリクエストに署名する必要があります。 DroidGuardのサンドボックスバージョンは、個別の「DroidGuardHelper」アプリとして利用できます。</string>
microG GmsCoreにはSafetyNetのオープンソースな実装が含まれていますが、公式サーバーでは、プロプライエタリなDroidGuardシステムを使用してSafetyNetリクエストに署名する必要があります。</string>
<string name="snet_enable_switch">デバイスの認証を許可</string>
<string name="pref_snet_testdrive_title">SafetyNetテストの実行</string>
<string name="pref_snet_status_official_title">公式サーバーを使用</string>
<string name="pref_snet_status_official_summary">root化されていないシステムと、microG DroidGuardHelperのインストールが必要です。</string>
<string name="pref_snet_status_official_info">公式サーバー</string>
<string name="pref_snet_status_third_party_title">サードパーティのサーバーを使用</string>
<string name="pref_snet_status_third_party_summary">サードパーティのサーバーは、DroidGuardの署名がないSafetyNetリクエストに応答できる場合があります</string>
<string name="pref_snet_status_third_party_info">third-party server</string>
<string name="pref_snet_custom_url_title">カスタムサーバーのURL</string>
<string name="pref_snet_custom_url_summary">SafetyNet認証リクエストに応答するサードパーティサーバーの完全なURL</string>
<string name="pref_snet_self_signed_title">自己署名証明書を使用</string>
<string name="pref_snet_self_signed_summary">サーバーにリクエストする代わりに、自己署名証明書を使用してローカルでSafetyNet応答に署名します。 ほとんどのアプリは、自己署名証明書を使用した応答の使用を拒否します。</string>
<string name="pref_snet_status_self_signed_info">自己署名証明書</string>
<string name="pref_safetynet_test_title">SafetyNetテストの実行</string>
<string name="pref_droidguard_operation_mode">動作モード</string>
</resources>

View File

@ -102,7 +102,6 @@ To zajmie kilka minut.</string>
<string name="prefcat_configuration">Konfiguracja</string>
<string name="prefcat_google_services">Usługi Google</string>
<string name="prefcat_location_service">Usługa lokalizacji</string>
<string name="prefcat_operation_mode">Tryb działania</string>
<string name="prefcat_services">Usługi w tle</string>
<string name="prefcat_test">Test</string>
@ -147,17 +146,8 @@ To zajmie kilka minut.</string>
<string name="gcm_unregister_after_deny_message">Odmówiłeś już zarejestrowanej aplikacji zarejestrować się w usłudze powiadomień push.\nCzy chcesz ją wyrejestrować, aby nie otrzymywała powiadomień push w przyszłości?</string>
<string name="gcm_messages_counter">Wiadomości: <xliff:g example="123">%1$d</xliff:g> (<xliff:g example="12345">%2$d</xliff:g> bajtów)</string>
<string name="snet_intro">Google SafetyNet jest systemem certyfikacji urządzenia, który upewnia się czy urządzenie jest poprawnie zabezpieczone i kompatybilne z Android CTS. Niektóre aplikacje używają SafetyNet ze względów bezpieczeństwa lub jako przeciwśrodek do modyfikacji.\n\nUsługa microG GmsCore zawiera wolną implementację SafetyNet, ale oficjalny serwer wymaga by SafetyNet był podpisany przez własnościowy system DroidGuard. Specjalna wersja DroidGuard-a jest dostępna do pobrania jako oddzielna aplikacja “DroidGuard Helper” w repozytorium miroG w F-Droid.</string>
<string name="pref_snet_testdrive_title">Wypróbuj działanie SafetyNet</string>
<string name="pref_snet_status_official_title">Użyj oficjalnego serwera</string>
<string name="pref_snet_status_official_summary">Wymaga niezrootowanego ROM-u i zainstalowanego microG DroidGuard Helper</string>
<string name="pref_snet_status_third_party_title">Użyj serwera strony trzeciej</string>
<string name="pref_snet_status_third_party_summary">Serwery stron trzecich mogą być w stanie odpowiedzieć na zapytania SafetyNet bez sygnatury DroidGuard</string>
<string name="pref_snet_custom_url_title">URL własnego serwera</string>
<string name="pref_snet_custom_url_summary">Pełny adres URL serwera strony trzeciej odpowiadającego na zapytania SafetyNet</string>
<string name="pref_snet_self_signed_title">Użyj samo-podpisanego certyfikatu</string>
<string name="pref_snet_self_signed_summary">Zamiast sprawdzać serwer, podpisuj odpowiedzi SafetyNet lokalnie używając samo-podpisanego certyfikatu. Większość aplikacji odmówi użycia samo-podpisanych odpowiedzi.</string>
<string name="snet_intro">Google SafetyNet jest systemem certyfikacji urządzenia, który upewnia się czy urządzenie jest poprawnie zabezpieczone i kompatybilne z Android CTS. Niektóre aplikacje używają SafetyNet ze względów bezpieczeństwa lub jako przeciwśrodek do modyfikacji.\n\nUsługa microG GmsCore zawiera wolną implementację SafetyNet, ale oficjalny serwer wymaga by SafetyNet był podpisany przez własnościowy system DroidGuard.</string>
<string name="pref_safetynet_test_title">Wypróbuj działanie SafetyNet</string>
<string name="pref_droidguard_operation_mode">Tryb działania</string>
</resources>

View File

@ -114,7 +114,6 @@
<string name="prefcat_configuration">Конфигурация</string>
<string name="prefcat_google_services">Google сервисы</string>
<string name="prefcat_location_service">Служба определения местоположения</string>
<string name="prefcat_operation_mode">Режим работы</string>
<string name="prefcat_services">Сервисы</string>
<string name="prefcat_test">Тест</string>
@ -181,22 +180,11 @@
<string name="prefcat_push_apps_unregistered_title">Незарегистрированные приложения</string>
<string name="prefcat_push_networks_title">Сети для приёма push-уведомлений</string>
<string name="snet_intro">Google SafetyNet это система сертификации устройства, гарантирующая, что устройство корректно защищено и совместимо с Android CTS. Некоторые приложения используют SafetyNet из соображений безопасности или в качестве предварительной системы защиты от взлома.\n\nmicroG GmsCore содержит свободную реализацию SafetyNet, но официальный сервер требует, чтобы запросы были подписаны с помощью проприетарной системы DroidGuard. Изолированная версия DroidGuard доступна как отдельное приложение "DroidGuard Helper".</string>
<string name="snet_intro">Google SafetyNet это система сертификации устройства, гарантирующая, что устройство корректно защищено и совместимо с Android CTS. Некоторые приложения используют SafetyNet из соображений безопасности или в качестве предварительной системы защиты от взлома.\n\nmicroG GmsCore содержит свободную реализацию SafetyNet, но официальный сервер требует, чтобы запросы были подписаны с помощью проприетарной системы DroidGuard.</string>
<string name="snet_enable_switch">Разрешить проверку статуса устройства</string>
<string name="pref_snet_testdrive_title">Тест верификации SafetyNet</string>
<string name="pref_snet_status_official_title">Использовать официальный сервер</string>
<string name="pref_snet_status_official_summary">Требуется система без root и установленный microG DroidGuard Helper</string>
<string name="pref_snet_status_official_info">официальный сервер</string>
<string name="pref_snet_status_third_party_title">Использовать сторонний сервер</string>
<string name="pref_snet_status_third_party_summary">Сторонние сервера могут быть в состоянии ответить на запросы SafetyNet без подписи DroidGuard</string>
<string name="pref_snet_status_third_party_info">сторонний сервер</string>
<string name="pref_snet_custom_url_title">URL стороннего сервера</string>
<string name="pref_snet_custom_url_summary">Полный URL стороннего сервера, который отвечает на проверочные запросы SafetyNet</string>
<string name="pref_snet_self_signed_title">Использовать самоподписанный сертификат</string>
<string name="pref_snet_self_signed_summary">Вместо запросов на сервер подписывать SafetyNet локально, используя самостоятельно созданный сертификат. Большинство приложений будут отказываться использовать самоподписанные ответы.</string>
<string name="pref_snet_status_self_signed_info">самоподписанный сертификат</string>
<string name="pref_safetynet_test_title">Тест верификации SafetyNet</string>
<string name="pref_droidguard_operation_mode">Режим работы</string>
</resources>

View File

@ -109,7 +109,6 @@
<string name="prefcat_configuration">Конфігурація</string>
<string name="prefcat_google_services">Сервіси Google</string>
<string name="prefcat_location_service">Сервіси позиціювання</string>
<string name="prefcat_operation_mode">Режим роботи</string>
<string name="prefcat_services">Сервіси</string>
<string name="prefcat_test">Тест</string>
@ -154,17 +153,8 @@
<string name="gcm_unregister_after_deny_message">Ви заборонили додатку push-повідомлення, який вже був прив\'язаний.\nВи бажаєте відв\'язати його зараз, аби більше не отримувати від нього push-повідомлень?</string>
<string name="gcm_messages_counter">Повідомлень: <xliff:g example="123">%1$d</xliff:g> (<xliff:g example="12345">%2$d</xliff:g> байт)</string>
<string name="snet_intro">Google SafetyNet це система сертифікації пристрою, яка гарантує, що пристрій коректно захищено та сумісне із Android CTS. Деякі додатки використовують SafetyNet для безпеки або в якості попередньої системи захисту від злому.\n\nmicroG GmsCore містить вільну реалізацію SafetyNet, але офіційний сервер вимагає, аби запити були підписані за допомогою закритої програмної системи DroidGuard. Ізольована версія DroidGuard доступна для встановлення як окремий додаток \"DroidGuard Helper\".</string>
<string name="pref_snet_testdrive_title">Протестувати SafetyNet перевірку</string>
<string name="pref_snet_status_official_title">Використовувати офіційний сервер</string>
<string name="pref_snet_status_official_summary">Потребує систему з адміністративними правами та встановленим microG DroidGuard Helper</string>
<string name="pref_snet_status_third_party_title">Використовувати сторонній сервер</string>
<string name="pref_snet_status_third_party_summary">Сторонні сервери можуть відповідати на SafetyNet запити без підпису DroidGuard</string>
<string name="pref_snet_custom_url_title">Посилання стороннього серверу</string>
<string name="pref_snet_custom_url_summary">Повне посилання стороннього серверу, який відповідає на запити SafetyNet</string>
<string name="pref_snet_self_signed_title">Використовувати самостійно підписаний сертифікат</string>
<string name="pref_snet_self_signed_summary">Підписувати SafetyNet локально, замість запитів на сервер, використовуючи само-підписний сертифікат. Більшість додатків будуть відхиляти само-підписні відповіді.</string>
<string name="snet_intro">Google SafetyNet це система сертифікації пристрою, яка гарантує, що пристрій коректно захищено та сумісне із Android CTS. Деякі додатки використовують SafetyNet для безпеки або в якості попередньої системи захисту від злому.\n\nmicroG GmsCore містить вільну реалізацію SafetyNet, але офіційний сервер вимагає, аби запити були підписані за допомогою закритої програмної системи DroidGuard.</string>
<string name="pref_safetynet_test_title">Протестувати SafetyNet перевірку</string>
<string name="pref_droidguard_operation_mode">Режим роботи</string>
</resources>

View File

@ -138,16 +138,7 @@
<string name="snet_intro">Google SafetyNet是一個確認手機被確實保護和相容於Android CTS的驗證系統。一些程式基於安全因素使用SafetyNet一些則是以必須通過的形式來防止篡改。
microG GmsCore包含了SafetyNet的自由執行但官方伺服器需要SafetyNet請求經非自由軟體性質的DroidGuard系統簽名。有一個可用的沙盒測試版本DroidGuard獨立程式“DroidGuard Helper”。</string>
microG GmsCore包含了SafetyNet的自由執行但官方伺服器需要SafetyNet請求經非自由軟體性質的DroidGuard系統簽名。</string>
<string name="pref_snet_testdrive_title">測試SafetyNet驗證</string>
<string name="pref_snet_status_official_title">使用官方伺服器</string>
<string name="pref_snet_status_official_summary">需要未root的系統及安裝microG DroidGuard Helper</string>
<string name="pref_snet_status_third_party_title">使用第三方伺服器</string>
<string name="pref_snet_status_third_party_summary">第三方伺服器可能不需要DroidGuard簽名便能回應SafetyNet請求</string>
<string name="pref_snet_custom_url_title">自訂伺服器網址</string>
<string name="pref_snet_custom_url_summary">回應SafetyNet驗證請求之第三方伺服器的完整網址</string>
<string name="pref_snet_self_signed_title">使用自行簽名認證</string>
<string name="pref_snet_self_signed_summary">不向伺服器請求簽名而是用本地的認證文件自行簽名SafetyNet。大部分的程式都會拒絕自行簽名認證。</string>
<string name="pref_safetynet_test_title">測試SafetyNet驗證</string>
</resources>

View File

@ -1,19 +1,8 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ 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.
<?xml version="1.0" encoding="utf-8"?>
<!--
~ SPDX-FileCopyrightText: 2017 microG Project Team
~ SPDX-License-Identifier: Apache-2.0
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="gms_app_name">microG Services Core</string>
<string name="gms_settings_name">microG Settings</string>
@ -114,7 +103,6 @@ This can take a couple of minutes."</string>
<string name="prefcat_configuration">Configuration</string>
<string name="prefcat_google_services">Google Services</string>
<string name="prefcat_location_service">Location service</string>
<string name="prefcat_operation_mode">Operation mode</string>
<string name="prefcat_services">Services</string>
<string name="prefcat_test">Test</string>
@ -182,21 +170,15 @@ This can take a couple of minutes."</string>
<string name="prefcat_push_apps_unregistered_title">Unregistered apps</string>
<string name="prefcat_push_networks_title">Networks to use for push notifications</string>
<string name="snet_intro">Google SafetyNet is a device certification system, ensuring that the device is properly secured and compatible with Android CTS. Some applications use SafetyNet for security reasons or as a prerequisite for tamper-protection.\n\nmicroG GmsCore contains a free implementation of SafetyNet, but the official server requires SafetyNet requests to be signed using the proprietary DroidGuard system. A sandboxed version of DroidGuard is available as a separate “DroidGuard Helper” app.</string>
<string name="snet_intro">Google SafetyNet is a device certification system, ensuring that the device is properly secured and compatible with Android CTS. Some applications use SafetyNet for security reasons or as a prerequisite for tamper-protection.\n\nmicroG GmsCore contains a free implementation of SafetyNet, but the official server requires SafetyNet requests to be signed using the proprietary DroidGuard system.</string>
<string name="snet_enable_switch">Allow device attestation</string>
<string name="pref_snet_testdrive_title">Try SafetyNet attestation</string>
<string name="pref_snet_status_official_title">Use official server</string>
<string name="pref_snet_status_official_summary">Requires an unrooted system and microG DroidGuard Helper installed</string>
<string name="pref_snet_status_official_info">official server</string>
<string name="pref_snet_status_third_party_title">Use third-party server</string>
<string name="pref_snet_status_third_party_summary">Third-party servers might be able to reply to SafetyNet requests without DroidGuard signature</string>
<string name="pref_snet_status_third_party_info">third-party server</string>
<string name="pref_snet_custom_url_title">Custom server URL</string>
<string name="pref_snet_custom_url_summary">Full URL of the third-party server answering SafetyNet attestation requests</string>
<string name="pref_snet_self_signed_title">Use self-signed certificate</string>
<string name="pref_snet_self_signed_summary">Instead of requesting a server, sign SafetyNet responses locally using a self-signed certificate. Most apps will refuse to use self-signed responses.</string>
<string name="pref_snet_status_self_signed_info">self-signed certificate</string>
<string name="pref_safetynet_test_title">Test SafetyNet attestation</string>
<string name="pref_recaptcha_test_title">Test ReCAPTCHA</string>
<string name="pref_test_summary_passed">Passed all tests</string>
<string name="pref_test_summary_failed">Failed: %s</string>
<string name="pref_test_summary_warn">Warning: %s</string>
<string name="pref_test_summary_running">Running…</string>
<string name="pref_droidguard_operation_mode">Operation mode</string>
</resources>

View File

@ -6,17 +6,29 @@
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<PreferenceCategory
android:key="prefcat_device_profile"
android:title="Device profile">
<ListPreference
android:key="pref_device_profile"
android:title="Select profile"
tools:summary="Automatic (Google Pixel 3, Android 11)" />
<Preference
android:key="pref_device_profile_import"
android:summary="Import device profile from file"
android:title="Import profile" />
</PreferenceCategory>
<PreferenceCategory
android:key="prefcat_device_registration_status"
android:layout="@layout/preference_category_no_label">
<Preference
android:enabled="false"
android:key="pref_device_registration_status"
android:selectable="false"
android:title="@string/pref_info_status"
tools:summary="Last registration: 13 hours ago" />
<Preference
android:enabled="false"
android:key="pref_device_registration_android_id"
android:selectable="false"
android:title="@string/pref_device_registration_android_id"
tools:summary="1953a59d1c1b7e4b" />
</PreferenceCategory>

View File

@ -1,32 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ 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.
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<Preference
android:selectable="false"
android:summary="@string/pref_gcm_enable_mcs_summary"/>
<Preference
android:key="pref_gcm_status"
android:persistent="false"
android:selectable="false"
android:summary="Current state: Connected since 2 min ago"/>
<PreferenceCategory
android:key="gcm_apps"
android:title="@string/pref_gcm_apps_title"/>
</PreferenceScreen>

View File

@ -26,7 +26,7 @@
android:layout="@layout/preference_category_no_label">
<Preference
android:key="pref_push_status"
android:selectable="false"
android:enabled="false"
android:title="@string/pref_info_status"
tools:summary="Connected since 15 minutes ago" />
</PreferenceCategory>

View File

@ -17,19 +17,26 @@
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<org.microg.gms.ui.TextPreference
android:icon="@drawable/ic_info_outline"
android:key="pref_snet_summary"
android:selectable="false"
android:summary="@string/snet_intro" />
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<PreferenceCategory
android:title="@string/prefcat_test"
app:isPreferenceVisible="false">
android:layout="@layout/preference_category_no_label">
<Preference
android:enabled="false"
android:key="pref_snet_run_attest"
android:summary="Not yet available"
android:title="@string/pref_snet_testdrive_title" />
android:title="@string/pref_safetynet_test_title"
tools:icon="@drawable/ic_circle_check"
tools:summary="@string/pref_test_summary_passed" />
<Preference
android:key="pref_recaptcha_run_test"
android:title="@string/pref_recaptcha_test_title"
tools:icon="@drawable/ic_circle_check"
tools:summary="@string/pref_test_summary_passed" />
</PreferenceCategory>
<PreferenceCategory android:layout="@layout/preference_category_no_label">
<org.microg.gms.ui.TextPreference
android:icon="@drawable/ic_info_outline"
android:key="pref_snet_summary"
android:selectable="false"
android:summary="@string/snet_intro" />
</PreferenceCategory>
</PreferenceScreen>

View File

@ -15,29 +15,12 @@
~ limitations under the License.
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory android:title="@string/prefcat_operation_mode">
<org.microg.tools.ui.RadioButtonPreference
android:checked="true"
android:key="snet_official"
android:summary="@string/pref_snet_status_official_summary"
android:title="@string/pref_snet_status_official_title"/>
<org.microg.tools.ui.RadioButtonPreference
android:checked="false"
android:enabled="false"
android:key="snet_self_signed"
android:summary="@string/pref_snet_self_signed_summary"
android:title="@string/pref_snet_self_signed_title"/>
<org.microg.tools.ui.RadioButtonPreference
android:checked="false"
android:key="snet_third_party"
android:summary="@string/pref_snet_status_third_party_summary"
android:title="@string/pref_snet_status_third_party_title"/>
<EditTextPreference
android:dependency="snet_third_party"
android:hint="https://example.com/server?key=123"
android:key="snet_custom_url"
android:summary="@string/pref_snet_custom_url_summary"
android:title="@string/pref_snet_custom_url_title"/>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<PreferenceCategory android:title="DroidGuard">
<Preference
android:key="pref_droidguard_mode"
android:title="@string/pref_droidguard_operation_mode"
tools:summary="Local (embedded)" />
</PreferenceCategory>
</PreferenceScreen>
</PreferenceScreen>

View File

@ -12,11 +12,12 @@ import android.net.Uri
import androidx.core.content.ContextCompat
import com.google.android.gms.R
import org.microg.gms.nearby.exposurenotification.Constants
import org.microg.gms.nearby.exposurenotification.ExposurePreferences
import org.microg.gms.nearby.exposurenotification.getExposureNotificationsServiceInfo
interface NearbyPreferencesIntegration {
companion object {
suspend fun getExposurePreferenceSummary(context: Context): String = if (isAvailable && getExposureNotificationsServiceInfo(context).configuration.enabled) {
suspend fun getExposurePreferenceSummary(context: Context): String = if (isAvailable && ExposurePreferences(context).enabled) {
context.getString(R.string.service_status_enabled_short)
} else {
context.getString(R.string.service_status_disabled_short)

View File

@ -0,0 +1,53 @@
/*
* SPDX-FileCopyrightText: 2021, microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'maven-publish'
apply plugin: 'signing'
dependencies {
implementation project(':play-services-droidguard-core')
implementation project(':play-services-base-core-ui')
implementation "androidx.appcompat:appcompat:$appcompatVersion"
implementation "androidx.preference:preference-ktx:$preferenceVersion"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion"
}
android {
compileSdkVersion androidCompileSdk
buildToolsVersion "$androidBuildVersionTools"
defaultConfig {
versionName version
minSdkVersion androidMinSdk
targetSdkVersion androidTargetSdk
}
sourceSets {
main {
java.srcDirs = ['src/main/kotlin']
}
}
lintOptions {
disable 'MissingTranslation'
}
compileOptions {
sourceCompatibility = 1.8
targetCompatibility = 1.8
}
kotlinOptions {
jvmTarget = 1.8
}
}
apply from: '../gradle/publish-android.gradle'
description = 'UI for microG service implementation for play-services-droidguard'

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ SPDX-FileCopyrightText: 2021, microG Project Team
~ SPDX-License-Identifier: Apache-2.0
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="org.microg.gms.droidguard.core.ui">
<application />
</manifest>

View File

@ -0,0 +1,69 @@
/*
* SPDX-FileCopyrightText: 2021 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package org.microg.gms.droidguard.core.ui
import android.content.Context
import android.text.TextWatcher
import android.util.AttributeSet
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import androidx.core.widget.addTextChangedListener
import androidx.preference.Preference
import androidx.preference.PreferenceViewHolder
class ContainedEditTextPreference : Preference {
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes)
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
constructor(context: Context) : super(context)
override fun onBindViewHolder(holder: PreferenceViewHolder) {
super.onBindViewHolder(holder)
val editText = holder.itemView.findViewById<EditText>(android.R.id.edit)
(editText as? TextWatcher)?.let { editText.removeTextChangedListener(it) }
editText.addTextChangedListener { textChangedListener(it?.toString() ?: "") }
editText.tag = this
editText.hint = hint
editText.text.replace(0, editText.text.length, text)
editText.isEnabled = editable
if (requestFocus) {
editText.requestFocus()
(editText.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager).showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT)
requestFocus = false
}
}
private var requestFocus: Boolean = false
fun editRequestFocus() {
requestFocus = true
notifyChanged()
}
var textChangedListener: (String) -> Unit = {}
var editable: Boolean = true
set(value) {
field = value
notifyChanged()
}
var text: String = ""
set(value) {
field = value
notifyChanged()
}
var hint: String = ""
set(value) {
field = value
notifyChanged()
}
init {
layoutResource = R.layout.preference_material_with_widget_below
widgetLayoutResource = R.layout.preference_edit_widget
}
}

View File

@ -0,0 +1,53 @@
/*
* SPDX-FileCopyrightText: 2021 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package org.microg.gms.droidguard.core.ui
import android.os.Bundle
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import org.microg.gms.droidguard.core.DroidGuardPreferences
import org.microg.gms.droidguard.core.DroidGuardPreferences.Mode.Embedded
import org.microg.gms.droidguard.core.DroidGuardPreferences.Mode.Network
import org.microg.gms.droidguard.core.ui.R.drawable.ic_radio_checked
import org.microg.gms.droidguard.core.ui.R.drawable.ic_radio_unchecked
class DroidGuardPreferencesFragment : PreferenceFragmentCompat() {
private lateinit var modeEmbedded: Preference
private lateinit var modeNetwork: ContainedEditTextPreference
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
addPreferencesFromResource(R.xml.preferences_droidguard)
}
override fun onBindPreferences() {
modeEmbedded = preferenceScreen.findPreference("pref_droidguard_mode_embedded") ?: modeEmbedded
modeNetwork = preferenceScreen.findPreference("pref_droidguard_mode_network") ?: modeNetwork
modeEmbedded.setOnPreferenceClickListener {
DroidGuardPreferences.setMode(it.context, Embedded)
updateConfiguration()
true
}
modeNetwork.setOnPreferenceClickListener {
DroidGuardPreferences.setMode(it.context, Network)
modeNetwork.editRequestFocus()
updateConfiguration()
true
}
modeNetwork.textChangedListener = {
DroidGuardPreferences.setNetworkServerUrl(requireContext(), it)
}
updateConfiguration()
}
fun updateConfiguration() {
val mode = DroidGuardPreferences.getMode(requireContext())
modeEmbedded.setIcon(if (mode == Embedded) ic_radio_checked else ic_radio_unchecked)
modeNetwork.setIcon(if (mode == Network) ic_radio_checked else ic_radio_unchecked)
modeNetwork.text = DroidGuardPreferences.getNetworkServerUrl(requireContext()) ?: ""
modeNetwork.editable = mode == Network
modeNetwork.hint = "https://example.com/droidguard/"
}
}

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ SPDX-FileCopyrightText: 2021 microG Project Team
~ SPDX-License-Identifier: Apache-2.0
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:id="@android:id/edit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusedByDefault="false"
android:inputType="textUri"
android:lines="1"
android:maxLines="1" />
</LinearLayout>

View File

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2015 The Android Open Source Project
~
~ 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
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeightSmall"
android:gravity="center_vertical"
android:paddingLeft="?android:attr/listPreferredItemPaddingLeft"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:paddingRight="?android:attr/listPreferredItemPaddingRight"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:background="?android:attr/selectableItemBackground"
android:clipToPadding="false"
android:baselineAligned="false">
<include layout="@layout/image_frame"/>
<RelativeLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingTop="16dp"
android:paddingBottom="16dp">
<TextView
android:id="@android:id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceListItem"
android:ellipsize="marquee"/>
<TextView
android:id="@android:id/summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@android:id/title"
android:layout_alignLeft="@android:id/title"
android:layout_alignStart="@android:id/title"
android:layout_gravity="start"
android:textAlignment="viewStart"
android:textColor="?android:attr/textColorSecondary"
android:maxLines="10"
style="@style/PreferenceSummaryTextStyle"/>
<!-- Preference should place its actual preference widget here. -->
<LinearLayout
android:id="@android:id/widget_frame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@android:id/summary"
android:layout_alignLeft="@android:id/title"
android:layout_alignStart="@android:id/title"
android:gravity="end|center_vertical"
android:orientation="vertical"/>
</RelativeLayout>
</LinearLayout>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ SPDX-FileCopyrightText: 2021 microG Project Team
~ SPDX-License-Identifier: Apache-2.0
-->
<resources>
<string name="prefcat_droidguard_mode">DroidGuard operation mode</string>
<string name="pref_droidguard_mode_embedded_title">Embedded</string>
<string name="pref_droidguard_mode_embedded_summary">Use local DroidGuard runtime</string>
<string name="pref_droidguard_mode_network_title">Remote</string>
<string name="pref_droidguard_mode_network_summary">Connect to DroidGuard runtime via network</string>
</resources>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory android:title="@string/prefcat_droidguard_mode">
<Preference
android:icon="@drawable/ic_radio_unchecked"
android:key="pref_droidguard_mode_embedded"
android:summary="@string/pref_droidguard_mode_embedded_summary"
android:title="@string/pref_droidguard_mode_embedded_title" />
<org.microg.gms.droidguard.core.ui.ContainedEditTextPreference
android:icon="@drawable/ic_radio_unchecked"
android:key="pref_droidguard_mode_network"
android:summary="@string/pref_droidguard_mode_network_summary"
android:title="@string/pref_droidguard_mode_network_title" />
</PreferenceCategory>
</PreferenceScreen>

View File

@ -10,6 +10,7 @@ include ':play-services-droidguard-api'
include ':play-services-iid-api'
include ':play-services-location-api'
include ':play-services-nearby-api'
include ':play-services-safetynet-api'
include ':play-services-tapandpay-api'
include ':play-services-vision-api'
include ':play-services-vision-common-api'
@ -38,6 +39,7 @@ include ':firebase-dynamic-links-api'
include ':play-services-core-proto'
include ':play-services-droidguard-core-proto'
include ':play-services-nearby-core-proto'
include ':play-services-safetynet-core-proto'
include ':play-services-wearable-proto'
include ':play-services-basement-ktx'
@ -53,10 +55,12 @@ include ':play-services-maps-core-mapbox'
include ':play-services-maps-core-vtm'
include ':play-services-maps-core-vtm:vtm-microg-theme'
include ':play-services-nearby-core'
include ':play-services-safetynet-core'
include ':play-services-tapandpay-core'
include ':play-services-vision-core'
include ':play-services-base-core-ui'
include ':play-services-droidguard-core-ui'
include ':play-services-nearby-core-ui'
include ':firebase-auth-core'