From 47c7b42124152af6482165992c71d056fee76eb7 Mon Sep 17 00:00:00 2001 From: Opstic <46141527+opstic@users.noreply.github.com> Date: Sun, 17 May 2026 03:40:23 +0800 Subject: [PATCH] Provide Phenotype flags from `ContentProvider` --- .../gms/phenotype/ConfigurationProvider.java | 14 +++++++++++++- .../microg/gms/phenotype/PhenotypeService.kt | 2 +- .../google/android/gms/phenotype/Flag.java | 19 +++++++++++++++++++ 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/play-services-core/src/main/java/org/microg/gms/phenotype/ConfigurationProvider.java b/play-services-core/src/main/java/org/microg/gms/phenotype/ConfigurationProvider.java index 19ab1207d0..965065e2e0 100644 --- a/play-services-core/src/main/java/org/microg/gms/phenotype/ConfigurationProvider.java +++ b/play-services-core/src/main/java/org/microg/gms/phenotype/ConfigurationProvider.java @@ -16,6 +16,8 @@ package org.microg.gms.phenotype; +import static org.microg.gms.phenotype.PhenotypeServiceKt.getCONFIGURATION_OPTIONS; + import android.content.ContentProvider; import android.content.ContentValues; import android.database.Cursor; @@ -26,8 +28,11 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import com.google.android.gms.phenotype.Flag; + public class ConfigurationProvider extends ContentProvider { private static final String TAG = "GmsPhenotypeCfgProvider"; + @Override public boolean onCreate() { Log.d(TAG, "unimplemented Method: onCreate"); @@ -39,7 +44,14 @@ public boolean onCreate() { public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) { selection = Uri.decode(uri.getLastPathSegment()); if (selection == null) return null; - return new MatrixCursor(new String[]{"key", "value"}); + MatrixCursor cursor = new MatrixCursor(new String[]{"key", "value"}); + + Flag[] flags = getCONFIGURATION_OPTIONS().get(selection); + if (flags == null) return cursor; + for (Flag flag : flags) { + cursor.addRow(new Object[]{flag.name, flag.getValueString()}); + } + return cursor; } @Nullable diff --git a/play-services-core/src/main/kotlin/org/microg/gms/phenotype/PhenotypeService.kt b/play-services-core/src/main/kotlin/org/microg/gms/phenotype/PhenotypeService.kt index c925faf26f..595fae1041 100644 --- a/play-services-core/src/main/kotlin/org/microg/gms/phenotype/PhenotypeService.kt +++ b/play-services-core/src/main/kotlin/org/microg/gms/phenotype/PhenotypeService.kt @@ -28,7 +28,7 @@ class PhenotypeService : BaseService(TAG, GmsService.PHENOTYPE) { } } -private val CONFIGURATION_OPTIONS = mapOf( +val CONFIGURATION_OPTIONS = mapOf( "com.google.android.apps.search.assistant.mobile.user#com.google.android.googlequicksearchbox" to arrayOf( // Enable Gemini voice input for all devices Flag("45477527", true, 0), diff --git a/play-services-phenotype/src/main/java/com/google/android/gms/phenotype/Flag.java b/play-services-phenotype/src/main/java/com/google/android/gms/phenotype/Flag.java index 12aa845758..c27e4aa2c0 100644 --- a/play-services-phenotype/src/main/java/com/google/android/gms/phenotype/Flag.java +++ b/play-services-phenotype/src/main/java/com/google/android/gms/phenotype/Flag.java @@ -5,6 +5,8 @@ package com.google.android.gms.phenotype; +import android.util.Base64; + import org.microg.gms.common.Hide; import org.microg.safeparcel.AutoSafeParcelable; @@ -95,6 +97,23 @@ public byte[] getBytes() { throw new IllegalArgumentException("Not a bytes type"); } + public String getValueString() { + switch (dataType) { + case DATA_TYPE_LONG: + return Long.toString(longValue); + case DATA_TYPE_BOOL: + return boolValue ? "true" : "false"; + case DATA_TYPE_DOUBLE: + return Double.toString(doubleValue); + case DATA_TYPE_STRING: + return stringValue; + case DATA_TYPE_BYTES: + return Base64.encodeToString(bytesValue, Base64.NO_WRAP | Base64.URL_SAFE); + default: + return null; + } + } + public static final int DATA_TYPE_LONG = 1; public static final int DATA_TYPE_BOOL = 2; public static final int DATA_TYPE_DOUBLE = 3;