Skip to content

Commit

Permalink
Organize vending protobuf files
Browse files Browse the repository at this point in the history
  • Loading branch information
fynngodau committed Sep 25, 2024
1 parent 85bd1c9 commit 2e1dfec
Show file tree
Hide file tree
Showing 21 changed files with 193 additions and 197 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ import android.content.pm.PackageInfo
import android.os.RemoteException
import android.util.Log
import com.android.vending.AUTH_TOKEN_SCOPE
import com.android.vending.LicenseResult
import com.android.vending.buildRequestHeaders
import com.android.vending.getAuthToken
import com.android.volley.VolleyError
import org.microg.vending.billing.core.HttpClient
import org.microg.vending.billing.proto.GoogleApiResponse
import java.io.IOException

private const val TAG = "FakeLicenseChecker"
Expand Down Expand Up @@ -142,8 +142,8 @@ suspend fun HttpClient.makeLicenseV1Request(
): V1Response? = get(
url = "https://play-fe.googleapis.com/fdfe/apps/checkLicense?pkgn=$packageName&vc=$versionCode&nnc=$nonce",
headers = buildRequestHeaders(auth, androidId),
adapter = LicenseResult.ADAPTER
).information?.v1?.let {
adapter = GoogleApiResponse.ADAPTER
).payload?.licenseV1Response?.let {
if (it.result != null && it.signedData != null && it.signature != null) {
V1Response(it.result, it.signedData, it.signature)
} else null
Expand All @@ -157,8 +157,8 @@ suspend fun HttpClient.makeLicenseV2Request(
): V2Response? = get(
url = "https://play-fe.googleapis.com/fdfe/apps/checkLicenseServerFallback?pkgn=$packageName&vc=$versionCode",
headers = buildRequestHeaders(auth, androidId),
adapter = LicenseResult.ADAPTER
).information?.v2?.license?.jwt?.let {
adapter = GoogleApiResponse.ADAPTER
).payload?.licenseV2Response?.license?.jwt?.let {
// Field present ←→ user has license
V2Response(LICENSED, it)
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import org.microg.vending.billing.core.GooglePlayApi.Companion.URL_DETAILS
import org.microg.vending.billing.core.GooglePlayApi.Companion.URL_PURCHASE
import org.microg.vending.billing.core.HeaderProvider
import org.microg.vending.billing.core.HttpClient
import org.microg.vending.billing.proto.ResponseWrapper
import org.microg.vending.billing.proto.GoogleApiResponse

suspend fun HttpClient.acquireFreeAppLicense(context: Context, account: Account, packageName: String): Boolean {
val authData = AuthManager.getAuthData(context, account)
Expand All @@ -27,7 +27,7 @@ suspend fun HttpClient.acquireFreeAppLicense(context: Context, account: Account,
url = URL_DETAILS,
headers = headers,
params = mapOf("doc" to packageName),
adapter = ResponseWrapper.ADAPTER
adapter = GoogleApiResponse.ADAPTER
).payload?.detailsResponse
} catch (e: VolleyError) {
Log.e(TAG, "Unable to auto-purchase $packageName because of a network error or unexpected response when gathering app data")
Expand Down Expand Up @@ -65,14 +65,14 @@ suspend fun HttpClient.acquireFreeAppLicense(context: Context, account: Account,
url = URL_PURCHASE,
headers = headers,
params = parameters,
adapter = ResponseWrapper.ADAPTER
adapter = GoogleApiResponse.ADAPTER
).payload?.buyResponse
} catch (e: VolleyError) {
Log.e(TAG, "Unable to auto-purchase $packageName because of a network error or unexpected response during purchase")
return false
}

if (buyResult?.encodedDeliveryToken.isNullOrBlank()) {
if (buyResult?.deliveryToken.isNullOrBlank()) {
Log.e(TAG, "Auto-purchasing $packageName failed. Was the purchase rejected by the server?")
return false
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ package org.microg.vending.billing.core
import android.content.Context
import android.util.Base64
import android.util.Log
import com.android.vending.Timestamp
import org.json.JSONObject
import org.microg.gms.utils.toBase64
import org.microg.vending.billing.proto.*
import org.microg.vending.proto.Timestamp
import java.io.IOException
import java.util.concurrent.TimeUnit

Expand Down Expand Up @@ -93,7 +93,7 @@ class IAPCore(
val requestBody = skuDetailsRequest.encode()
val cacheEntry = skuDetailsCache.get(requestBody)
if (cacheEntry != null) {
val getSkuDetailsResult = GetSkuDetailsResult.parseFrom(ResponseWrapper.ADAPTER.decode(cacheEntry).payload?.skuDetailsResponse)
val getSkuDetailsResult = GetSkuDetailsResult.parseFrom(GoogleApiResponse.ADAPTER.decode(cacheEntry).payload?.skuDetailsResponse)
if (getSkuDetailsResult.skuDetailsList != null && getSkuDetailsResult.skuDetailsList.isNotEmpty()) {
Log.d("IAPCore", "getSkuDetails from cache ")
return getSkuDetailsResult
Expand All @@ -104,7 +104,7 @@ class IAPCore(
GooglePlayApi.URL_SKU_DETAILS,
headers = HeaderProvider.getDefaultHeaders(authData, deviceInfo),
payload = skuDetailsRequest,
adapter = ResponseWrapper.ADAPTER
adapter = GoogleApiResponse.ADAPTER
)
skuDetailsCache.put(requestBody, response.encode())
GetSkuDetailsResult.parseFrom(response.payload?.skuDetailsResponse)
Expand Down Expand Up @@ -245,7 +245,7 @@ class IAPCore(
headers = HeaderProvider.getDefaultHeaders(authData, deviceInfo),
params = mapOf("theme" to acquireRequest.theme.toString()),
payload = acquireRequest,
ResponseWrapper.ADAPTER
GoogleApiResponse.ADAPTER
)
AcquireResult.parseFrom(params, acquireRequest, response.payload?.acquireResponse)
} catch (e: Exception) {
Expand All @@ -269,7 +269,7 @@ class IAPCore(
GooglePlayApi.URL_CONSUME_PURCHASE,
headers = HeaderProvider.getDefaultHeaders(authData, deviceInfo),
form = request,
adapter = ResponseWrapper.ADAPTER
adapter = GoogleApiResponse.ADAPTER
)
ConsumePurchaseResult.parseFrom(response.payload?.consumePurchaseResponse)
} catch (e: Exception) {
Expand All @@ -290,7 +290,7 @@ class IAPCore(
GooglePlayApi.URL_ACKNOWLEDGE_PURCHASE,
headers = HeaderProvider.getDefaultHeaders(authData, deviceInfo),
payload = acknowledgePurchaseRequest,
adapter = ResponseWrapper.ADAPTER
adapter = GoogleApiResponse.ADAPTER
)
AcknowledgePurchaseResult.parseFrom(response.payload?.acknowledgePurchaseResponse)
} catch (e: Exception) {
Expand Down Expand Up @@ -318,7 +318,7 @@ class IAPCore(
GooglePlayApi.URL_GET_PURCHASE_HISTORY,
HeaderProvider.getDefaultHeaders(authData, deviceInfo),
reqParams,
ResponseWrapper.ADAPTER
GoogleApiResponse.ADAPTER
)
GetPurchaseHistoryResult.parseFrom(response.payload?.purchaseHistoryResponse)
} catch (e: IOException) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ suspend fun HttpClient.downloadPackageComponents(
)
file
}.onFailure {
Log.w(TAG, "package component failed to downlaod from url ${info.url}, " +
Log.w(TAG, "package component failed to download from url ${info.url}, " +
"to be saved as `${info.componentName}`", it)
}.getOrNull()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ package org.microg.vending.delivery

import android.util.Log
import com.android.vending.buildRequestHeaders
import com.google.android.finsky.GoogleApiResponse
import com.google.android.finsky.splitinstallservice.PackageComponent
import org.microg.vending.billing.core.AuthData
import org.microg.vending.billing.core.GooglePlayApi.Companion.URL_DELIVERY
import org.microg.vending.billing.core.HttpClient
import org.microg.vending.billing.proto.GoogleApiResponse
import org.microg.vending.splitinstall.SPLIT_LANGUAGE_TAG

private const val TAG = "GmsVendingDelivery"
Expand Down Expand Up @@ -60,24 +60,24 @@ suspend fun HttpClient.requestDownloadUrls(
)
Log.d(TAG, "requestDownloadUrls end response -> $response")

val basePackage = response.response!!.splitReqResult!!.pkgList?.let {
val basePackage = response.payload!!.deliveryResponse!!.deliveryData?.let {
if (it.baseUrl != null && it.baseBytes != null) {
PackageComponent(packageName, "base", it.baseUrl, it.baseBytes)
} else null
}
val splitComponents = response.response.splitReqResult!!.pkgList!!.pkgDownLoadInfo.filter {
!it.splitPkgName.isNullOrEmpty() && !it.downloadUrl.isNullOrEmpty()
val splitComponents = response.payload.deliveryResponse!!.deliveryData!!.splitPackages.filter {
!it.splitPackageName.isNullOrEmpty() && !it.downloadUrl.isNullOrEmpty()
}.map {
if (requestSplitPackages != null) {
// Only download requested, if specific components were requested
requestSplitPackages.firstOrNull { requestComponent ->
requestComponent.contains(it.splitPkgName!!)
requestComponent.contains(it.splitPackageName!!)
}?.let { requestComponent ->
PackageComponent(packageName, requestComponent, it.downloadUrl!!, it.size!!)
}
} else {
// Download all offered components (server chooses)
PackageComponent(packageName, it.splitPkgName!!, it.downloadUrl!!, it.size!!)
PackageComponent(packageName, it.splitPackageName!!, it.downloadUrl!!, it.size!!)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.microg.vending.enterprise

import com.google.android.finsky.AppInstallPolicy
import org.microg.vending.enterprise.proto.AppInstallPolicy

class EnterpriseApp(
packageName: String,
Expand Down
21 changes: 10 additions & 11 deletions vending-app/src/main/java/org/microg/vending/ui/VendingActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,9 @@ import androidx.compose.runtime.mutableStateMapOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import com.android.vending.AppMeta
import com.android.vending.GetItemsRequest
import com.android.vending.GetItemsResponse
import com.android.vending.RequestApp
import com.android.vending.RequestItem
import com.android.vending.buildRequestHeaders
import com.android.vending.installer.installPackages
import com.android.volley.VolleyError
import com.google.android.finsky.GoogleApiResponse
import com.android.vending.installer.uninstallPackage
import kotlinx.coroutines.runBlocking
import org.microg.gms.common.DeviceConfiguration
Expand All @@ -45,10 +39,15 @@ import org.microg.vending.billing.core.GooglePlayApi.Companion.URL_FDFE
import org.microg.vending.billing.core.GooglePlayApi.Companion.URL_ITEM_DETAILS
import org.microg.vending.billing.core.HttpClient
import org.microg.vending.billing.createDeviceEnvInfo
import org.microg.vending.billing.proto.GoogleApiResponse
import org.microg.vending.delivery.downloadPackageComponents
import org.microg.vending.enterprise.EnterpriseApp
import org.microg.vending.delivery.requestDownloadUrls
import org.microg.vending.enterprise.AppState
import org.microg.vending.proto.AppMeta
import org.microg.vending.proto.GetItemsRequest
import org.microg.vending.proto.RequestApp
import org.microg.vending.proto.RequestItem
import org.microg.vending.ui.components.EnterpriseList
import org.microg.vending.ui.components.NetworkState
import java.io.IOException
Expand Down Expand Up @@ -178,14 +177,14 @@ class VendingActivity : ComponentActivity() {
),
adapter = GoogleApiResponse.ADAPTER
)
Log.d(TAG, "uploaddc: ${upload.response!!.uploadDeviceConfigResponse}")
Log.d(TAG, "uploaddc: ${upload.payload!!.uploadDeviceConfigResponse}")

// Fetch list of apps available to the scoped enterprise account
val apps = client.post(
url = URL_ENTERPRISE_CLIENT_POLICY,
headers = headers.plus("content-type" to "application/x-protobuf"),
adapter = GoogleApiResponse.ADAPTER
).response?.enterpriseClientPolicyResult?.policy?.apps?.filter { it.packageName != null && it.policy != null }
).payload?.enterpriseClientPolicyResponse?.policy?.apps?.filter { it.packageName != null && it.policy != null }

if (apps == null) {
Log.e(TAG, "unexpected network response: missing expected fields")
Expand All @@ -200,13 +199,13 @@ class VendingActivity : ComponentActivity() {
url = URL_ITEM_DETAILS,
// TODO: meaning unclear, but returns 400 without. constant? possibly has influence on which fields are returned?
headers = headers.plus("x-dfe-item-field-mask" to "GgWGHay3ByILPP/Avy+4A4YlCRM"),
adapter = GetItemsResponse.ADAPTER,
payload = GetItemsRequest(
apps.map {
RequestItem(RequestApp(AppMeta(it.packageName)))
}
)
).items.map { it.response }.filterNotNull().associate { item ->
),
adapter = GoogleApiResponse.ADAPTER
).getItemsResponses.mapNotNull { it.response }.associate { item ->
val packageName = item.meta!!.packageName!!
val installedDetails = this@VendingActivity.packageManager.getInstalledPackages(0).find {
it.applicationInfo.packageName == packageName
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,9 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.android.vending.R
import com.google.android.finsky.AppInstallPolicy
import org.microg.vending.enterprise.App
import org.microg.vending.enterprise.AppState
import org.microg.vending.enterprise.EnterpriseApp
import org.microg.vending.enterprise.proto.AppInstallPolicy


@Composable
Expand Down
21 changes: 20 additions & 1 deletion vending-app/src/main/kotlin/com/android/vending/extensions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,29 @@ import android.accounts.AccountManagerFuture
import android.os.Bundle
import android.util.Base64
import android.util.Log
import com.google.android.gms.common.BuildConfig
import okio.ByteString
import org.microg.gms.profile.Build
import org.microg.vending.billing.getUserAgent
import org.microg.vending.proto.AndroidVersionMeta
import org.microg.vending.proto.DeviceMeta
import org.microg.vending.proto.EncodedTriple
import org.microg.vending.proto.EncodedTripleWrapper
import org.microg.vending.proto.IntWrapper
import org.microg.vending.proto.Locality
import org.microg.vending.proto.LocalityWrapper
import org.microg.vending.proto.RequestHeader
import org.microg.vending.proto.RequestLanguagePackage
import org.microg.vending.proto.StringWrapper
import org.microg.vending.proto.Timestamp
import org.microg.vending.proto.TimestampContainer
import org.microg.vending.proto.TimestampContainer1
import org.microg.vending.proto.TimestampContainer1Wrapper
import org.microg.vending.proto.TimestampContainer2
import org.microg.vending.proto.TimestampStringWrapper
import org.microg.vending.proto.TimestampWrapper
import org.microg.vending.proto.UnknownByte12
import org.microg.vending.proto.UserAgent
import org.microg.vending.proto.Uuid
import java.io.ByteArrayOutputStream
import java.io.IOException
import java.net.URLEncoder
Expand Down
58 changes: 58 additions & 0 deletions vending-app/src/main/proto/DeliveryResponse.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@

option java_package = "org.microg.vending.delivery.proto";
option java_multiple_files = true;

message DeliveryResponse {
optional DeliveryStatus status = 1;
optional DeliveryData deliveryData = 2;
}

enum DeliveryStatus {
SUCCESS = 1;
NOT_SUPPORTED = 2;
NOT_PURCHASED = 3;
APP_REMOVED = 7;
APP_NOT_SUPPORTED = 9;
}

message DeliveryData {
/*
* Size of the file downloaded through `baseUrl` in bytes.
*/
optional uint32 baseBytes = 1;
/*
* Location of `base.apk`.
*/
optional string baseUrl = 3;
repeated SplitDeliveryData splitPackages = 15;
}

/*
* Encodes additional app bundle components (according to observations, both
* OBB and split APK files).
*/
message SplitDeliveryData {
optional string splitPackageName = 1;
/*
* Size of the package described by this message, i.e. the file at `downloadUrl`.
*/
optional uint32 size = 2;
optional string sha1 = 4;
optional string downloadUrl = 5;
/*
* Alternative download? Meaning not clear, unused.
*/
optional DownloadInfo downloadInfo1 = 8;
optional string sha256 = 9;
optional string unknownInfoString = 15;
/*
* Alternative download? Meaning not clear, unused.
*/
optional DownloadInfo downloadInfo2 = 16;
}

message DownloadInfo {
optional int32 id = 1;
optional uint32 bytes = 2;
optional string url = 3;
}
4 changes: 2 additions & 2 deletions vending-app/src/main/proto/EnterpriseClientPolicy.proto
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@

syntax = "proto3";

option java_package = "com.google.android.finsky";
option java_package = "org.microg.vending.enterprise.proto";
option java_multiple_files = true;

message EnterpriseClientPolicyResponse {
Expand All @@ -20,6 +19,7 @@ message App {
optional int32 unknownNumber = 9; // = 1
}

// TODO: could be inaccurate
enum AppInstallPolicy {
UNKNOWN = 0;
OPTIONAL = 1;
Expand Down
2 changes: 1 addition & 1 deletion vending-app/src/main/proto/GetItemsRequest.proto
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
syntax = "proto3";

option java_package = "com.android.vending";
option java_package = "org.microg.vending.proto";
option java_multiple_files = true;

message GetItemsRequest {
Expand Down
Loading

0 comments on commit 2e1dfec

Please sign in to comment.