Skip to content

Commit 8bfd3f0

Browse files
committed
Play Source
* Play Search: Search only works for package names. Install will work for some apps. Very alpha.
1 parent 057a0c9 commit 8bfd3f0

17 files changed

+568
-4
lines changed

app/build.gradle.kts

+4-3
Original file line numberDiff line numberDiff line change
@@ -93,16 +93,17 @@ dependencies {
9393
implementation("androidx.work:work-runtime-ktx:2.9.0")
9494
implementation("io.insert-koin:koin-android:3.4.2")
9595
implementation("io.insert-koin:koin-androidx-compose:3.4.2")
96-
implementation("com.squareup.retrofit2:retrofit:2.9.0")
97-
implementation("com.squareup.retrofit2:converter-gson:2.9.0")
98-
implementation("com.squareup.okhttp3:logging-interceptor:4.11.0")
96+
implementation("com.squareup.retrofit2:retrofit:2.10.0")
97+
implementation("com.squareup.retrofit2:converter-gson:2.10.0")
98+
implementation("com.squareup.okhttp3:logging-interceptor:4.12.0")
9999
implementation("com.google.code.gson:gson:2.10.1")
100100
implementation("io.coil-kt:coil-compose:2.4.0")
101101
implementation("com.github.rumboalla.KryptoPrefs:kryptoprefs:0.4.3")
102102
implementation("com.github.rumboalla.KryptoPrefs:kryptoprefs-gson:0.4.3")
103103
implementation("org.jsoup:jsoup:1.16.1")
104104
implementation("com.github.topjohnwu.libsu:core:5.2.1")
105105
implementation("io.github.g00fy2:versioncompare:1.5.0")
106+
implementation("com.gitlab.AuroraOSS:gplayapi:3.2.10")
106107

107108
testImplementation("junit:junit:4.13.2")
108109

app/src/main/kotlin/com/apkupdater/data/ui/Source.kt

+1
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,4 @@ val IzzySource = Source("F-Droid (Izzy)", R.drawable.ic_izzy)
1515
val AptoideSource = Source("Aptoide", R.drawable.ic_aptoide)
1616
val ApkPureSource = Source("ApkPure", R.drawable.ic_apkpure)
1717
val GitLabSource = Source("GitLab", R.drawable.ic_gitlab)
18+
val PlaySource = Source("Play", R.drawable.ic_play)

app/src/main/kotlin/com/apkupdater/di/MainModule.kt

+4-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import com.apkupdater.repository.AptoideRepository
1313
import com.apkupdater.repository.FdroidRepository
1414
import com.apkupdater.repository.GitHubRepository
1515
import com.apkupdater.repository.GitLabRepository
16+
import com.apkupdater.repository.PlayRepository
1617
import com.apkupdater.repository.SearchRepository
1718
import com.apkupdater.repository.UpdatesRepository
1819
import com.apkupdater.service.ApkMirrorService
@@ -145,13 +146,15 @@ val mainModule = module {
145146

146147
single { AptoideRepository(get(), get(), get()) }
147148

149+
single { PlayRepository(get(), get(), get()) }
150+
148151
single(named("main")) { FdroidRepository(get(), "https://f-droid.org/repo/", FdroidSource, get()) }
149152

150153
single(named("izzy")) { FdroidRepository(get(), "https://apt.izzysoft.de/fdroid/repo/", IzzySource, get()) }
151154

152155
single { UpdatesRepository(get(), get(), get(), get(named("main")), get(named("izzy")), get(), get(), get(), get()) }
153156

154-
single { SearchRepository(get(), get(named("main")), get(named("izzy")), get(), get(), get(), get(), get()) }
157+
single { SearchRepository(get(), get(named("main")), get(named("izzy")), get(), get(), get(), get(), get(), get()) }
155158

156159
single { KryptoBuilder.nocrypt(get(), androidContext().getString(R.string.app_name)) }
157160

app/src/main/kotlin/com/apkupdater/prefs/Prefs.kt

+3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.apkupdater.prefs
22

33
import com.apkupdater.data.ui.Screen
4+
import com.aurora.gplayapi.data.models.AuthData
45
import com.kryptoprefs.context.KryptoContext
56
import com.kryptoprefs.gson.json
67
import com.kryptoprefs.preferences.KryptoPrefs
@@ -29,11 +30,13 @@ class Prefs(
2930
val useIzzy = boolean("useIzzy", defValue = true, backed = true)
3031
val useAptoide = boolean("useAptoide", defValue = true, backed = true)
3132
val useApkPure = boolean("useApkPure", defValue = true, backed = true)
33+
val usePlay = boolean("usePlay", defValue = true, backed = true)
3234
val enableAlarm = boolean("enableAlarm", defValue = false, backed = true)
3335
val alarmHour = int("alarmHour", defValue = 12, backed = true)
3436
val alarmFrequency = int("alarmFrequency", 0, backed = true)
3537
val androidTvUi = boolean("androidTvUi", defValue = isAndroidTv, backed = true)
3638
val rootInstall = boolean("rootInstall", defValue = false, backed = true)
3739
val theme = int("theme", defValue = 0, backed = true)
3840
val lastTab = string("lastTab", defValue = Screen.Updates.route, backed = true)
41+
val playAuthData = json("playAuthData", AuthData("", ""), true)
3942
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package com.apkupdater.repository
2+
3+
import android.content.Context
4+
import android.net.Uri
5+
import android.util.Log
6+
import com.apkupdater.data.ui.AppUpdate
7+
import com.apkupdater.data.ui.PlaySource
8+
import com.apkupdater.prefs.Prefs
9+
import com.apkupdater.util.play.NativeDeviceInfoProvider
10+
import com.apkupdater.util.play.PlayHttpClient
11+
import com.aurora.gplayapi.data.models.AuthData
12+
import com.aurora.gplayapi.helpers.AppDetailsHelper
13+
import com.aurora.gplayapi.helpers.PurchaseHelper
14+
import com.google.gson.Gson
15+
import kotlinx.coroutines.flow.catch
16+
import kotlinx.coroutines.flow.flow
17+
18+
19+
class PlayRepository(
20+
private val context: Context,
21+
private val gson: Gson,
22+
private val prefs: Prefs
23+
) {
24+
private suspend fun auth(): AuthData {
25+
val savedData = prefs.playAuthData.get()
26+
if (savedData.email.isEmpty()) {
27+
val properties = NativeDeviceInfoProvider(context).getNativeDeviceProperties()
28+
val playResponse = PlayHttpClient.postAuth(
29+
"https://auroraoss.com/api/auth",
30+
gson.toJson(properties).toByteArray()
31+
)
32+
if (playResponse.isSuccessful) {
33+
val authData = gson.fromJson(String(playResponse.responseBytes), AuthData::class.java)
34+
prefs.playAuthData.put(authData)
35+
return authData
36+
}
37+
throw IllegalStateException("Auth not successful.")
38+
}
39+
return savedData
40+
}
41+
42+
suspend fun search(text: String) = flow {
43+
if (text.contains(" ") || !text.contains(".")) {
44+
emit(Result.success(emptyList()))
45+
return@flow
46+
}
47+
val authData = auth()
48+
val details = AppDetailsHelper(authData).using(PlayHttpClient)
49+
val app = details.getAppByPackageName(text)
50+
val files = PurchaseHelper(authData).purchase(app.packageName, app.versionCode, app.offerType)
51+
val link = files.joinToString(separator = ",") { it.url }
52+
val update = AppUpdate(
53+
app.displayName,
54+
app.packageName,
55+
app.versionName,
56+
"",
57+
app.versionCode.toLong(),
58+
0L,
59+
PlaySource,
60+
Uri.parse(app.iconArtwork.url),
61+
link,
62+
whatsNew = app.changes
63+
)
64+
emit(Result.success(listOf(update)))
65+
}.catch {
66+
emit(Result.failure(it))
67+
Log.e("PlayRepository", "Error searching.", it)
68+
}
69+
70+
}

app/src/main/kotlin/com/apkupdater/repository/SearchRepository.kt

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class SearchRepository(
1717
private val gitHubRepository: GitHubRepository,
1818
private val apkPureRepository: ApkPureRepository,
1919
private val gitLabRepository: GitLabRepository,
20+
private val playRepository: PlayRepository,
2021
private val prefs: Prefs
2122
) {
2223

@@ -29,6 +30,7 @@ class SearchRepository(
2930
if (prefs.useGitHub.get()) sources.add(gitHubRepository.search(text))
3031
if (prefs.useApkPure.get()) sources.add(apkPureRepository.search(text))
3132
if (prefs.useGitLab.get()) sources.add(gitLabRepository.search(text))
33+
if (prefs.usePlay.get()) sources.add(playRepository.search(text))
3234

3335
if (sources.isNotEmpty()) {
3436
sources.combine { updates ->

app/src/main/kotlin/com/apkupdater/ui/screen/SettingsScreen.kt

+6
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,12 @@ fun Settings(viewModel: SettingsViewModel) = LazyColumn {
241241
stringResource(R.string.source_apkpure),
242242
R.drawable.ic_apkpure
243243
)
244+
SwitchSetting(
245+
{ viewModel.getUsePlay() },
246+
{ viewModel.setUsePlay(it) },
247+
stringResource(R.string.source_play) + " (Alpha)",
248+
R.drawable.ic_play
249+
)
244250
}
245251

246252
item {

app/src/main/kotlin/com/apkupdater/util/SessionInstaller.kt

+3
Original file line numberDiff line numberDiff line change
@@ -110,4 +110,7 @@ class SessionInstaller(private val context: Context) {
110110
file.delete()
111111
}
112112

113+
suspend fun playInstall(id: Int, packageName: String, streams: List<InputStream>) =
114+
install(id, packageName, streams)
115+
113116
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package com.apkupdater.util.play
2+
3+
import android.opengl.GLES10
4+
import android.text.TextUtils
5+
import javax.microedition.khronos.egl.EGL10
6+
import javax.microedition.khronos.egl.EGLConfig
7+
import javax.microedition.khronos.egl.EGLContext
8+
import javax.microedition.khronos.egl.EGLDisplay
9+
10+
11+
object EglExtensionProvider {
12+
@JvmStatic
13+
val eglExtensions: List<String>
14+
get() {
15+
val glExtensions: MutableSet<String> = HashSet()
16+
val egl10 = EGLContext.getEGL() as EGL10
17+
val display = egl10.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY)
18+
egl10.eglInitialize(display, IntArray(2))
19+
val cf = IntArray(1)
20+
if (egl10.eglGetConfigs(display, null, 0, cf)) {
21+
val configs = arrayOfNulls<EGLConfig>(cf[0])
22+
if (egl10.eglGetConfigs(display, configs, cf[0], cf)) {
23+
val a1 = intArrayOf(EGL10.EGL_WIDTH, EGL10.EGL_PBUFFER_BIT, EGL10.EGL_HEIGHT, EGL10.EGL_PBUFFER_BIT, EGL10.EGL_NONE)
24+
val a2 = intArrayOf(12440, EGL10.EGL_PIXMAP_BIT, EGL10.EGL_NONE)
25+
val a3 = IntArray(1)
26+
for (i in 0 until cf[0]) {
27+
egl10.eglGetConfigAttrib(display, configs[i], EGL10.EGL_CONFIG_CAVEAT, a3)
28+
if (a3[0] != EGL10.EGL_SLOW_CONFIG) {
29+
egl10.eglGetConfigAttrib(display, configs[i], EGL10.EGL_SURFACE_TYPE, a3)
30+
if (1 and a3[0] != 0) {
31+
egl10.eglGetConfigAttrib(display, configs[i], EGL10.EGL_RENDERABLE_TYPE, a3)
32+
if (1 and a3[0] != 0) {
33+
addExtensionsForConfig(egl10, display, configs[i], a1, null, glExtensions)
34+
}
35+
if (4 and a3[0] != 0) {
36+
addExtensionsForConfig(egl10, display, configs[i], a1, a2, glExtensions)
37+
}
38+
}
39+
}
40+
}
41+
}
42+
}
43+
egl10.eglTerminate(display)
44+
return ArrayList(glExtensions).sorted()
45+
}
46+
47+
private fun addExtensionsForConfig(
48+
egl10: EGL10,
49+
eglDisplay: EGLDisplay,
50+
eglConfig: EGLConfig?,
51+
ai: IntArray,
52+
ai1: IntArray?,
53+
set: MutableSet<String>
54+
) {
55+
val eglContext = egl10.eglCreateContext(eglDisplay, eglConfig, EGL10.EGL_NO_CONTEXT, ai1)
56+
if (eglContext === EGL10.EGL_NO_CONTEXT) {
57+
return
58+
}
59+
val eglSurface = egl10.eglCreatePbufferSurface(eglDisplay, eglConfig, ai)
60+
if (eglSurface === EGL10.EGL_NO_SURFACE) {
61+
egl10.eglDestroyContext(eglDisplay, eglContext)
62+
} else {
63+
egl10.eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext)
64+
val s = GLES10.glGetString(7939)
65+
if (!TextUtils.isEmpty(s)) {
66+
val split = s.split(" ".toRegex()).toTypedArray()
67+
val i = split.size
68+
set.addAll(listOf(*split).subList(0, i))
69+
}
70+
egl10.eglMakeCurrent(
71+
eglDisplay,
72+
EGL10.EGL_NO_SURFACE,
73+
EGL10.EGL_NO_SURFACE,
74+
EGL10.EGL_NO_CONTEXT
75+
)
76+
egl10.eglDestroySurface(eglDisplay, eglSurface)
77+
egl10.eglDestroyContext(eglDisplay, eglContext)
78+
}
79+
}
80+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.apkupdater.util.play
2+
3+
import com.aurora.gplayapi.network.IHttpClient
4+
5+
6+
interface IProxyHttpClient : IHttpClient {
7+
@Throws(UnsupportedOperationException::class)
8+
fun setProxy(proxyInfo: ProxyInfo): IHttpClient
9+
}

0 commit comments

Comments
 (0)