mirror of
https://github.com/microg/android_packages_apps_GmsCore
synced 2026-08-06 14:26:05 -04:00
Add phone number verification settings and usage record
This commit is contained in:
parent
4510ced43d
commit
395864f0bf
14 changed files with 391 additions and 0 deletions
|
|
@ -220,6 +220,24 @@ object SettingsContract {
|
|||
)
|
||||
}
|
||||
|
||||
object Constellation {
|
||||
const val ID = "constellation"
|
||||
fun getContentUri(context: Context) = Uri.withAppendedPath(getAuthorityUri(context), ID)
|
||||
fun getContentType(context: Context) = "vnd.android.cursor.item/vnd.${getAuthority(context)}.$ID"
|
||||
|
||||
const val PHONE_NUMBER_VERIFICATION_ENABLED = "phone_number_verification_enabled"
|
||||
const val PHONE_NUMBER_VERIFICATION_LAST_PACKAGE = "phone_number_verification_last_package"
|
||||
const val PHONE_NUMBER_VERIFICATION_LAST_USED_AT_MS = "phone_number_verification_last_used_at_ms"
|
||||
const val PHONE_NUMBER_VERIFICATION_LAST_SUCCESSFUL = "phone_number_verification_last_successful"
|
||||
|
||||
val PROJECTION = arrayOf(
|
||||
PHONE_NUMBER_VERIFICATION_ENABLED,
|
||||
PHONE_NUMBER_VERIFICATION_LAST_PACKAGE,
|
||||
PHONE_NUMBER_VERIFICATION_LAST_USED_AT_MS,
|
||||
PHONE_NUMBER_VERIFICATION_LAST_SUCCESSFUL,
|
||||
)
|
||||
}
|
||||
|
||||
object Profile {
|
||||
const val ID = "profile"
|
||||
fun getContentUri(context: Context) = Uri.withAppendedPath(getAuthorityUri(context), ID)
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import android.preference.PreferenceManager
|
|||
import org.microg.gms.common.PackageUtils.warnIfNotMainProcess
|
||||
import org.microg.gms.settings.SettingsContract.Auth
|
||||
import org.microg.gms.settings.SettingsContract.CheckIn
|
||||
import org.microg.gms.settings.SettingsContract.Constellation
|
||||
import org.microg.gms.settings.SettingsContract.DroidGuard
|
||||
import org.microg.gms.settings.SettingsContract.Exposure
|
||||
import org.microg.gms.settings.SettingsContract.GameProfile
|
||||
|
|
@ -80,6 +81,7 @@ class SettingsProvider : ContentProvider() {
|
|||
Exposure.ID -> queryExposure(projection ?: Exposure.PROJECTION)
|
||||
SafetyNet.ID -> querySafetyNet(projection ?: SafetyNet.PROJECTION)
|
||||
DroidGuard.ID -> queryDroidGuard(projection ?: DroidGuard.PROJECTION)
|
||||
Constellation.ID -> queryConstellation(projection ?: Constellation.PROJECTION)
|
||||
Profile.ID -> queryProfile(projection ?: Profile.PROJECTION)
|
||||
Location.ID -> queryLocation(projection ?: Location.PROJECTION)
|
||||
Vending.ID -> queryVending(projection ?: Vending.PROJECTION)
|
||||
|
|
@ -103,6 +105,7 @@ class SettingsProvider : ContentProvider() {
|
|||
Exposure.ID -> updateExposure(values)
|
||||
SafetyNet.ID -> updateSafetyNet(values)
|
||||
DroidGuard.ID -> updateDroidGuard(values)
|
||||
Constellation.ID -> updateConstellation(values)
|
||||
Profile.ID -> updateProfile(values)
|
||||
Location.ID -> updateLocation(values)
|
||||
Vending.ID -> updateVending(values)
|
||||
|
|
@ -298,6 +301,31 @@ class SettingsProvider : ContentProvider() {
|
|||
editor.apply()
|
||||
}
|
||||
|
||||
private fun queryConstellation(p: Array<out String>): Cursor = MatrixCursor(p).addRow(p) { key ->
|
||||
when (key) {
|
||||
Constellation.PHONE_NUMBER_VERIFICATION_ENABLED -> getSettingsBoolean(key, false)
|
||||
Constellation.PHONE_NUMBER_VERIFICATION_LAST_PACKAGE -> getSettingsString(key)
|
||||
Constellation.PHONE_NUMBER_VERIFICATION_LAST_USED_AT_MS -> getSettingsLong(key, 0L)
|
||||
Constellation.PHONE_NUMBER_VERIFICATION_LAST_SUCCESSFUL -> getSettingsBoolean(key, false)
|
||||
else -> throw IllegalArgumentException("Unknown key: $key")
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateConstellation(values: ContentValues) {
|
||||
if (values.size() == 0) return
|
||||
val editor = preferences.edit()
|
||||
values.valueSet().forEach { (key, value) ->
|
||||
when (key) {
|
||||
Constellation.PHONE_NUMBER_VERIFICATION_ENABLED -> editor.putBoolean(key, value as Boolean)
|
||||
Constellation.PHONE_NUMBER_VERIFICATION_LAST_PACKAGE -> editor.putString(key, value as String?)
|
||||
Constellation.PHONE_NUMBER_VERIFICATION_LAST_USED_AT_MS -> editor.putLong(key, value as Long)
|
||||
Constellation.PHONE_NUMBER_VERIFICATION_LAST_SUCCESSFUL -> editor.putBoolean(key, value as Boolean)
|
||||
else -> throw IllegalArgumentException("Unknown key: $key")
|
||||
}
|
||||
}
|
||||
editor.apply()
|
||||
}
|
||||
|
||||
private fun queryProfile(p: Array<out String>): Cursor = MatrixCursor(p).addRow(p) { key ->
|
||||
when (key) {
|
||||
Profile.PROFILE -> getSettingsString(key, "auto")
|
||||
|
|
|
|||
|
|
@ -59,4 +59,6 @@ dependencies {
|
|||
implementation "com.squareup.okhttp3:okhttp:$okHttpVersion"
|
||||
api "com.squareup.wire:wire-runtime:$wireVersion"
|
||||
api "com.squareup.wire:wire-grpc-client:$wireVersion"
|
||||
|
||||
implementation "androidx.preference:preference-ktx:$preferenceVersion"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ import org.microg.gms.constellation.core.proto.ProceedResponse
|
|||
import org.microg.gms.constellation.core.proto.ServerTimestamp
|
||||
import org.microg.gms.constellation.core.proto.SyncResponse
|
||||
import org.microg.gms.constellation.core.proto.VerificationToken
|
||||
import org.microg.gms.settings.SettingsContract
|
||||
import org.microg.gms.settings.SettingsContract.Constellation
|
||||
|
||||
private const val STATE_PREFS_NAME = "constellation_prefs"
|
||||
private const val TOKEN_PREFS_NAME = "com.google.android.gms.constellation"
|
||||
|
|
@ -30,6 +32,11 @@ private const val KEY_PNVR_NOTICE_CONSENT = "pnvr_notice_consent"
|
|||
private const val KEY_PNVR_NOTICE_SOURCE = "pnvr_notice_source"
|
||||
private const val KEY_PNVR_NOTICE_VERSION = "pnvr_notice_version"
|
||||
private const val KEY_PNVR_NOTICE_UPDATED_AT_MS = "pnvr_notice_updated_at_ms"
|
||||
data class PhoneNumberVerificationRecord(
|
||||
val packageName: String,
|
||||
val usedAtMillis: Long,
|
||||
val successful: Boolean
|
||||
)
|
||||
|
||||
object ConstellationStateStore {
|
||||
fun loadVerificationTokens(context: Context): List<VerificationToken> {
|
||||
|
|
@ -130,6 +137,43 @@ object ConstellationStateStore {
|
|||
}
|
||||
}
|
||||
|
||||
fun isPhoneNumberVerificationEnabled(context: Context): Boolean =
|
||||
SettingsContract.getSettings(
|
||||
context,
|
||||
Constellation.getContentUri(context),
|
||||
arrayOf(Constellation.PHONE_NUMBER_VERIFICATION_ENABLED)
|
||||
) { it.getInt(0) != 0 }
|
||||
|
||||
fun setPhoneNumberVerificationEnabled(context: Context, enabled: Boolean) {
|
||||
SettingsContract.setSettings(context, Constellation.getContentUri(context)) {
|
||||
put(Constellation.PHONE_NUMBER_VERIFICATION_ENABLED, enabled)
|
||||
}
|
||||
}
|
||||
|
||||
fun recordPhoneNumberVerification(context: Context, packageName: String, successful: Boolean) {
|
||||
SettingsContract.setSettings(context, Constellation.getContentUri(context)) {
|
||||
put(Constellation.PHONE_NUMBER_VERIFICATION_LAST_PACKAGE, packageName)
|
||||
put(Constellation.PHONE_NUMBER_VERIFICATION_LAST_USED_AT_MS, System.currentTimeMillis())
|
||||
put(Constellation.PHONE_NUMBER_VERIFICATION_LAST_SUCCESSFUL, successful)
|
||||
}
|
||||
}
|
||||
|
||||
fun loadLastPhoneNumberVerification(context: Context): PhoneNumberVerificationRecord? {
|
||||
return SettingsContract.getSettings(
|
||||
context,
|
||||
Constellation.getContentUri(context),
|
||||
Constellation.PROJECTION
|
||||
) { cursor ->
|
||||
cursor.getString(1)?.let { packageName ->
|
||||
PhoneNumberVerificationRecord(
|
||||
packageName,
|
||||
cursor.getLong(2),
|
||||
cursor.getInt(3) != 0
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun storeVerificationTokens(context: Context, tokens: List<VerificationToken>) {
|
||||
if (tokens.isEmpty()) return
|
||||
val filtered = tokens.filter {
|
||||
|
|
|
|||
|
|
@ -176,6 +176,10 @@ private suspend fun handleVerifyPhoneNumberRequest(
|
|||
var phoneNumbers = emptyList<PhoneNumberInfo>()
|
||||
var verifications = emptyArray<PhoneNumberVerification>()
|
||||
val status = try {
|
||||
if (!ConstellationStateStore.isPhoneNumberVerificationEnabled(context)) {
|
||||
throw PhoneNumberVerificationDisabledException()
|
||||
}
|
||||
|
||||
when (readCallbackMode) {
|
||||
ReadCallbackMode.LEGACY -> {
|
||||
Log.d(TAG, "Using read-only mode")
|
||||
|
|
@ -205,6 +209,7 @@ private suspend fun handleVerifyPhoneNumberRequest(
|
|||
} catch (e: Exception) {
|
||||
Log.e(TAG, "verifyPhoneNumber failed", e)
|
||||
when {
|
||||
e is PhoneNumberVerificationDisabledException -> Status(5000)
|
||||
readCallbackMode != ReadCallbackMode.NONE -> Status.INTERNAL_ERROR
|
||||
e is GrpcException -> handleRpcError(e)
|
||||
e is NoConsentException -> Status(5001)
|
||||
|
|
@ -212,6 +217,18 @@ private suspend fun handleVerifyPhoneNumberRequest(
|
|||
}
|
||||
}
|
||||
|
||||
val successful = status.isSuccess && when (readCallbackMode) {
|
||||
ReadCallbackMode.NONE -> verifications.isNotEmpty() &&
|
||||
(request.targetedSims.isEmpty() ||
|
||||
verifications.size == request.targetedSims.size) &&
|
||||
verifications.all {
|
||||
it.verificationStatus == Verification.Status.STATUS_VERIFIED.toClientStatus()
|
||||
}
|
||||
|
||||
else -> true
|
||||
}
|
||||
ConstellationStateStore.recordPhoneNumberVerification(context, callingPackage, successful)
|
||||
|
||||
if (readCallbackMode == ReadCallbackMode.LEGACY ||
|
||||
readCallbackMode == ReadCallbackMode.NONE && legacyCallbackOnFullFlow
|
||||
) {
|
||||
|
|
@ -232,6 +249,8 @@ private suspend fun handleVerifyPhoneNumberRequest(
|
|||
)
|
||||
}
|
||||
|
||||
private class PhoneNumberVerificationDisabledException : Exception("Phone number verification is disabled")
|
||||
|
||||
private fun handleRpcError(error: GrpcException): Status {
|
||||
val statusCode = when (error.grpcStatus) {
|
||||
GrpcStatus.RESOURCE_EXHAUSTED -> 5008
|
||||
|
|
|
|||
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026, microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package org.microg.gms.constellation.core.ui
|
||||
|
||||
import android.content.Context
|
||||
import android.text.format.DateUtils
|
||||
import android.util.AttributeSet
|
||||
import android.util.DisplayMetrics
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.content.res.AppCompatResources
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceViewHolder
|
||||
import org.microg.gms.constellation.core.R
|
||||
import org.microg.gms.ui.getApplicationInfoIfExists
|
||||
|
||||
class PhoneNumberVerificationAppPreference : 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)
|
||||
|
||||
var packageName: String? = null
|
||||
set(value) {
|
||||
field = value
|
||||
val packageManager = context.packageManager
|
||||
val applicationInfo = packageManager.getApplicationInfoIfExists(value)
|
||||
title = applicationInfo?.loadLabel(packageManager)?.toString() ?: value
|
||||
icon = applicationInfo?.loadIcon(packageManager)
|
||||
?: AppCompatResources.getDrawable(context, android.R.mipmap.sym_def_app_icon)
|
||||
notifyChanged()
|
||||
}
|
||||
|
||||
var usedAtMillis: Long = 0L
|
||||
set(value) {
|
||||
field = value
|
||||
notifyChanged()
|
||||
}
|
||||
|
||||
init {
|
||||
isPersistent = false
|
||||
layoutResource = R.layout.preference_phone_number_verification_last_use
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
holder.findViewById(R.id.phone_number_verification_last_use_time)?.let {
|
||||
(it as TextView).text = if (usedAtMillis > 0L) {
|
||||
DateUtils.getRelativeTimeSpanString(usedAtMillis)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2026, microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package org.microg.gms.constellation.core.ui
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.preference.PreferenceCategory
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import org.microg.gms.constellation.core.ConstellationStateStore
|
||||
import org.microg.gms.constellation.core.R
|
||||
import org.microg.gms.ui.SwitchBarPreference
|
||||
|
||||
class PhoneNumberVerificationPreferencesFragment : PreferenceFragmentCompat() {
|
||||
private lateinit var enabled: SwitchBarPreference
|
||||
private lateinit var lastUseCategory: PreferenceCategory
|
||||
private lateinit var app: PhoneNumberVerificationAppPreference
|
||||
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
addPreferencesFromResource(R.xml.preferences_phone_number_verification)
|
||||
}
|
||||
|
||||
override fun onBindPreferences() {
|
||||
enabled = preferenceScreen.findPreference(PREF_ENABLED) ?: enabled
|
||||
lastUseCategory = preferenceScreen.findPreference(PREF_LAST_USE_CATEGORY) ?: lastUseCategory
|
||||
app = preferenceScreen.findPreference(PREF_LAST_USE) ?: app
|
||||
enabled.setOnPreferenceChangeListener { _, newValue ->
|
||||
ConstellationStateStore.setPhoneNumberVerificationEnabled(
|
||||
requireContext(),
|
||||
newValue as Boolean
|
||||
)
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
enabled.isChecked =
|
||||
ConstellationStateStore.isPhoneNumberVerificationEnabled(requireContext())
|
||||
val record = ConstellationStateStore.loadLastPhoneNumberVerification(requireContext())
|
||||
lastUseCategory.isVisible = record != null
|
||||
if (record != null) {
|
||||
app.packageName = record.packageName
|
||||
app.summary = getString(
|
||||
if (record.successful) {
|
||||
R.string.phone_number_verification_result_success
|
||||
} else {
|
||||
R.string.phone_number_verification_result_failure
|
||||
}
|
||||
)
|
||||
app.usedAtMillis = record.usedAtMillis
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val PREF_ENABLED = "pref_phone_number_verification_enabled"
|
||||
private const val PREF_LAST_USE_CATEGORY = "prefcat_phone_number_verification_last_use"
|
||||
private const val PREF_LAST_USE = "pref_phone_number_verification_last_use"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ SPDX-FileCopyrightText: 2026, 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="#000"
|
||||
android:pathData="M6.62,10.79c1.44,2.83 3.76,5.14 6.59,6.59l2.2,-2.2c0.27,-0.27 0.67,-0.36 1.02,-0.24 1.12,0.37 2.33,0.57 3.57,0.57 0.55,0 1,0.45 1,1V20c0,0.55 -0.45,1 -1,1C10.61,21 3,13.39 3,4c0,-0.55 0.45,-1 1,-1h3.5c0.55,0 1,0.45 1,1 0,1.25 0.2,2.45 0.57,3.57 0.11,0.35 0.03,0.74 -0.25,1.02l-2.2,2.2z" />
|
||||
</vector>
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ SPDX-FileCopyrightText: 2026, 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="wrap_content"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:baselineAligned="false"
|
||||
android:clipToPadding="false"
|
||||
android:gravity="center_vertical"
|
||||
android:minHeight="?android:attr/listPreferredItemHeightSmall"
|
||||
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
|
||||
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/icon_frame"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="start|center_vertical"
|
||||
android:minWidth="56dp"
|
||||
android:orientation="horizontal"
|
||||
android:paddingTop="4dp"
|
||||
android:paddingEnd="12dp"
|
||||
android:paddingBottom="4dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@android:id/icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:maxWidth="48dp"
|
||||
android:maxHeight="48dp" />
|
||||
</LinearLayout>
|
||||
|
||||
<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:ellipsize="marquee"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?android:attr/textAppearanceListItem" />
|
||||
|
||||
<TextView
|
||||
android:id="@android:id/summary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@android:id/title"
|
||||
android:layout_alignStart="@android:id/title"
|
||||
android:maxLines="2"
|
||||
android:textAppearance="?android:attr/textAppearanceListItemSecondary"
|
||||
android:textColor="?android:attr/textColorSecondary" />
|
||||
</RelativeLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/phone_number_verification_last_use_time"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:gravity="end|center_vertical"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="?android:attr/textAppearanceListItemSecondary"
|
||||
android:textColor="?android:attr/textColorSecondary" />
|
||||
</LinearLayout>
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ SPDX-FileCopyrightText: 2026, microG Project Team
|
||||
~ SPDX-License-Identifier: Apache-2.0
|
||||
-->
|
||||
<resources>
|
||||
<string name="phone_number_verification_title">Phone Number Verification</string>
|
||||
<string name="phone_number_verification_enable">Enable phone number verification</string>
|
||||
<string name="phone_number_verification_last_use_title">Last use</string>
|
||||
<string name="phone_number_verification_result_success">Successful</string>
|
||||
<string name="phone_number_verification_result_failure">Failed</string>
|
||||
<string name="phone_number_verification_carrier_notice">Your carrier may charge you for texts and calls used for verification.</string>
|
||||
</resources>
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ SPDX-FileCopyrightText: 2026, microG Project Team
|
||||
~ SPDX-License-Identifier: Apache-2.0
|
||||
-->
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<org.microg.gms.ui.SwitchBarPreference
|
||||
android:key="pref_phone_number_verification_enabled"
|
||||
android:persistent="false"
|
||||
android:title="@string/phone_number_verification_enable" />
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="prefcat_phone_number_verification_last_use"
|
||||
android:title="@string/phone_number_verification_last_use_title"
|
||||
app:isPreferenceVisible="false">
|
||||
|
||||
<org.microg.gms.constellation.core.ui.PhoneNumberVerificationAppPreference
|
||||
android:key="pref_phone_number_verification_last_use"
|
||||
android:selectable="false"
|
||||
app:iconSpaceReserved="false" />
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory android:layout="@layout/preference_category_no_label">
|
||||
<org.microg.gms.ui.FooterPreference
|
||||
android:selectable="false"
|
||||
android:title="@string/phone_number_verification_carrier_notice" />
|
||||
</PreferenceCategory>
|
||||
</PreferenceScreen>
|
||||
|
|
@ -13,6 +13,7 @@ import androidx.preference.Preference
|
|||
import androidx.preference.PreferenceCategory
|
||||
import com.google.android.gms.R
|
||||
import org.microg.gms.checkin.CheckinPreferences
|
||||
import org.microg.gms.constellation.core.ConstellationStateStore
|
||||
import org.microg.gms.gcm.GcmDatabase
|
||||
import org.microg.gms.gcm.GcmPrefs
|
||||
import org.microg.gms.safetynet.SafetyNetPreferences
|
||||
|
|
@ -42,6 +43,10 @@ class SettingsFragment : ResourceSettingsFragment() {
|
|||
findNavController().navigate(requireContext(), R.id.openSafetyNetSettings)
|
||||
true
|
||||
}
|
||||
findPreference<Preference>(PREF_PHONE_NUMBER_VERIFICATION)!!.onPreferenceClickListener = Preference.OnPreferenceClickListener {
|
||||
findNavController().navigate(requireContext(), R.id.openPhoneNumberVerificationSettings)
|
||||
true
|
||||
}
|
||||
findPreference<Preference>(PREF_LOCATION)!!.onPreferenceClickListener = Preference.OnPreferenceClickListener {
|
||||
findNavController().navigate(requireContext(), R.id.openLocationSettings)
|
||||
true
|
||||
|
|
@ -116,6 +121,13 @@ class SettingsFragment : ResourceSettingsFragment() {
|
|||
|
||||
findPreference<Preference>(PREF_CHECKIN)!!.setSummary(if (CheckinPreferences.isEnabled(requireContext())) org.microg.gms.base.core.R.string.service_status_enabled_short else org.microg.gms.base.core.R.string.service_status_disabled_short)
|
||||
findPreference<Preference>(PREF_SNET)!!.setSummary(if (SafetyNetPreferences.isEnabled(requireContext())) org.microg.gms.base.core.R.string.service_status_enabled_short else org.microg.gms.base.core.R.string.service_status_disabled_short)
|
||||
findPreference<Preference>(PREF_PHONE_NUMBER_VERIFICATION)!!.setSummary(
|
||||
if (ConstellationStateStore.isPhoneNumberVerificationEnabled(requireContext())) {
|
||||
org.microg.gms.base.core.R.string.service_status_enabled_short
|
||||
} else {
|
||||
org.microg.gms.base.core.R.string.service_status_disabled_short
|
||||
}
|
||||
)
|
||||
|
||||
lifecycleScope.launchWhenResumed {
|
||||
val entries = getAllSettingsProviders(requireContext()).flatMap { it.getEntriesDynamic(requireContext()) }
|
||||
|
|
@ -134,6 +146,7 @@ class SettingsFragment : ResourceSettingsFragment() {
|
|||
const val PREF_ABOUT = "pref_about"
|
||||
const val PREF_GCM = "pref_gcm"
|
||||
const val PREF_SNET = "pref_snet"
|
||||
const val PREF_PHONE_NUMBER_VERIFICATION = "pref_phone_number_verification"
|
||||
const val PREF_LOCATION = "pref_location"
|
||||
const val PREF_CHECKIN = "pref_checkin"
|
||||
const val PREF_VENDING = "pref_vending"
|
||||
|
|
|
|||
|
|
@ -23,6 +23,9 @@
|
|||
<action
|
||||
android:id="@+id/openSafetyNetSettings"
|
||||
app:destination="@id/safetyNetFragment" />
|
||||
<action
|
||||
android:id="@+id/openPhoneNumberVerificationSettings"
|
||||
app:destination="@id/phoneNumberVerificationFragment" />
|
||||
<action
|
||||
android:id="@+id/openVendingSettings"
|
||||
app:destination="@id/vendingFragment" />
|
||||
|
|
@ -163,6 +166,11 @@
|
|||
app:argType="string" />
|
||||
</fragment>
|
||||
|
||||
<fragment
|
||||
android:id="@+id/phoneNumberVerificationFragment"
|
||||
android:name="org.microg.gms.constellation.core.ui.PhoneNumberVerificationPreferencesFragment"
|
||||
android:label="@string/phone_number_verification_title" />
|
||||
|
||||
<!-- Play Store services -->
|
||||
|
||||
<fragment
|
||||
|
|
|
|||
|
|
@ -44,6 +44,10 @@
|
|||
android:icon="@drawable/ic_certificate"
|
||||
android:key="pref_snet"
|
||||
android:title="@string/service_name_device_attestation" />
|
||||
<Preference
|
||||
android:icon="@drawable/ic_phone"
|
||||
android:key="pref_phone_number_verification"
|
||||
android:title="@string/phone_number_verification_title" />
|
||||
<Preference
|
||||
android:icon="@drawable/ic_shop"
|
||||
android:key="pref_vending"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue