diff --git a/app/build.gradle b/app/build.gradle index 87e1b1af8..04ac9976a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -19,8 +19,8 @@ android { applicationId "net.xzos.upgradeall" minSdkVersion 21 targetSdkVersion 33 - versionCode 99 - versionName "0.13-alpha.2" + versionCode 100 + versionName "0.13-alpha.3" if (project.hasProperty('appVerName')) { versionName = "${versionName}_${appVerName}" } @@ -76,14 +76,6 @@ android { dataBinding true viewBinding true } - packagingOptions { - jniLibs { - excludes += ['META-INF/**', 'kotlin/**', 'org/**'] - } - resources { - excludes += ['META-INF/**', 'kotlin/**', 'org/**', '**.properties', '**.bin'] - } - } dependenciesInfo.includeInApk false lint { @@ -169,4 +161,11 @@ dependencies { implementation 'com.google.firebase:firebase-analytics:21.0.0' implementation 'com.google.firebase:firebase-crashlytics:18.2.11' } + //Protobuf + implementation "com.google.protobuf:protobuf-java:3.21.2" +} +// fix different protobuf versions of gplayapi and firebase +configurations { + all*.exclude group: 'com.google.protobuf', module: 'protobuf-javalite' + all*.exclude group: 'com.google.firebase', module: 'protolite-well-known-types' } \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 3ad15ab99..4493df4db 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -162,4 +162,8 @@ -keep class * extends androidx.room.RoomDatabase -keep @androidx.room.Entity class * -dontwarn androidx.room.paging.** -##---------------End: proguard configuration for ROOM ---------- \ No newline at end of file +##---------------End: proguard configuration for ROOM ---------- + +##---------------Begin: proguard configuration for Firebase ---------- +-keep class com.google.firebase.** { *; } +##---------------End: proguard configuration for Firebase ---------- diff --git a/core-utils/src/main/java/net/xzos/upgradeall/core/utils/LocaleUtils.kt b/core-utils/src/main/java/net/xzos/upgradeall/core/utils/LocaleUtils.kt new file mode 100644 index 000000000..ff36ff756 --- /dev/null +++ b/core-utils/src/main/java/net/xzos/upgradeall/core/utils/LocaleUtils.kt @@ -0,0 +1,12 @@ +package net.xzos.upgradeall.core.utils + +import java.util.* + +/** + * 提供 Android properties 格式的 Locale + * 例如:* toString(): zh_CN + */ +fun getLocale(): Locale { + val locale = Locale.getDefault() + return Locale(locale.language, locale.country) +} \ No newline at end of file diff --git a/core-websdk/build.gradle b/core-websdk/build.gradle index 4e58b9d64..809bb1ebc 100644 --- a/core-websdk/build.gradle +++ b/core-websdk/build.gradle @@ -53,4 +53,6 @@ dependencies { implementation 'org.dom4j:dom4j:2.1.3' // markdown support implementation 'org.jetbrains:markdown:0.3.1' + // google play support + implementation('com.gitlab.AuroraOSS:gplayapi:0e224071') } \ No newline at end of file diff --git a/core-websdk/proguard-rules.pro b/core-websdk/proguard-rules.pro index 481bb4348..a1e5acf75 100644 --- a/core-websdk/proguard-rules.pro +++ b/core-websdk/proguard-rules.pro @@ -18,4 +18,8 @@ # If you keep the line number information, uncomment this to # hide the original source file name. -#-renamesourcefileattribute SourceFile \ No newline at end of file +#-renamesourcefileattribute SourceFile + +##---------------Begin: proguard configuration for GPlay API ---------- +-keep public class com.aurora.gplayapi.** { *; } +##---------------End: proguard configuration for GPlay API ---------- \ No newline at end of file diff --git a/core-websdk/src/main/java/net/xzos/upgradeall/core/websdk/api/client_proxy/ClientProxyApi.kt b/core-websdk/src/main/java/net/xzos/upgradeall/core/websdk/api/client_proxy/ClientProxyApi.kt index 9bf56daa6..8c0a1ef51 100644 --- a/core-websdk/src/main/java/net/xzos/upgradeall/core/websdk/api/client_proxy/ClientProxyApi.kt +++ b/core-websdk/src/main/java/net/xzos/upgradeall/core/websdk/api/client_proxy/ClientProxyApi.kt @@ -23,6 +23,7 @@ internal class ClientProxyApi(dataCache: DataCacheManager) : BaseApi { LsposedRepo(dataCache, okhttpProxy), FDroid(dataCache, okhttpProxy), Gitlab(dataCache, okhttpProxy), + GooglePlay(dataCache, okhttpProxy), ).associateBy({ it.uuid }, { it }) override fun getCloudConfig(url: String): CloudConfigList? { diff --git a/core-websdk/src/main/java/net/xzos/upgradeall/core/websdk/api/client_proxy/Constants.kt b/core-websdk/src/main/java/net/xzos/upgradeall/core/websdk/api/client_proxy/Constants.kt new file mode 100644 index 000000000..833fc76c5 --- /dev/null +++ b/core-websdk/src/main/java/net/xzos/upgradeall/core/websdk/api/client_proxy/Constants.kt @@ -0,0 +1,3 @@ +package net.xzos.upgradeall.core.websdk.api.client_proxy + +const val APK_CONTENT_TYPE = "application/vnd.android.package-archive" \ No newline at end of file diff --git a/core-websdk/src/main/java/net/xzos/upgradeall/core/websdk/api/client_proxy/hubs/CoolApk.kt b/core-websdk/src/main/java/net/xzos/upgradeall/core/websdk/api/client_proxy/hubs/CoolApk.kt index a490625a0..eaf0cbe9a 100644 --- a/core-websdk/src/main/java/net/xzos/upgradeall/core/websdk/api/client_proxy/hubs/CoolApk.kt +++ b/core-websdk/src/main/java/net/xzos/upgradeall/core/websdk/api/client_proxy/hubs/CoolApk.kt @@ -10,6 +10,7 @@ import net.xzos.upgradeall.core.utils.log.Log import net.xzos.upgradeall.core.utils.log.ObjectTag import net.xzos.upgradeall.core.utils.log.ObjectTag.Companion.core import net.xzos.upgradeall.core.utils.md5 +import net.xzos.upgradeall.core.websdk.api.client_proxy.APK_CONTENT_TYPE import net.xzos.upgradeall.core.websdk.api.web.http.HttpRequestData import net.xzos.upgradeall.core.websdk.api.web.proxy.OkhttpProxy import net.xzos.upgradeall.core.websdk.base_model.ApiRequestData @@ -97,9 +98,7 @@ internal class CoolApk( assetGson: AssetGson? ): List? { val request = assetGson?.downloadUrl?.let { httpRedirects(it) } - if (request?.headers?.get("Content-Type")?.split(";") - ?.get(0) != "application/vnd.android.package-archive" - ) { + if (request?.headers?.get("Content-Type")?.split(";")?.get(0) != APK_CONTENT_TYPE) { Log.i(logObjectTag, TAG, "getDownload: 返回非安装包数据") val newAssets = getRelease(data)?.get(assetIndex[0])?.assetGsonList?.get(assetIndex[1]) ?: return null diff --git a/core-websdk/src/main/java/net/xzos/upgradeall/core/websdk/api/client_proxy/hubs/FDroid.kt b/core-websdk/src/main/java/net/xzos/upgradeall/core/websdk/api/client_proxy/hubs/FDroid.kt index eb9afac99..1f1e34dec 100644 --- a/core-websdk/src/main/java/net/xzos/upgradeall/core/websdk/api/client_proxy/hubs/FDroid.kt +++ b/core-websdk/src/main/java/net/xzos/upgradeall/core/websdk/api/client_proxy/hubs/FDroid.kt @@ -4,6 +4,7 @@ import net.xzos.upgradeall.core.utils.constant.ANDROID_APP_TYPE import net.xzos.upgradeall.core.utils.constant.VERSION_CODE import net.xzos.upgradeall.core.utils.data_cache.DataCacheManager import net.xzos.upgradeall.core.utils.data_cache.utils.StringEncoder +import net.xzos.upgradeall.core.websdk.api.client_proxy.APK_CONTENT_TYPE import net.xzos.upgradeall.core.websdk.api.web.http.HttpRequestData import net.xzos.upgradeall.core.websdk.api.web.proxy.OkhttpProxy import net.xzos.upgradeall.core.websdk.base_model.ApiRequestData @@ -34,10 +35,7 @@ class FDroid( changelog = changelog.apply { changelog = null }, assetGsonList = listOf( it.valueOf("apkname").let { name -> - AssetGson( - name, "application/vnd.android.package-archive", - "$url/$name" - ) + AssetGson(name, APK_CONTENT_TYPE, "$url/$name") } ) ) diff --git a/core-websdk/src/main/java/net/xzos/upgradeall/core/websdk/api/client_proxy/hubs/GooglePlay.kt b/core-websdk/src/main/java/net/xzos/upgradeall/core/websdk/api/client_proxy/hubs/GooglePlay.kt new file mode 100644 index 000000000..953370d2c --- /dev/null +++ b/core-websdk/src/main/java/net/xzos/upgradeall/core/websdk/api/client_proxy/hubs/GooglePlay.kt @@ -0,0 +1,84 @@ +package net.xzos.upgradeall.core.websdk.api.client_proxy.hubs + +import com.aurora.gplayapi.DeviceManager +import com.aurora.gplayapi.data.models.AuthData +import com.aurora.gplayapi.data.providers.DeviceInfoProvider +import com.aurora.gplayapi.helpers.AppDetailsHelper +import com.aurora.gplayapi.helpers.AuthHelper +import com.aurora.gplayapi.helpers.PurchaseHelper +import net.xzos.upgradeall.core.utils.constant.ANDROID_APP_TYPE +import net.xzos.upgradeall.core.utils.constant.VERSION_CODE +import net.xzos.upgradeall.core.utils.data_cache.DataCacheManager +import net.xzos.upgradeall.core.utils.data_cache.utils.JsonObjectEncoder +import net.xzos.upgradeall.core.utils.getLocale +import net.xzos.upgradeall.core.websdk.api.client_proxy.APK_CONTENT_TYPE +import net.xzos.upgradeall.core.websdk.api.web.http.HttpRequestData +import net.xzos.upgradeall.core.websdk.api.web.proxy.OkhttpProxy +import net.xzos.upgradeall.core.websdk.base_model.ApiRequestData +import net.xzos.upgradeall.core.websdk.json.AssetGson +import net.xzos.upgradeall.core.websdk.json.DownloadItem +import net.xzos.upgradeall.core.websdk.json.ReleaseGson +import org.json.JSONObject + +class GooglePlay( + dataCache: DataCacheManager, okhttpProxy: OkhttpProxy +) : BaseHub(dataCache, okhttpProxy) { + override val uuid: String = "65c2f60c-7d08-48b8-b4ba-ac6ee924f6fa" + + private fun getAuthJson(url: String = "https://auroraoss.com/api/auth"): JSONObject? { + return dataCache.get("AuroraOSS_auth", JsonObjectEncoder) { + okhttpProxy.okhttpExecute(HttpRequestData(url))?.body?.string() + ?.let { JSONObject(it) } + } + } + + private fun getAuthData(authJson: JSONObject, deviceName: String = "px_3a"): AuthData? { + val email = authJson.getString("email") + val auth = authJson.getString("auth") + val properties = DeviceManager.loadProperties("$deviceName.properties") ?: return null + val locale = getLocale() + val deviceInfoProvider = DeviceInfoProvider(properties, locale.toString()) + return AuthHelper.buildInsecure(email, auth, locale, deviceInfoProvider) + } + + override fun getRelease(data: ApiRequestData): List? { + val appPackage = data.appId[ANDROID_APP_TYPE] ?: return emptyList() + val authJson = getAuthJson() ?: return null + val authData = getAuthData(authJson) ?: return null + val detailHelper = AppDetailsHelper(authData) + val app = detailHelper.getAppByPackageName(appPackage) + return listOf( + ReleaseGson( + versionNumber = app.versionName, + extra = mapOf(VERSION_CODE to app.versionCode), + changelog = app.changes, + assetGsonList = app.fileList.map { + AssetGson( + fileName = it.name, + fileType = APK_CONTENT_TYPE, + downloadUrl = it.url, + ) + } + ) + ) + } + + override fun getDownload( + data: ApiRequestData, + assetIndex: List, + assetGson: AssetGson? + ): List? { + val appPackage = data.appId[ANDROID_APP_TYPE] ?: return emptyList() + val authJson = getAuthJson() ?: return null + val authData = getAuthData(authJson) ?: return null + val detailHelper = AppDetailsHelper(authData) + val app = detailHelper.getAppByPackageName(appPackage) + return PurchaseHelper(authData).purchase( + app.packageName, + app.versionCode, + app.offerType + ).map { + DownloadItem(it.name, it.url, null, null) + } + } +} \ No newline at end of file