Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bazaar SDK Hackathon 1403 #2

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.farsitel.bazaar;
interface IAutoUpdateCheckService {
boolean isAutoUpdateEnable(String packageName);
boolean update(String packageName); // false mean you don't have permission
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.farsitel.bazaar.updater

sealed class AutoUpdateResult {
data class Success(val isEnable: Boolean) : AutoUpdateResult()
data class Error(val throwable: Throwable) : AutoUpdateResult()
}

inline fun AutoUpdateResult.doOnSuccess(call: (Boolean) -> Unit): AutoUpdateResult {
if (this is AutoUpdateResult.Success) call(isEnable)
return this
}

inline fun AutoUpdateResult.doOnError(call: (Throwable) -> Unit): AutoUpdateResult {
if (this is AutoUpdateResult.Error) call(throwable)
return this
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.farsitel.bazaar.updater

import android.content.ComponentName
import android.content.ServiceConnection
import android.os.IBinder
import com.farsitel.bazaar.IAutoUpdateCheckService
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

internal class AutoUpdateServiceConnection(
private val packageName: String,
private val scope: CoroutineScope,
private val onResult: ((Boolean) -> Unit),
private val onError: ((Throwable) -> Unit),
) : ServiceConnection {

private var service: IAutoUpdateCheckService? = null

override fun onServiceConnected(name: ComponentName?, boundService: IBinder?) {
service = IAutoUpdateCheckService.Stub.asInterface(boundService)
try {
scope.launch(Dispatchers.IO) {
val isEnabled = service?.isAutoUpdateEnable(packageName)
onResult(isEnabled ?: false)
}
} catch (t: Throwable) {
onError(t)
}
}

override fun onServiceDisconnected(p0: ComponentName?) {
}
}
87 changes: 76 additions & 11 deletions updater/src/main/java/com/farsitel/bazaar/updater/BazaarUpdater.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ import java.lang.ref.WeakReference

object BazaarUpdater {

private var connection: WeakReference<UpdateServiceConnection>? = null
private var updateConnection: WeakReference<UpdateServiceConnection>? = null
private var autoUpdateConnection: WeakReference<AutoUpdateServiceConnection>? = null

fun getLastUpdateState(
context: Context,
Expand All @@ -25,14 +26,43 @@ object BazaarUpdater {
if (verifyBazaarIsInstalled(context).not()) {
onResult(UpdateResult.Error(BazaarIsNotInstalledException()))
} else {
initService(
initUpdateService(
context = context,
onResult = onResult,
scope = scope
)
}
}

fun getAutoUpdateState(
context: Context,
scope: CoroutineScope = retrieveScope(context),
onResult: (AutoUpdateResult) -> Unit
) {
if (verifyBazaarIsInstalled(context).not()) {
onResult(AutoUpdateResult.Error(BazaarIsNotInstalledException()))
} else {
initAutoUpdateService(
context = context,
onResult = onResult,
scope = scope
)
}
}

fun enableAutoUpdate(context: Context) {
if (verifyBazaarIsInstalled(context).not()) {
return
} else {
val intent = Intent(
Intent.ACTION_VIEW, "$BAZAAR_THIRD_PARTY_AUTO_UPDATE${context.packageName}".toUri()
).apply {
setPackage(BAZAAR_PACKAGE_NAME)
}
context.startActivity(intent)
}
}

fun updateApplication(context: Context) {
val intent = if (verifyBazaarIsInstalled(context).not()) {
Intent(Intent.ACTION_VIEW, "$BAZAAR_WEB_APP_DETAIL${context.packageName}".toUri())
Expand All @@ -57,40 +87,75 @@ object BazaarUpdater {
}
}

private fun initService(
private fun initUpdateService(
context: Context,
scope: CoroutineScope,
onResult: (UpdateResult) -> Unit
) {
connection = WeakReference(
updateConnection = WeakReference(
UpdateServiceConnection(
packageName = context.packageName,
scope = scope,
bazaarVersionCode = getBazaarVersionCode(context),
onResult = { updateVersion ->
onResult(parseUpdateResponse(version = updateVersion, context = context))
releaseService(context)
releaseUpdateService(context)
},
onError = { message ->
onResult(UpdateResult.Error(message))
releaseService(context)
releaseUpdateService(context)
}
))

val intent = Intent(BAZAAR_UPDATE_INTENT)
intent.setPackage(BAZAAR_PACKAGE_NAME)
try {
connection?.get()?.let { con ->
updateConnection?.get()?.let { con ->
context.bindService(intent, con, Context.BIND_AUTO_CREATE)
}
} catch (e: Exception) {
releaseService(context)
releaseUpdateService(context)
}
}

private fun initAutoUpdateService(
context: Context,
scope: CoroutineScope,
onResult: (AutoUpdateResult) -> Unit
) {
autoUpdateConnection = WeakReference(
AutoUpdateServiceConnection(
packageName = context.packageName,
scope = scope,
onResult = { isEnable ->
onResult(AutoUpdateResult.Success(isEnable))
releaseAutoUpdateService(context)
},
onError = { message ->
onResult(AutoUpdateResult.Error(message))
releaseUpdateService(context)
}
))

val intent = Intent(BAZAAR_AUTO_UPDATE_INTENT)
intent.setPackage(BAZAAR_PACKAGE_NAME)
try {
autoUpdateConnection?.get()?.let { con ->
context.bindService(intent, con, Context.BIND_AUTO_CREATE)
}
} catch (e: Exception) {
releaseAutoUpdateService(context)
}
}

/** This is our function to un-binds this activity from our service. */
private fun releaseService(context: Context) {
connection?.get()?.let { con -> context.unbindService(con) }
connection = null
private fun releaseUpdateService(context: Context) {
updateConnection?.get()?.let { con -> context.unbindService(con) }
updateConnection = null
}

private fun releaseAutoUpdateService(context: Context) {
autoUpdateConnection?.get()?.let { con -> context.unbindService(con) }
autoUpdateConnection = null
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package com.farsitel.bazaar.updater

internal const val BAZAAR_UPDATE_INTENT = "com.farsitel.bazaar.service.UpdateCheckService.BIND"
internal const val BAZAAR_AUTO_UPDATE_INTENT = "com.farsitel.bazaar.service.AutoUpdateCheckService.BIND"
internal const val BAZAAR_PACKAGE_NAME = "com.farsitel.bazaar"
internal const val BAZAAR_THIRD_PARTY_APP_DETAIL = "bazaar://details/modal?id="
internal const val BAZAAR_THIRD_PARTY_AUTO_UPDATE = "bazaar://autoupdate/modal?id="
internal const val BAZAAR_WEB_APP_DETAIL = "https://cafebazaar.ir/app/?id="
internal const val BAZAAR_ERROR_RESULT = -1L

Expand Down