Files
assistant-android/app/src/main/java/com/gh/common/util/GameActivityDownloadHelper.kt

430 lines
16 KiB
Kotlin

package com.gh.common.util
import android.annotation.SuppressLint
import android.content.Context
import android.text.TextUtils
import androidx.appcompat.app.AppCompatActivity
import com.gh.common.DefaultJsApi
import com.gh.gamecenter.common.constant.Constants
import com.gh.common.dialog.CertificationDialog
import com.gh.common.exposure.ExposureEvent
import com.gh.common.exposure.ExposureManager
import com.gh.common.exposure.ExposureSource
import com.gh.common.exposure.ExposureType
import com.gh.common.history.HistoryHelper
import com.gh.common.repository.ReservationRepository
import com.gh.gamecenter.core.runOnUiThread
import com.gh.gamecenter.common.view.dsbridge.CompletionHandler
import com.gh.download.DownloadManager
import com.gh.download.dialog.DownloadDialog
import com.gh.gamecenter.R
import com.gh.gamecenter.WebActivity
import com.gh.gamecenter.common.callback.ConfirmListener
import com.gh.gamecenter.common.utils.observableToMain
import com.gh.gamecenter.common.utils.singleToMain
import com.gh.gamecenter.common.utils.DialogHelper
import com.gh.gamecenter.core.utils.*
import com.gh.gamecenter.entity.ApkEntity
import com.gh.gamecenter.entity.GameEntity
import com.gh.gamecenter.entity.PluginLocation
import com.gh.gamecenter.gamedetail.dialog.GamePermissionDialogFragment
import com.gh.gamecenter.manager.UserManager
import com.gh.gamecenter.common.retrofit.EmptyResponse
import com.gh.gamecenter.common.retrofit.Response
import com.gh.gamecenter.retrofit.RetrofitManager
import com.gh.gamecenter.teenagermode.TeenagerModeActivity
import com.gh.gamecenter.common.retrofit.ApiResponse
import com.gh.gamecenter.common.utils.DataLogUtils
import com.lightgame.download.FileUtils
/**
* 游戏活动下载辅助类
*/
object GameActivityDownloadHelper {
private var mTraceEvent: ExposureEvent? = null
private var mGameEntity: GameEntity? = null
fun start(context: Context, event: DefaultJsApi.GameActivityEvent) {
if (mGameEntity != null && mGameEntity?.id == event.gameId) {
runOnUiThread {
handleGameEntity(context, event, mGameEntity!!)
}
} else {
RetrofitManager.getInstance()
.api
.getGameDigest(event.gameId)
.map(ApkActiveUtils.filterMapper)
.compose(observableToMain())
.subscribe(object : Response<GameEntity>() {
override fun onResponse(gameEntity: GameEntity?) {
mGameEntity = gameEntity
gameEntity?.let {
handleGameEntity(context, event, it)
}
}
})
}
}
private fun handleGameEntity(
context: Context,
event: DefaultJsApi.GameActivityEvent,
gameEntity: GameEntity
) {
// 青少年模式
if (isTeenageMode(context)) return
val entrance = "(游戏活动[${event.activityTitle}])"
val location = "游戏活动:${event.activityTitle}-${gameEntity.name}"
if (mTraceEvent == null) {
val exposureSources = arrayListOf(
ExposureSource("游戏活动", "${event.activityTitle}+${event.activityId}")
)
mTraceEvent = ExposureEvent.createEvent(gameEntity, exposureSources, null, ExposureType.EXPOSURE)
}
mTraceEvent?.run {
when {
// 预约
gameEntity.isReservable -> reserve(context, gameEntity, entrance, this)
// 开始玩
gameEntity.getApk().size == 0 && gameEntity.h5Link != null -> play(context, gameEntity)
// 下载
else -> handleDownload(context, event, gameEntity, entrance, location, this)
}
}
}
// 青少年模式
private fun isTeenageMode(context: Context): Boolean {
if (SPUtils.getBoolean(Constants.SP_TEENAGER_MODE)) {
DialogHelper.showDialog(
context,
"提示",
"当前处于儿童/青少年模式, \n暂不提供游戏下载",
"退出青少年模式",
"关闭",
{ context.startActivity(TeenagerModeActivity.getIntent(context)) },
{},
DialogHelper.Config(
centerTitle = true,
centerContent = true
)
)
return true
}
return false
}
// 预约
private fun reserve(
context: Context,
gameEntity: GameEntity,
entrance: String,
traceEvent: ExposureEvent
) {
if (!ReservationRepository.thisGameHasBeenReserved(gameEntity.id)) {
CheckLoginUtils.checkLogin(context, entrance) {
ReservationHelper.reserve(context, gameEntity.id, object : EmptyCallback {
override fun onCallback() {
LogUtils.logReservation(gameEntity, traceEvent)
clear()
}
})
}
} else {
ToastUtils.toast("游戏已成功预约")
}
}
// 开始玩(H5链接)
private fun play(context: Context, gameEntity: GameEntity) {
val linkEntity = gameEntity.h5Link
val isPlay = "play" == linkEntity!!.type // 是否为开始玩
if (isPlay) {
HistoryHelper.insertGameEntity(gameEntity)
}
val i = WebActivity.getIntentForWebGame(
context,
gameEntity.h5Link!!.link,
gameEntity.name,
isPlay,
linkEntity.closeButton
)
context.startActivity(i)
}
// 下载
private fun handleDownload(
context: Context,
event: DefaultJsApi.GameActivityEvent,
gameEntity: GameEntity,
entrance: String,
location: String,
traceEvent: ExposureEvent
) {
val apk = getApk(gameEntity, event, true) ?: return
val downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshotByUrl(apk.url)
if (downloadEntity != null) {
ToastUtils.toast("${gameEntity.name}已加入下载队列")
} else {
val str = GameUtils.getDownloadBtnText(context, gameEntity, PluginLocation.only_game)
if (str == context.getString(R.string.download)) {
GamePermissionDialogFragment.show((context as AppCompatActivity), gameEntity, gameEntity.info, object : ConfirmListener {
override fun onConfirm() {
CertificationDialog.showCertificationDialog(context, gameEntity, object : ConfirmListener {
override fun onConfirm() {
DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean ->
download(context, gameEntity, apk, isSubscribe, entrance, location, traceEvent)
}
}
})
}
})
DataLogUtils.uploadGameLog(context, gameEntity.id, gameEntity.name, entrance)
} else if (str == context.getString(R.string.attempt)) {
RealNameHelper.checkIfAuth(context, gameEntity, object : EmptyCallback {
override fun onCallback() {
GamePermissionDialogFragment.show((context as AppCompatActivity), gameEntity, gameEntity.info, object : ConfirmListener {
override fun onConfirm() {
CertificationDialog.showCertificationDialog(context, gameEntity, object : ConfirmListener {
override fun onConfirm() {
DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean ->
download(context, gameEntity, apk, isSubscribe, entrance, location, traceEvent)
}
}
})
}
})
}
})
DataLogUtils.uploadGameLog(context, gameEntity.id, gameEntity.name, entrance)
} else if (str.contains("")) {
if (gameEntity.pluggableCollection != null) {
DownloadDialog.showDownloadDialog(context, gameEntity, traceEvent, entrance, location)
} else {
CertificationDialog.showCertificationDialog(context, gameEntity, object : ConfirmListener {
override fun onConfirm() {
DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean ->
plugin(context, gameEntity, apk, entrance, location, isSubscribe, traceEvent)
}
}
})
}
} else if (str == context.getString(R.string.install) || str == context.getString(R.string.launch)) {
ToastUtils.toast("${gameEntity.name}已加入下载队列")
} else if (str == context.getString(R.string.update)) {
DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean ->
update(context, gameEntity, apk, entrance, location, isSubscribe, traceEvent)
}
}
}
}
private fun getApk(
gameEntity: GameEntity,
event: DefaultJsApi.GameActivityEvent,
isRemoveOther: Boolean
): ApkEntity? {
return when {
gameEntity.getApk().isEmpty() -> null
gameEntity.getApk().size == 1 -> gameEntity.getApk()[0]
// 找出对应平台版本Apk且移除掉其他平台版本Apk
isRemoveOther -> {
// 当前游戏为多版本时,只保留活动指定的版本即可,方便之后判断
var apk: ApkEntity? = null
val iterator = gameEntity.getApk().iterator()
while (iterator.hasNext()) {
val tempApk = iterator.next()
if (tempApk.getPlatform() == event.platform) {
apk = tempApk
} else {
iterator.remove()
}
}
apk
}
// 找出对应平台版本Apk即可
else -> {
var apk: ApkEntity? = null
run outside@{
gameEntity.getApk().forEach {
if (it.getPlatform() == event.platform) {
apk = it
return@outside
}
}
}
apk
}
}
}
private fun download(
context: Context,
gameEntity: GameEntity,
apk: ApkEntity,
isSubscribe: Boolean,
entrance: String,
location: String,
traceEvent: ExposureEvent
) {
val msg = FileUtils.isCanDownload(context, apk.size)
if (TextUtils.isEmpty(msg)) {
DownloadManager.createDownload(
context, apk, gameEntity, context.getString(
R.string.download
), entrance, location, isSubscribe, traceEvent
)
ToastUtils.toast("${gameEntity.name}已加入下载队列")
} else {
ToastUtils.toast(msg)
}
}
// 插件化
private fun plugin(
context: Context,
gameEntity: GameEntity,
apk: ApkEntity,
entrance: String,
location: String,
isSubscribe: Boolean,
traceEvent: ExposureEvent?
) {
val msg = FileUtils.isCanDownload(context, apk.size)
if (TextUtils.isEmpty(msg)) {
DownloadManager.createDownload(context, apk, gameEntity, "插件化", entrance, location, isSubscribe, traceEvent)
ToastUtils.toast("${gameEntity.name}已加入下载队列")
} else {
ToastUtils.toast(msg)
}
}
// 更新
private fun update(
context: Context,
gameEntity: GameEntity,
apk: ApkEntity,
entrance: String,
location: String,
isSubscribe: Boolean,
traceEvent: ExposureEvent?
) {
DownloadManager.createDownload(context, apk, gameEntity, "更新", entrance, location, isSubscribe, traceEvent)
ToastUtils.toast("${gameEntity.name}已加入下载队列")
}
@SuppressLint("CheckResult")
fun postTaskComplete(gameId: String) {
val api = RetrofitManager.getInstance().newApi
val single = if (UserManager.getInstance().isLoggedIn) {
api.postGameActivityTask(gameId)
} else {
api.postGameActivityTaskForNoLogin(gameId)
}
single.compose(singleToMain()).subscribe(EmptyResponse())
}
// 判断是否完成任务(预约完成或者已安装且无更新)
@SuppressLint("CheckResult")
fun checkTaskComplete(
context: Context,
event: DefaultJsApi.GameActivityEvent,
handler: CompletionHandler<Any>
) {
// 预约完成
if (ReservationRepository.thisGameHasBeenReserved(event.gameId)) {
postTaskComplete(event.gameId)
handler.complete(true)
return
}
if (mGameEntity != null && mGameEntity?.id == event.gameId) {
handleCheckTaskComplete(context, mGameEntity, event, handler)
} else {
RetrofitManager.getInstance()
.api
.getGameDigest(event.gameId)
.map(ApkActiveUtils.filterMapper)
.compose(observableToMain())
.subscribe(object : Response<GameEntity>() {
override fun onResponse(gameEntity: GameEntity?) {
mGameEntity = gameEntity
handleCheckTaskComplete(context, gameEntity, event, handler)
}
override fun onApiFailure(e: ApiResponse<GameEntity>?) {
super.onApiFailure(e)
handler.complete(false)
}
})
}
}
private fun handleCheckTaskComplete(
context: Context,
gameEntity: GameEntity?,
event: DefaultJsApi.GameActivityEvent,
handler: CompletionHandler<Any>
) {
if (gameEntity == null) {
handler.complete(false)
} else {
val apk = getApk(gameEntity, event, false)
if (apk == null) {
handler.complete(false)
} else {
// 已安装
if (PackageUtils.isInstalled(context, apk.packageName)) {
// 是否可更新
if (PackageUtils.isCanUpdate(apk, event.gameId)
|| PackageUtils.isNonPluginUpdatable(apk, gameEntity)
) {
handler.complete(false)
} else {
// 已安装且无更新
postTaskComplete(event.gameId)
handler.complete(true)
}
} else {
handler.complete(false)
}
}
}
}
fun postExposureEvent(event: DefaultJsApi.GameActivityEvent) {
RetrofitManager.getInstance()
.api
.getGameDigest(event.gameId)
.map(ApkActiveUtils.filterMapper)
.compose(observableToMain())
.subscribe(object : Response<GameEntity>() {
override fun onResponse(gameEntity: GameEntity?) {
mGameEntity = gameEntity
gameEntity?.let {
val exposureSources = arrayListOf(
ExposureSource("游戏活动", "${event.activityTitle}+${event.activityId}")
)
mTraceEvent = ExposureEvent.createEvent(
gameEntity,
exposureSources,
null,
ExposureType.EXPOSURE
)
mTraceEvent?.run { ExposureManager.log(this) }
}
}
})
}
fun clear() {
mTraceEvent = null
mGameEntity = null
}
}