Loading play-services-base/core/src/main/kotlin/org/microg/gms/settings/SettingsContract.kt +4 −0 Original line number Diff line number Diff line Loading @@ -277,6 +277,8 @@ object SettingsContract { const val BILLING = "vending_billing" const val ASSET_DELIVERY = "vending_asset_delivery" const val ASSET_DEVICE_SYNC = "vending_device_sync" const val APPS_INSTALL = "vending_apps_install" const val APPS_INSTALLER_LIST = "vending_apps_installer_list" val PROJECTION = arrayOf( LICENSING, Loading @@ -285,6 +287,8 @@ object SettingsContract { BILLING, ASSET_DELIVERY, ASSET_DEVICE_SYNC, APPS_INSTALL, APPS_INSTALLER_LIST, ) } Loading play-services-base/core/src/main/kotlin/org/microg/gms/settings/SettingsProvider.kt +4 −1 Original line number Diff line number Diff line Loading @@ -10,7 +10,6 @@ import android.content.ContentValues import android.content.Context import android.content.Context.MODE_PRIVATE import android.content.SharedPreferences import android.content.pm.ApplicationInfo import android.database.Cursor import android.database.MatrixCursor import android.net.Uri Loading Loading @@ -368,6 +367,8 @@ class SettingsProvider : ContentProvider() { Vending.ASSET_DELIVERY -> getSettingsBoolean(key, false) Vending.ASSET_DEVICE_SYNC -> getSettingsBoolean(key, false) Vending.SPLIT_INSTALL -> getSettingsBoolean(key, false) Vending.APPS_INSTALL -> getSettingsBoolean(key, false) Vending.APPS_INSTALLER_LIST -> getSettingsString(key, "") else -> throw IllegalArgumentException("Unknown key: $key") } } Loading @@ -383,6 +384,8 @@ class SettingsProvider : ContentProvider() { Vending.SPLIT_INSTALL -> editor.putBoolean(key, value as Boolean) Vending.ASSET_DELIVERY -> editor.putBoolean(key, value as Boolean) Vending.ASSET_DEVICE_SYNC -> editor.putBoolean(key, value as Boolean) Vending.APPS_INSTALL -> editor.putBoolean(key, value as Boolean) Vending.APPS_INSTALLER_LIST -> editor.putString(key, value as String) else -> throw IllegalArgumentException("Unknown key: $key") } } Loading play-services-base/core/src/main/kotlin/org/microg/gms/vending/InstallerData.kt 0 → 100644 +61 −0 Original line number Diff line number Diff line /** * SPDX-FileCopyrightText: 2025 microG Project Team * SPDX-License-Identifier: Apache-2.0 */ package org.microg.gms.vending import org.json.JSONException import org.json.JSONObject enum class AllowType(val value: Int) { REJECT_ALWAYS(0), REJECT_ONCE(1), ALLOW_ONCE(2), ALLOW_ALWAYS(3), } data class InstallerData(val packageName: String, var allowType: Int, val pkgSignSha256: String) { override fun toString(): String { return JSONObject() .put(CHANNEL_PACKAGE_NAME, packageName) .put(CHANNEL_ALLOW_TYPE, allowType) .put(CHANNEL_SIGNATURE, pkgSignSha256) .toString() } companion object { private const val CHANNEL_PACKAGE_NAME = "packageName" private const val CHANNEL_ALLOW_TYPE = "allowType" private const val CHANNEL_SIGNATURE = "signature" private fun parse(jsonString: String): InstallerData? { try { val json = JSONObject(jsonString) return InstallerData( json.getString(CHANNEL_PACKAGE_NAME), json.getInt(CHANNEL_ALLOW_TYPE), json.getString(CHANNEL_SIGNATURE) ) } catch (e: JSONException) { return null } } fun loadDataSet(content: String): Set<InstallerData> { return content.split("|").mapNotNull { parse(it) }.toSet() } fun updateDataSetString(channelList: Set<InstallerData>, channel: InstallerData): String { val channelData = channelList.find { it.packageName == channel.packageName && it.pkgSignSha256 == channel.pkgSignSha256 } val newChannelList = if (channelData != null) { channelData.allowType = channel.allowType channelList } else { channelList + channel } return newChannelList.let { it -> it.joinToString(separator = "|") { it.toString() } } } } } No newline at end of file play-services-core/src/huawei/AndroidManifest.xml +3 −0 Original line number Diff line number Diff line Loading @@ -55,5 +55,8 @@ <meta-data android:name="org.microg.gms.settings.allow_upload_game_played" android:value="true" /> <meta-data android:name="org.microg.gms.settings.vending_apps_install" android:value="true" /> </application> </manifest> No newline at end of file play-services-core/src/main/kotlin/org/microg/gms/ui/VendingFragment.kt +24 −0 Original line number Diff line number Diff line Loading @@ -7,7 +7,11 @@ package org.microg.gms.ui import android.annotation.SuppressLint import android.os.Bundle import android.view.Menu import android.view.MenuInflater import android.view.MenuItem import androidx.lifecycle.lifecycleScope import androidx.navigation.fragment.findNavController import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat import androidx.preference.TwoStatePreference Loading Loading @@ -118,7 +122,27 @@ class VendingFragment : PreferenceFragmentCompat() { } } init { setHasOptionsMenu(true) } override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { menu.add(0, MENU_INSTALL_MANAGED, 0, R.string.pref_app_install_settings_title) super.onCreateOptionsMenu(menu, inflater) } override fun onOptionsItemSelected(item: MenuItem): Boolean { return when (item.itemId) { MENU_INSTALL_MANAGED -> { findNavController().navigate(requireContext(), R.id.openVendingInstallSettings) true } else -> super.onOptionsItemSelected(item) } } companion object { private const val MENU_INSTALL_MANAGED = Menu.FIRST const val PREF_LICENSING_ENABLED = "vending_licensing" const val PREF_LICENSING_PURCHASE_FREE_APPS_ENABLED = "vending_licensing_purchase_free_apps" const val PREF_SPLIT_INSTALL_ENABLED = "vending_split_install" Loading Loading
play-services-base/core/src/main/kotlin/org/microg/gms/settings/SettingsContract.kt +4 −0 Original line number Diff line number Diff line Loading @@ -277,6 +277,8 @@ object SettingsContract { const val BILLING = "vending_billing" const val ASSET_DELIVERY = "vending_asset_delivery" const val ASSET_DEVICE_SYNC = "vending_device_sync" const val APPS_INSTALL = "vending_apps_install" const val APPS_INSTALLER_LIST = "vending_apps_installer_list" val PROJECTION = arrayOf( LICENSING, Loading @@ -285,6 +287,8 @@ object SettingsContract { BILLING, ASSET_DELIVERY, ASSET_DEVICE_SYNC, APPS_INSTALL, APPS_INSTALLER_LIST, ) } Loading
play-services-base/core/src/main/kotlin/org/microg/gms/settings/SettingsProvider.kt +4 −1 Original line number Diff line number Diff line Loading @@ -10,7 +10,6 @@ import android.content.ContentValues import android.content.Context import android.content.Context.MODE_PRIVATE import android.content.SharedPreferences import android.content.pm.ApplicationInfo import android.database.Cursor import android.database.MatrixCursor import android.net.Uri Loading Loading @@ -368,6 +367,8 @@ class SettingsProvider : ContentProvider() { Vending.ASSET_DELIVERY -> getSettingsBoolean(key, false) Vending.ASSET_DEVICE_SYNC -> getSettingsBoolean(key, false) Vending.SPLIT_INSTALL -> getSettingsBoolean(key, false) Vending.APPS_INSTALL -> getSettingsBoolean(key, false) Vending.APPS_INSTALLER_LIST -> getSettingsString(key, "") else -> throw IllegalArgumentException("Unknown key: $key") } } Loading @@ -383,6 +384,8 @@ class SettingsProvider : ContentProvider() { Vending.SPLIT_INSTALL -> editor.putBoolean(key, value as Boolean) Vending.ASSET_DELIVERY -> editor.putBoolean(key, value as Boolean) Vending.ASSET_DEVICE_SYNC -> editor.putBoolean(key, value as Boolean) Vending.APPS_INSTALL -> editor.putBoolean(key, value as Boolean) Vending.APPS_INSTALLER_LIST -> editor.putString(key, value as String) else -> throw IllegalArgumentException("Unknown key: $key") } } Loading
play-services-base/core/src/main/kotlin/org/microg/gms/vending/InstallerData.kt 0 → 100644 +61 −0 Original line number Diff line number Diff line /** * SPDX-FileCopyrightText: 2025 microG Project Team * SPDX-License-Identifier: Apache-2.0 */ package org.microg.gms.vending import org.json.JSONException import org.json.JSONObject enum class AllowType(val value: Int) { REJECT_ALWAYS(0), REJECT_ONCE(1), ALLOW_ONCE(2), ALLOW_ALWAYS(3), } data class InstallerData(val packageName: String, var allowType: Int, val pkgSignSha256: String) { override fun toString(): String { return JSONObject() .put(CHANNEL_PACKAGE_NAME, packageName) .put(CHANNEL_ALLOW_TYPE, allowType) .put(CHANNEL_SIGNATURE, pkgSignSha256) .toString() } companion object { private const val CHANNEL_PACKAGE_NAME = "packageName" private const val CHANNEL_ALLOW_TYPE = "allowType" private const val CHANNEL_SIGNATURE = "signature" private fun parse(jsonString: String): InstallerData? { try { val json = JSONObject(jsonString) return InstallerData( json.getString(CHANNEL_PACKAGE_NAME), json.getInt(CHANNEL_ALLOW_TYPE), json.getString(CHANNEL_SIGNATURE) ) } catch (e: JSONException) { return null } } fun loadDataSet(content: String): Set<InstallerData> { return content.split("|").mapNotNull { parse(it) }.toSet() } fun updateDataSetString(channelList: Set<InstallerData>, channel: InstallerData): String { val channelData = channelList.find { it.packageName == channel.packageName && it.pkgSignSha256 == channel.pkgSignSha256 } val newChannelList = if (channelData != null) { channelData.allowType = channel.allowType channelList } else { channelList + channel } return newChannelList.let { it -> it.joinToString(separator = "|") { it.toString() } } } } } No newline at end of file
play-services-core/src/huawei/AndroidManifest.xml +3 −0 Original line number Diff line number Diff line Loading @@ -55,5 +55,8 @@ <meta-data android:name="org.microg.gms.settings.allow_upload_game_played" android:value="true" /> <meta-data android:name="org.microg.gms.settings.vending_apps_install" android:value="true" /> </application> </manifest> No newline at end of file
play-services-core/src/main/kotlin/org/microg/gms/ui/VendingFragment.kt +24 −0 Original line number Diff line number Diff line Loading @@ -7,7 +7,11 @@ package org.microg.gms.ui import android.annotation.SuppressLint import android.os.Bundle import android.view.Menu import android.view.MenuInflater import android.view.MenuItem import androidx.lifecycle.lifecycleScope import androidx.navigation.fragment.findNavController import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat import androidx.preference.TwoStatePreference Loading Loading @@ -118,7 +122,27 @@ class VendingFragment : PreferenceFragmentCompat() { } } init { setHasOptionsMenu(true) } override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { menu.add(0, MENU_INSTALL_MANAGED, 0, R.string.pref_app_install_settings_title) super.onCreateOptionsMenu(menu, inflater) } override fun onOptionsItemSelected(item: MenuItem): Boolean { return when (item.itemId) { MENU_INSTALL_MANAGED -> { findNavController().navigate(requireContext(), R.id.openVendingInstallSettings) true } else -> super.onOptionsItemSelected(item) } } companion object { private const val MENU_INSTALL_MANAGED = Menu.FIRST const val PREF_LICENSING_ENABLED = "vending_licensing" const val PREF_LICENSING_PURCHASE_FREE_APPS_ENABLED = "vending_licensing_purchase_free_apps" const val PREF_SPLIT_INSTALL_ENABLED = "vending_split_install" Loading