Compare commits
35 Commits
feature-GH
...
v5.28.2-91
| Author | SHA1 | Date | |
|---|---|---|---|
| 42d5d46e53 | |||
| cdccc35703 | |||
| d3e2fea019 | |||
| f343841233 | |||
| f62083eff2 | |||
| 8594e998c2 | |||
| 6865706b0f | |||
| b6d8ca4d84 | |||
| 455e1f0432 | |||
| 15276cc4b3 | |||
| 130a7cdf2a | |||
| 164ec0c368 | |||
| 991bd22511 | |||
| df1ab5221d | |||
| 226d6c4f2c | |||
| 896adc9d36 | |||
| 0e33abebdd | |||
| c8ed126605 | |||
| b510a329b6 | |||
| 2de1ba4e1d | |||
| e4a0f0e68b | |||
| c064f9d3a6 | |||
| 759401d9ae | |||
| e56209d15e | |||
| c466ff1f21 | |||
| e09cf299f0 | |||
| 25352ba609 | |||
| 3cd065cb6e | |||
| 919a98ffe6 | |||
| eff84218a8 | |||
| 7c9c363422 | |||
| 8b1a38214c | |||
| 2acde0af00 | |||
| 201c1207f9 | |||
| 75d86b5a91 |
@ -3,10 +3,13 @@ package com.gh.gamecenter.provider
|
||||
import android.app.Activity
|
||||
import android.app.Application
|
||||
import android.text.TextUtils
|
||||
import com.gh.gamecenter.BuildConfig
|
||||
import com.gh.gamecenter.KuaishouHelper
|
||||
import com.gh.gamecenter.core.AppExecutor
|
||||
import com.gh.gamecenter.core.provider.IFlavorProvider
|
||||
import com.gh.gamecenter.core.utils.SPUtils
|
||||
import com.gh.gamecenter.core.utils.TimeUtils
|
||||
import com.gh.gamecenter.core.utils.ToastUtils
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.kwai.monitor.payload.TurboHelper
|
||||
|
||||
@ -44,6 +47,11 @@ class FlavorProviderImp : IFlavorProvider {
|
||||
|
||||
override fun logCoreEvent() {
|
||||
logEvent("EVENT_KEY_PATH_OPTIMIZATION")
|
||||
if (BuildConfig.ACTIVATE_REPORTING_RATIO == 1) {
|
||||
AppExecutor.uiExecutor.executeWithDelay({
|
||||
ToastUtils.toast("关键行为 EVENT_KEY_PATH_OPTIMIZATION")
|
||||
}, 500)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@ -830,8 +830,9 @@
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<receiver
|
||||
<activity
|
||||
android:name="com.gh.common.xapk.XapkInstallReceiver"
|
||||
android:theme="@style/Theme.Transparent"
|
||||
android:exported="false" />
|
||||
|
||||
<receiver
|
||||
|
||||
@ -1,23 +0,0 @@
|
||||
package com.gh.common.chain
|
||||
|
||||
import android.content.Context
|
||||
import com.gh.download.server.BrowserInstallHelper
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.core.utils.ToastUtils
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
|
||||
class AutoSwitchAssistantInstallHandler : ChainHandler() {
|
||||
|
||||
override fun handleRequest(context: Context, gameEntity: GameEntity) {
|
||||
if (BrowserInstallHelper.isUseBrowserToInstallEnabled()
|
||||
&& BrowserInstallHelper.shouldUseBrowserToInstall()
|
||||
&& gameEntity.isSplitXApk()) {
|
||||
ToastUtils.toast(context.getString(R.string.unsupported_browser_install_hint))
|
||||
}
|
||||
if (hasNext()) {
|
||||
getNext()?.handleRequest(context, gameEntity)
|
||||
} else {
|
||||
processEndCallback?.invoke(null)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
package com.gh.common.databind;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Typeface;
|
||||
@ -19,7 +20,6 @@ import androidx.core.content.ContextCompat;
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||
|
||||
import com.facebook.drawee.view.SimpleDraweeView;
|
||||
import com.gh.common.chain.AutoSwitchAssistantInstallHandler;
|
||||
import com.gh.common.chain.BrowserInstallHandler;
|
||||
import com.gh.common.chain.CertificationHandler;
|
||||
import com.gh.common.chain.ChainBuilder;
|
||||
@ -52,6 +52,7 @@ import com.gh.common.util.PackageUtils;
|
||||
import com.gh.common.util.ReservationHelper;
|
||||
import com.gh.download.DownloadManager;
|
||||
import com.gh.download.dialog.DownloadDialog;
|
||||
import com.gh.download.server.BrowserInstallHelper;
|
||||
import com.gh.gamecenter.DownloadManagerActivity;
|
||||
import com.gh.gamecenter.R;
|
||||
import com.gh.gamecenter.WebActivity;
|
||||
@ -66,6 +67,7 @@ import com.gh.gamecenter.common.view.DrawableView;
|
||||
import com.gh.gamecenter.core.utils.DisplayUtils;
|
||||
import com.gh.gamecenter.core.utils.MtaHelper;
|
||||
import com.gh.gamecenter.core.utils.NumberUtils;
|
||||
import com.gh.gamecenter.core.utils.ToastUtils;
|
||||
import com.gh.gamecenter.databinding.KaifuDetailItemRowBinding;
|
||||
import com.gh.gamecenter.feature.entity.ApkEntity;
|
||||
import com.gh.gamecenter.feature.entity.CommunityVideoEntity;
|
||||
@ -414,7 +416,7 @@ public class BindingAdapters {
|
||||
builder.addHandler(new CheckDownloadHandler());
|
||||
|
||||
builder.setProcessEndCallback(o -> {
|
||||
download(progressBar, gameEntity, traceEvent, (boolean) o, entrance, location);
|
||||
download(v.getContext(), progressBar, gameEntity, traceEvent, (boolean) o, entrance, location);
|
||||
return null;
|
||||
});
|
||||
final ChainHandler chainHandler = builder.buildHandlerChain();
|
||||
@ -452,7 +454,7 @@ public class BindingAdapters {
|
||||
if (downloadEntity != null) {
|
||||
File file = new File(downloadEntity.getPath());
|
||||
if (!file.exists()) {
|
||||
download(progressBar, gameEntity, traceEvent, false, entrance, location);
|
||||
download(v.getContext(), progressBar, gameEntity, traceEvent, false, entrance, location);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -678,12 +680,16 @@ public class BindingAdapters {
|
||||
|
||||
|
||||
// 开始下载
|
||||
private static void download(DownloadButton progressBar,
|
||||
private static void download(Context context,
|
||||
DownloadButton progressBar,
|
||||
GameEntity gameEntity,
|
||||
ExposureEvent traceEvent,
|
||||
boolean isSubscribe,
|
||||
String entrance,
|
||||
String location) {
|
||||
if (BrowserInstallHelper.shouldAutoSwitchAssistantInstall(gameEntity)) {
|
||||
ToastUtils.toast(context.getString(R.string.unsupported_browser_install_hint));
|
||||
}
|
||||
String str = progressBar.getText().toString();
|
||||
String method;
|
||||
if (str.contains("更新")) {
|
||||
|
||||
@ -31,6 +31,7 @@ import com.gh.gamecenter.common.constant.Constants
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.gamecenter.common.entity.LinkEntity
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.core.AppExecutor
|
||||
import com.gh.gamecenter.core.utils.*
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.entity.PluginLocation
|
||||
@ -1014,10 +1015,13 @@ object DownloadItemUtils {
|
||||
isSubscribe,
|
||||
traceEvent
|
||||
)
|
||||
ToastUtils.toast(gameEntity.name + "已加入下载队列")
|
||||
if (BrowserInstallHelper.shouldAutoSwitchAssistantInstall(gameEntity)) {
|
||||
ToastUtils.toast(context.getString(R.string.unsupported_browser_install_hint))
|
||||
val toast = context.getString(R.string.unsupported_browser_install_hint)
|
||||
AppExecutor.uiExecutor.executeWithDelay({
|
||||
ToastUtils.toast(toast)
|
||||
}, 1000)
|
||||
}
|
||||
Utils.toast(context, gameEntity.name + "已加入下载队列")
|
||||
if (downloadBtn is DownloadButton) {
|
||||
downloadBtn.text = "0%"
|
||||
downloadBtn.buttonStyle = DownloadButton.ButtonStyle.DOWNLOADING_NORMAL
|
||||
@ -1041,10 +1045,13 @@ object DownloadItemUtils {
|
||||
val msg = FileUtils.isCanDownload(context, gameEntity.getApk()[0].size ?: "")
|
||||
if (TextUtils.isEmpty(msg)) {
|
||||
DownloadManager.createDownload(context, gameEntity, "插件化", entrance, location, isSubscribe, traceEvent)
|
||||
ToastUtils.toast(gameEntity.name + "已加入下载队列")
|
||||
if (BrowserInstallHelper.shouldAutoSwitchAssistantInstall(gameEntity)) {
|
||||
ToastUtils.toast(context.getString(R.string.unsupported_browser_install_hint))
|
||||
val toast = context.getString(R.string.unsupported_browser_install_hint)
|
||||
AppExecutor.uiExecutor.executeWithDelay({
|
||||
ToastUtils.toast(toast)
|
||||
}, 1000)
|
||||
}
|
||||
Utils.toast(context, gameEntity.name + "已加入下载队列")
|
||||
if (downloadBtn is DownloadButton) {
|
||||
downloadBtn.setText(R.string.downloading)
|
||||
downloadBtn.buttonStyle = DownloadButton.ButtonStyle.DOWNLOADING_PLUGIN
|
||||
|
||||
@ -27,6 +27,7 @@ import com.gh.gamecenter.common.utils.DialogHelper
|
||||
import com.gh.gamecenter.common.utils.observableToMain
|
||||
import com.gh.gamecenter.common.utils.singleToMain
|
||||
import com.gh.gamecenter.common.view.dsbridge.CompletionHandler
|
||||
import com.gh.gamecenter.core.AppExecutor
|
||||
import com.gh.gamecenter.core.runOnUiThread
|
||||
import com.gh.gamecenter.core.utils.EmptyCallback
|
||||
import com.gh.gamecenter.core.utils.MtaHelper
|
||||
@ -183,10 +184,13 @@ object GameActivityDownloadHelper {
|
||||
str != context.getString(R.string.install) &&
|
||||
str != context.getString(R.string.launch)
|
||||
) {
|
||||
if (BrowserInstallHelper.shouldAutoSwitchAssistantInstall(gameEntity)) {
|
||||
ToastUtils.toast(context.getString(R.string.unsupported_browser_install_hint))
|
||||
}
|
||||
ToastUtils.toast("${gameEntity.name}已加入下载队列")
|
||||
if (BrowserInstallHelper.shouldAutoSwitchAssistantInstall(gameEntity)) {
|
||||
val toast = context.getString(R.string.unsupported_browser_install_hint)
|
||||
AppExecutor.uiExecutor.executeWithDelay({
|
||||
ToastUtils.toast(toast)
|
||||
}, 1000)
|
||||
}
|
||||
} else {
|
||||
when {
|
||||
str == context.getString(R.string.download) || str == context.getString(R.string.attempt) -> {
|
||||
@ -208,10 +212,13 @@ object GameActivityDownloadHelper {
|
||||
handleUpdateStatus(context, gameEntity, apk, entrance, location, traceEvent)
|
||||
}
|
||||
else -> {
|
||||
if (BrowserInstallHelper.shouldAutoSwitchAssistantInstall(gameEntity)) {
|
||||
ToastUtils.toast(context.getString(R.string.unsupported_browser_install_hint))
|
||||
}
|
||||
ToastUtils.toast("${gameEntity.name}已加入下载队列")
|
||||
if (BrowserInstallHelper.shouldAutoSwitchAssistantInstall(gameEntity)) {
|
||||
val toast = context.getString(R.string.unsupported_browser_install_hint)
|
||||
AppExecutor.uiExecutor.executeWithDelay({
|
||||
ToastUtils.toast(toast)
|
||||
}, 1000)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -430,10 +437,13 @@ object GameActivityDownloadHelper {
|
||||
R.string.download
|
||||
), entrance, location, isSubscribe, traceEvent
|
||||
)
|
||||
if (BrowserInstallHelper.shouldAutoSwitchAssistantInstall(gameEntity)) {
|
||||
ToastUtils.toast(context.getString(R.string.unsupported_browser_install_hint))
|
||||
}
|
||||
ToastUtils.toast("${gameEntity.name}已加入下载队列")
|
||||
if (BrowserInstallHelper.shouldAutoSwitchAssistantInstall(gameEntity)) {
|
||||
val toast = context.getString(R.string.unsupported_browser_install_hint)
|
||||
AppExecutor.uiExecutor.executeWithDelay({
|
||||
ToastUtils.toast(toast)
|
||||
}, 1000)
|
||||
}
|
||||
} else {
|
||||
ToastUtils.toast(msg)
|
||||
}
|
||||
@ -452,10 +462,13 @@ object GameActivityDownloadHelper {
|
||||
val msg = FileUtils.isCanDownload(context, apk.size)
|
||||
if (TextUtils.isEmpty(msg)) {
|
||||
DownloadManager.createDownload(context, apk, gameEntity, "插件化", entrance, location, isSubscribe, traceEvent)
|
||||
if (BrowserInstallHelper.shouldAutoSwitchAssistantInstall(gameEntity)) {
|
||||
ToastUtils.toast(context.getString(R.string.unsupported_browser_install_hint))
|
||||
}
|
||||
ToastUtils.toast("${gameEntity.name}已加入下载队列")
|
||||
if (BrowserInstallHelper.shouldAutoSwitchAssistantInstall(gameEntity)) {
|
||||
val toast = context.getString(R.string.unsupported_browser_install_hint)
|
||||
AppExecutor.uiExecutor.executeWithDelay({
|
||||
ToastUtils.toast(toast)
|
||||
}, 1000)
|
||||
}
|
||||
} else {
|
||||
ToastUtils.toast(msg)
|
||||
}
|
||||
@ -495,10 +508,13 @@ object GameActivityDownloadHelper {
|
||||
traceEvent: ExposureEvent?
|
||||
) {
|
||||
DownloadManager.createDownload(context, apk, gameEntity, "更新", entrance, location, isSubscribe, traceEvent)
|
||||
if (BrowserInstallHelper.shouldAutoSwitchAssistantInstall(gameEntity)) {
|
||||
ToastUtils.toast(context.getString(R.string.unsupported_browser_install_hint))
|
||||
}
|
||||
ToastUtils.toast("${gameEntity.name}已加入下载队列")
|
||||
if (BrowserInstallHelper.shouldAutoSwitchAssistantInstall(gameEntity)) {
|
||||
val toast = context.getString(R.string.unsupported_browser_install_hint)
|
||||
AppExecutor.uiExecutor.executeWithDelay({
|
||||
ToastUtils.toast(toast)
|
||||
}, 1000)
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
|
||||
@ -4,9 +4,12 @@ import android.app.Activity
|
||||
import android.app.PendingIntent
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageInstaller.SessionCallback
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.FileProvider
|
||||
import com.gh.common.dialog.InstallPermissionDialogFragment
|
||||
@ -18,6 +21,7 @@ import com.gh.gamecenter.common.constant.Constants
|
||||
import com.gh.gamecenter.common.utils.DialogHelper
|
||||
import com.gh.gamecenter.common.utils.getExtension
|
||||
import com.gh.gamecenter.common.utils.getMetaExtra
|
||||
import com.gh.gamecenter.core.AppExecutor
|
||||
import com.gh.gamecenter.core.utils.CurrentActivityHolder
|
||||
import com.gh.gamecenter.core.utils.MD5Utils
|
||||
import com.gh.gamecenter.core.utils.ToastUtils
|
||||
@ -161,14 +165,13 @@ object PackageInstaller {
|
||||
}
|
||||
|
||||
val flags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
|
||||
PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_CANCEL_CURRENT
|
||||
} else {
|
||||
PendingIntent.FLAG_UPDATE_CURRENT
|
||||
PendingIntent.FLAG_CANCEL_CURRENT
|
||||
}
|
||||
val pendingIntent = PendingIntent.getBroadcast(context, 0, intent, flags)
|
||||
val pendingIntent = PendingIntent.getActivity(context, sessionId, intent, flags)
|
||||
// 提交数据流并执行安装
|
||||
session.commit(pendingIntent.intentSender)
|
||||
session.close()
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -1,30 +1,35 @@
|
||||
package com.gh.common.xapk
|
||||
|
||||
import android.content.BroadcastReceiver
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageInstaller
|
||||
import android.content.pm.PackageInstaller.SessionInfo
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import androidx.annotation.RequiresApi
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
class XapkInstallReceiver : BroadcastReceiver() {
|
||||
class XapkInstallReceiver : Activity() {
|
||||
|
||||
companion object {
|
||||
const val KEY_PACKAGE_PATH = "package_path"
|
||||
}
|
||||
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
overridePendingTransition(0, 0)
|
||||
handleIntent(this, intent)
|
||||
|
||||
}
|
||||
|
||||
private fun handleIntent(context: Context, intent: Intent) {
|
||||
when (intent.getIntExtra(PackageInstaller.EXTRA_STATUS, -999)) {
|
||||
PackageInstaller.STATUS_PENDING_USER_ACTION -> {
|
||||
val installIntent = intent.getParcelableExtra<Intent>(Intent.EXTRA_INTENT)
|
||||
if (installIntent != null) {
|
||||
val installPackagePath = intent.getStringExtra(KEY_PACKAGE_PATH)
|
||||
val installSessionId = intent.getIntExtra(PackageInstaller.EXTRA_SESSION_ID, -1)
|
||||
XapkInstaller.onPendingUserAction(installPackagePath!!, installSessionId)
|
||||
installIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
context.startActivity(installIntent)
|
||||
updatePendingSessionInfoStatus(intent, XapkPendingSessionInfo.STATUS_PENDING_USER_ACTION)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
PackageInstaller.STATUS_FAILURE,
|
||||
@ -34,11 +39,21 @@ class XapkInstallReceiver : BroadcastReceiver() {
|
||||
PackageInstaller.STATUS_FAILURE_INCOMPATIBLE,
|
||||
PackageInstaller.STATUS_FAILURE_INVALID,
|
||||
PackageInstaller.STATUS_FAILURE_STORAGE -> {
|
||||
val installPackagePath = intent.getStringExtra(KEY_PACKAGE_PATH)
|
||||
if (!installPackagePath.isNullOrEmpty()) {
|
||||
XapkInstaller.onInstallCanceled(installPackagePath)
|
||||
}
|
||||
updatePendingSessionInfoStatus(intent, XapkPendingSessionInfo.STATUS_INSTALL_CANCELED)
|
||||
finish()
|
||||
}
|
||||
else -> {
|
||||
updatePendingSessionInfoStatus(intent, XapkPendingSessionInfo.STATUS_INSTALL_SUCCESS)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updatePendingSessionInfoStatus(intent: Intent, status: Int) {
|
||||
val installPackagePath = intent.getStringExtra(KEY_PACKAGE_PATH)
|
||||
if (!installPackagePath.isNullOrEmpty()) {
|
||||
val pendingSessionInfo = XapkInstaller.getPendingSessionInfo(installPackagePath)
|
||||
pendingSessionInfo?.updateStatus(status)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -9,6 +9,7 @@ import com.gh.download.DownloadManager
|
||||
import com.gh.gamecenter.common.utils.debugOnly
|
||||
import com.gh.gamecenter.common.utils.getExtension
|
||||
import com.gh.gamecenter.common.utils.throwExceptionInDebug
|
||||
import com.gh.gamecenter.core.AppExecutor
|
||||
import com.gh.gamecenter.core.utils.SentryHelper
|
||||
import com.gh.gamecenter.xapk.XApkUnZipper
|
||||
import com.gh.gamecenter.xapk.core.XApkFile
|
||||
@ -59,9 +60,7 @@ object XapkInstaller : XApkUnZipCallback, XApkUnZipOutputFactory {
|
||||
|
||||
private val mDownloadEntityMap = Collections.synchronizedMap(HashMap<String, DownloadEntity>())
|
||||
|
||||
private val mInstallingPath = Collections.synchronizedList(mutableListOf<String>())
|
||||
|
||||
private val mPendingSessionIdMap = Collections.synchronizedMap(HashMap<String, Int>())
|
||||
private val mPendingSessionInfoMap = HashMap<String, XapkPendingSessionInfo>()
|
||||
|
||||
// 按并行解压
|
||||
@JvmStatic
|
||||
@ -99,7 +98,11 @@ object XapkInstaller : XApkUnZipCallback, XApkUnZipOutputFactory {
|
||||
val downloadEntity = mDownloadEntityMap[apk.file.path] ?: return
|
||||
downloadEntity.meta[XAPK_UNZIP_PERCENT] = String.format("%.2f", progress * 100)
|
||||
downloadEntity.meta[XAPK_UNZIP_STATUS] = XapkUnzipStatus.UNZIPPING.name
|
||||
NDataChanger.notifyDataChanged(downloadEntity)
|
||||
|
||||
AppExecutor.ioExecutor.execute {
|
||||
NDataChanger.notifyDataChanged(downloadEntity)
|
||||
}
|
||||
|
||||
debugOnly {
|
||||
Utils.log("unzip", "onProgress->$progress")
|
||||
}
|
||||
@ -110,43 +113,40 @@ object XapkInstaller : XApkUnZipCallback, XApkUnZipOutputFactory {
|
||||
|
||||
downloadEntity.meta[XAPK_UNZIP_PERCENT] = "100.0"
|
||||
downloadEntity.meta[XAPK_UNZIP_STATUS] = XapkUnzipStatus.SUCCESS.name
|
||||
NDataChanger.notifyDataChanged(downloadEntity)
|
||||
DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
|
||||
|
||||
DownloadDataHelper.uploadDownloadStatusEvent(downloadEntity, "xapk解压成功")
|
||||
AppExecutor.ioExecutor.execute {
|
||||
NDataChanger.notifyDataChanged(downloadEntity)
|
||||
DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
|
||||
DownloadDataHelper.uploadDownloadStatusEvent(downloadEntity, "xapk解压成功")
|
||||
}
|
||||
|
||||
debugOnly {
|
||||
Utils.log("unzip", "onSuccess->${downloadEntity.path}")
|
||||
}
|
||||
|
||||
if (!mInstallingPath.contains(downloadEntity.path)) {
|
||||
mInstallingPath.add(downloadEntity.path)
|
||||
}
|
||||
|
||||
NDataChanger.notifyDataChanged(downloadEntity)
|
||||
|
||||
XapkInstallerLooper.add(downloadEntity.path, installer)
|
||||
XapkInstallerLooper.install(mContext)
|
||||
installer.install(mContext)
|
||||
}
|
||||
|
||||
override fun onError(apk: XApkFile, exception: Throwable) {
|
||||
val downloadEntity = mDownloadEntityMap[apk.file.path] ?: return
|
||||
downloadEntity.meta[XAPK_UNZIP_STATUS] = XapkUnzipStatus.FAILURE.name
|
||||
DownloadNotificationHelper.addOrUpdateDownloadNotification(downloadEntity)
|
||||
NDataChanger.notifyDataChanged(downloadEntity)
|
||||
DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
|
||||
|
||||
// 仅官网渠道上报 XAPK 异常信息
|
||||
if (HaloApp.getInstance().channel == "GH_206") {
|
||||
SentryHelper.onEvent(
|
||||
"XAPK_UNZIP_ERROR",
|
||||
"gameName", downloadEntity.name,
|
||||
"errorDigest", exception.localizedMessage
|
||||
)
|
||||
AppExecutor.ioExecutor.execute {
|
||||
DownloadNotificationHelper.addOrUpdateDownloadNotification(downloadEntity)
|
||||
NDataChanger.notifyDataChanged(downloadEntity)
|
||||
DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
|
||||
// 仅官网渠道上报 XAPK 异常信息
|
||||
if (HaloApp.getInstance().channel == "GH_206") {
|
||||
SentryHelper.onEvent(
|
||||
"XAPK_UNZIP_ERROR",
|
||||
"gameName", downloadEntity.name,
|
||||
"errorDigest", exception.localizedMessage
|
||||
)
|
||||
}
|
||||
|
||||
DownloadDataHelper.uploadDownloadStatusEvent(downloadEntity, "xapk解压失败")
|
||||
}
|
||||
|
||||
DownloadDataHelper.uploadDownloadStatusEvent(downloadEntity, "xapk解压失败")
|
||||
|
||||
debugOnly {
|
||||
Utils.log("unzip", "onFailure->$exception")
|
||||
}
|
||||
@ -156,8 +156,10 @@ object XapkInstaller : XApkUnZipCallback, XApkUnZipOutputFactory {
|
||||
val downloadEntity = mDownloadEntityMap.remove(apk.file.path) ?: return
|
||||
downloadEntity.meta[XAPK_UNZIP_PERCENT] = "0.0"
|
||||
downloadEntity.meta[XAPK_UNZIP_STATUS] = XapkUnzipStatus.CANCEL.name
|
||||
NDataChanger.notifyDataChanged(downloadEntity)
|
||||
DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
|
||||
AppExecutor.ioExecutor.execute {
|
||||
NDataChanger.notifyDataChanged(downloadEntity)
|
||||
DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onNext(apk: XApkFile, fileName: String) {
|
||||
@ -166,11 +168,9 @@ object XapkInstaller : XApkUnZipCallback, XApkUnZipOutputFactory {
|
||||
}
|
||||
}
|
||||
|
||||
fun isInstalling(packagePath: String): Boolean = mInstallingPath.contains(packagePath)
|
||||
fun getPendingSessionInfo(packagePath: String): XapkPendingSessionInfo? = mPendingSessionInfoMap[packagePath]
|
||||
|
||||
fun onPendingUserAction(packagePath: String, sessionId: Int) {
|
||||
mPendingSessionIdMap[packagePath] = sessionId
|
||||
}
|
||||
fun isInstalling(packagePath: String): Boolean = mPendingSessionInfoMap.containsKey(packagePath)
|
||||
|
||||
/**
|
||||
* 通知XAPK安装完成
|
||||
@ -178,41 +178,32 @@ object XapkInstaller : XApkUnZipCallback, XApkUnZipOutputFactory {
|
||||
fun onInstalled(packagePath: String) {
|
||||
val downloadEntity = mDownloadEntityMap.remove(packagePath) ?: return
|
||||
|
||||
mPendingSessionIdMap.remove(packagePath)
|
||||
mInstallingPath.remove(packagePath)
|
||||
mPendingSessionInfoMap.remove(packagePath)
|
||||
|
||||
downloadEntity.meta[XAPK_UNZIP_PERCENT] = "100.0"
|
||||
downloadEntity.meta[XAPK_UNZIP_STATUS] = XapkUnzipStatus.INSTALLED.name
|
||||
|
||||
NDataChanger.notifyDataChanged(downloadEntity)
|
||||
|
||||
DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
|
||||
|
||||
DownloadDataHelper.uploadDownloadStatusEvent(downloadEntity, "xapk安装成功")
|
||||
|
||||
XapkInstallerLooper.remove(downloadEntity.path)
|
||||
XapkInstallerLooper.install(mContext)
|
||||
AppExecutor.ioExecutor.execute {
|
||||
NDataChanger.notifyDataChanged(downloadEntity)
|
||||
DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
|
||||
DownloadDataHelper.uploadDownloadStatusEvent(downloadEntity, "xapk安装成功")
|
||||
}
|
||||
}
|
||||
|
||||
fun onInstallCanceled(packagePath: String) {
|
||||
|
||||
val downloadEntity = mDownloadEntityMap.remove(packagePath) ?: return
|
||||
|
||||
mPendingSessionIdMap.remove(packagePath)
|
||||
|
||||
mInstallingPath.remove(packagePath)
|
||||
mPendingSessionInfoMap.remove(packagePath)
|
||||
|
||||
downloadEntity.meta[XAPK_UNZIP_PERCENT] = "0.0"
|
||||
downloadEntity.meta[XAPK_UNZIP_STATUS] = XapkUnzipStatus.CANCEL.name
|
||||
|
||||
NDataChanger.notifyDataChanged(downloadEntity)
|
||||
|
||||
DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
|
||||
|
||||
DownloadDataHelper.uploadDownloadStatusEvent(downloadEntity, "xapk安装取消")
|
||||
|
||||
XapkInstallerLooper.remove(downloadEntity.path)
|
||||
XapkInstallerLooper.install(mContext)
|
||||
AppExecutor.ioExecutor.execute {
|
||||
NDataChanger.notifyDataChanged(downloadEntity)
|
||||
DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
|
||||
DownloadDataHelper.uploadDownloadStatusEvent(downloadEntity, "xapk安装取消")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -220,29 +211,46 @@ object XapkInstaller : XApkUnZipCallback, XApkUnZipOutputFactory {
|
||||
* 1. 用户触碰安装弹窗(原生Android系统)区域外导致安装取消
|
||||
*/
|
||||
fun updateCurrentInstallStatus() {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP || mPendingSessionIdMap.isEmpty()) {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP || mPendingSessionInfoMap.isEmpty()) {
|
||||
return
|
||||
}
|
||||
|
||||
val installer = mContext.packageManager.packageInstaller
|
||||
val updateList = mutableListOf<XapkPendingSessionInfo>()
|
||||
|
||||
for (pendingSessionEntry in mPendingSessionIdMap) {
|
||||
val sessionInfo = installer.getSessionInfo(pendingSessionEntry.value)
|
||||
for (pendingSessionInfoEntry in mPendingSessionInfoMap) {
|
||||
|
||||
// 1. 用户点击了取消按钮时,sessionInfo为空
|
||||
// 2. 用户点击了确定按钮时,sessionInfo的progress大于0.8
|
||||
if (sessionInfo == null || sessionInfo.progress > 0.8F) {
|
||||
continue
|
||||
val pendingSessionInfo = pendingSessionInfoEntry.value
|
||||
|
||||
if (pendingSessionInfo.getStatus() == XapkPendingSessionInfo.STATUS_PENDING_USER_ACTION) {// 用户触摸安装弹窗外部区域取消安装后,更新安装状态
|
||||
val installer = mContext.packageManager.packageInstaller
|
||||
val sessionId = pendingSessionInfo.sessionId
|
||||
if (sessionId != -1) {
|
||||
val sessionInfo = installer.getSessionInfo(sessionId)
|
||||
// 表示用户点击了安装弹窗外部区域
|
||||
if (sessionInfo != null && sessionInfo.progress <= 0.8F) {
|
||||
AppExecutor.ioExecutor.execute {
|
||||
installer.abandonSession(sessionInfo.sessionId)
|
||||
}
|
||||
pendingSessionInfo.updateStatus(XapkPendingSessionInfo.STATUS_INSTALL_CANCELED)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
installer.abandonSession(sessionInfo.sessionId)
|
||||
val installStatus = pendingSessionInfo.getStatus()
|
||||
if (installStatus == XapkPendingSessionInfo.STATUS_INSTALL_CANCELED
|
||||
|| installStatus == XapkPendingSessionInfo.STATUS_INSTALL_SUCCESS
|
||||
) {
|
||||
updateList.add(pendingSessionInfo)
|
||||
}
|
||||
}
|
||||
|
||||
val downloadEntity = mDownloadEntityMap[pendingSessionEntry.key] ?: return
|
||||
|
||||
if (!PackageUtils.isInstalled(mContext, downloadEntity.packageName)) {
|
||||
onInstallCanceled(downloadEntity.path)
|
||||
} else {
|
||||
for (pendingSessionInfo in updateList) {
|
||||
val downloadEntity = mDownloadEntityMap[pendingSessionInfo.path] ?: continue
|
||||
val installStatus = pendingSessionInfo.getStatus()
|
||||
if (installStatus == XapkPendingSessionInfo.STATUS_INSTALL_SUCCESS) {
|
||||
onInstalled(downloadEntity.path)
|
||||
} else if (installStatus == XapkPendingSessionInfo.STATUS_INSTALL_CANCELED) {
|
||||
onInstallCanceled(downloadEntity.path)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -268,9 +276,15 @@ object XapkInstaller : XApkUnZipCallback, XApkUnZipOutputFactory {
|
||||
private val xApkFile: XApkFile,
|
||||
private val sessionId: Int,
|
||||
) : IPackageInstaller {
|
||||
|
||||
override fun install(context: Context) {
|
||||
val downloadEntity = mDownloadEntityMap[xApkFile.file.path] ?: return
|
||||
PackageInstaller.installMultiple(context, downloadEntity.path, sessionId)
|
||||
val applicationContext = context.applicationContext
|
||||
mPendingSessionInfoMap[downloadEntity.path] = XapkPendingSessionInfo(downloadEntity.path, sessionId)
|
||||
AppExecutor.ioExecutor.execute {// 有可能卡顿造成anr
|
||||
NDataChanger.notifyDataChanged(downloadEntity)
|
||||
PackageInstaller.installMultiple(applicationContext, downloadEntity.path, sessionId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -278,6 +292,7 @@ object XapkInstaller : XApkUnZipCallback, XApkUnZipOutputFactory {
|
||||
private val xApkFile: XApkFile,
|
||||
private val file: File
|
||||
) : IPackageInstaller {
|
||||
|
||||
override fun install(context: Context) {
|
||||
val downloadEntity = mDownloadEntityMap[xApkFile.file.path] ?: return
|
||||
PackageInstaller.install(
|
||||
@ -288,42 +303,6 @@ object XapkInstaller : XApkUnZipCallback, XApkUnZipOutputFactory {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* XAPK安装每次只能执行一个安装流程,因此添加一个安装队列
|
||||
*/
|
||||
private object XapkInstallerLooper {
|
||||
|
||||
private val packagePathList = mutableListOf<String>()
|
||||
|
||||
private val installerList = mutableListOf<IPackageInstaller>()
|
||||
|
||||
fun add(packagePath: String, installer: IPackageInstaller) {
|
||||
if (packagePathList.contains(packagePath)) {
|
||||
return
|
||||
}
|
||||
packagePathList.add(packagePath)
|
||||
installerList.add(installer)
|
||||
}
|
||||
|
||||
fun install(context: Context) {
|
||||
if (installerList.isEmpty()) {
|
||||
return
|
||||
}
|
||||
installerList.first().install(context)
|
||||
}
|
||||
|
||||
fun remove(packagePath: String) {
|
||||
if (!packagePathList.contains(packagePath)) {
|
||||
return
|
||||
}
|
||||
val index = packagePathList.indexOf(packagePath)
|
||||
if (index != -1) {
|
||||
packagePathList.removeAt(index)
|
||||
installerList.removeAt(index)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum class XapkUnzipStatus(status: String) {
|
||||
|
||||
@ -0,0 +1,21 @@
|
||||
package com.gh.common.xapk
|
||||
|
||||
class XapkPendingSessionInfo(
|
||||
val path: String,
|
||||
val sessionId: Int = -1
|
||||
) {
|
||||
companion object {
|
||||
const val STATUS_INIT = -1
|
||||
const val STATUS_PENDING_USER_ACTION = 0
|
||||
const val STATUS_INSTALL_SUCCESS = 1
|
||||
const val STATUS_INSTALL_CANCELED = 2
|
||||
}
|
||||
|
||||
private var status = STATUS_INIT
|
||||
|
||||
internal fun updateStatus(status: Int) {
|
||||
this.status = status
|
||||
}
|
||||
|
||||
fun getStatus(): Int = status
|
||||
}
|
||||
@ -111,8 +111,7 @@ object PackageObserver {
|
||||
runOnIoThread { FileUtils.deleteFile(mDownloadEntity.path) }
|
||||
}
|
||||
|
||||
if (mDownloadEntity.format == Constants.XAPK_FORMAT
|
||||
|| mDownloadEntity.format == Constants.XAPK_APKS_FORMAT) {
|
||||
if (mDownloadEntity.format == Constants.XAPK_FORMAT) {
|
||||
XapkInstaller.onInstalled(mDownloadEntity.path)
|
||||
}
|
||||
|
||||
|
||||
@ -198,7 +198,6 @@ public class MainActivity extends BaseActivity {
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
showAd = getIntent().getBooleanExtra(SHOW_AD, false) && savedInstanceState == null;
|
||||
|
||||
HaloApp.getInstance().initFresco();
|
||||
HaloApp.getInstance().isAlreadyUpAndRunning = true;
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
@ -297,19 +297,7 @@ class SplashScreenActivity : BaseActivity() {
|
||||
private fun doFlavorInit() {
|
||||
HaloApp.getInstance().flavorProvider.init(HaloApp.getInstance(), this, PkgHelper.getActivateRatio())
|
||||
|
||||
val whiteListChannel = arrayListOf(
|
||||
"GH_206",
|
||||
"KS-GHZS-KY1",
|
||||
"KS-GHZS-MC1",
|
||||
"GDT_GHZS_MC1",
|
||||
"T11-GH-APPDY-ZC01",
|
||||
"T7-GH-APPDY-KY03",
|
||||
"T8-GH-APPUX-KY04",
|
||||
"T1-GHZS-MC01",
|
||||
"T4-GHZS-MC03"
|
||||
)
|
||||
|
||||
if (whiteListChannel.contains(HaloApp.getInstance().channel) || PackageFlavorHelper.IS_TEST_FLAVOR) {
|
||||
if (HaloApp.getInstance().channel == "GH_206" || PackageFlavorHelper.IS_TEST_FLAVOR) {
|
||||
SensorsBridge.init(HaloApp.getInstance(), HaloApp.getInstance().channel)
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,10 +12,6 @@ import androidx.fragment.app.DialogFragment;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
|
||||
import com.airbnb.lottie.LottieAnimationView;
|
||||
import com.gh.common.chain.AutoSwitchAssistantInstallHandler;
|
||||
import com.gh.common.chain.UnsupportedFeatureHandler;
|
||||
import com.gh.common.util.PackageLauncher;
|
||||
import com.gh.gamecenter.common.base.GlobalActivityManager;
|
||||
import com.gh.common.chain.BrowserInstallHandler;
|
||||
import com.gh.common.chain.CertificationHandler;
|
||||
import com.gh.common.chain.ChainBuilder;
|
||||
@ -26,15 +22,13 @@ import com.gh.common.chain.DownloadDialogHelperHandler;
|
||||
import com.gh.common.chain.GamePermissionHandler;
|
||||
import com.gh.common.chain.OverseaDownloadHandler;
|
||||
import com.gh.common.chain.PackageCheckHandler;
|
||||
import com.gh.common.chain.UnsupportedFeatureHandler;
|
||||
import com.gh.common.chain.UpdateNewSimulatorHandler;
|
||||
import com.gh.common.chain.ValidateVSpaceHandler;
|
||||
import com.gh.common.chain.VersionNumberHandler;
|
||||
import com.gh.common.constant.Config;
|
||||
import com.gh.common.dialog.DeviceRemindDialog;
|
||||
import com.gh.common.dialog.GameOffServiceDialogFragment;
|
||||
import com.gh.gamecenter.common.utils.ExtensionsKt;
|
||||
import com.gh.gamecenter.common.utils.SensorsBridge;
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent;
|
||||
import com.gh.common.filter.RegionSetting;
|
||||
import com.gh.common.filter.RegionSettingHelper;
|
||||
import com.gh.common.history.HistoryHelper;
|
||||
@ -42,34 +36,38 @@ import com.gh.common.simulator.NewSimulatorGameManager;
|
||||
import com.gh.common.simulator.SimulatorDownloadManager;
|
||||
import com.gh.common.simulator.SimulatorGameManager;
|
||||
import com.gh.common.util.CheckLoginUtils;
|
||||
import com.gh.common.util.DirectUtils;
|
||||
import com.gh.common.xapk.XapkInstaller;
|
||||
import com.gh.common.xapk.XapkUnzipStatus;
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts;
|
||||
import com.gh.gamecenter.common.utils.DataLogUtils;
|
||||
import com.gh.common.util.DetailDownloadUtils;
|
||||
import com.gh.gamecenter.common.utils.DialogHelper;
|
||||
import com.gh.common.util.DialogUtils;
|
||||
import com.gh.gamecenter.core.utils.PageSwitchDataHelper;
|
||||
import com.gh.common.util.DirectUtils;
|
||||
import com.gh.common.util.LogUtils;
|
||||
import com.gh.common.util.PackageInstaller;
|
||||
import com.gh.common.util.PackageLauncher;
|
||||
import com.gh.common.util.PackageUtils;
|
||||
import com.gh.gamecenter.common.utils.PermissionHelper;
|
||||
import com.gh.common.util.ReservationHelper;
|
||||
import com.gh.gamecenter.feature.view.DownloadButton;
|
||||
import com.gh.common.xapk.XapkInstaller;
|
||||
import com.gh.common.xapk.XapkUnzipStatus;
|
||||
import com.gh.download.DownloadManager;
|
||||
import com.gh.download.dialog.DownloadDialog;
|
||||
import com.gh.gamecenter.DownloadManagerActivity;
|
||||
import com.gh.gamecenter.R;
|
||||
import com.gh.gamecenter.WebActivity;
|
||||
import com.gh.gamecenter.common.constant.Constants;
|
||||
import com.gh.gamecenter.core.utils.StringUtils;
|
||||
import com.gh.gamecenter.feature.entity.ApkEntity;
|
||||
import com.gh.gamecenter.feature.entity.GameEntity;
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts;
|
||||
import com.gh.gamecenter.common.entity.LinkEntity;
|
||||
import com.gh.gamecenter.common.eventbus.EBReuse;
|
||||
import com.gh.gamecenter.feature.entity.SimulatorEntity;
|
||||
import com.gh.gamecenter.common.utils.DataLogUtils;
|
||||
import com.gh.gamecenter.common.utils.DialogHelper;
|
||||
import com.gh.gamecenter.common.utils.ExtensionsKt;
|
||||
import com.gh.gamecenter.common.utils.PermissionHelper;
|
||||
import com.gh.gamecenter.common.utils.SensorsBridge;
|
||||
import com.gh.gamecenter.core.utils.PageSwitchDataHelper;
|
||||
import com.gh.gamecenter.core.utils.StringUtils;
|
||||
import com.gh.gamecenter.eventbus.EBScroll;
|
||||
import com.gh.gamecenter.feature.entity.ApkEntity;
|
||||
import com.gh.gamecenter.feature.entity.GameEntity;
|
||||
import com.gh.gamecenter.feature.entity.SimulatorEntity;
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent;
|
||||
import com.gh.gamecenter.feature.view.DownloadButton;
|
||||
import com.gh.gamecenter.gamedetail.GameDetailFragment;
|
||||
import com.gh.gamecenter.gamedetail.dialog.GamePermissionDialogFragment;
|
||||
import com.gh.gamecenter.teenagermode.TeenagerModeActivity;
|
||||
@ -227,7 +225,6 @@ public class DetailViewHolder {
|
||||
}
|
||||
case PLUGIN:
|
||||
ChainBuilder builder = new ChainBuilder();
|
||||
builder.addHandler(new AutoSwitchAssistantInstallHandler());
|
||||
builder.addHandler(new UnsupportedFeatureHandler());
|
||||
builder.addHandler(new UpdateNewSimulatorHandler());
|
||||
builder.addHandler(new GamePermissionHandler());
|
||||
|
||||
@ -137,8 +137,7 @@ public class GameDownloadFragment extends BaseFragment implements View.OnClickLi
|
||||
}
|
||||
}
|
||||
|
||||
adapter.getUrlMap().put(PackageUtils.getPackageNameByPath(HaloApp.getInstance().getApplication(),
|
||||
downloadEntity.getPath()), downloadEntity.getUrl());
|
||||
adapter.getUrlMap().put(downloadEntity.getPackageName(), downloadEntity.getUrl());
|
||||
|
||||
// 用户焦点在下载管理页面时有任务完成,直接把所有下载完成的任务标记为已读
|
||||
DownloadManager.getInstance().markDownloadedTaskAsRead();
|
||||
|
||||
@ -773,7 +773,18 @@ class HomeSearchToolWrapperFragment : SearchToolWrapperFragment() {
|
||||
}
|
||||
|
||||
// 这里的 selectedPosition 指的是应该被高亮显示的 position
|
||||
val selectedPosition = (position + positionOffset).roundToInt()
|
||||
val selectedPosition = try {
|
||||
(position + positionOffset).roundToInt()
|
||||
} catch (e: IllegalArgumentException) {
|
||||
// roundToInt() 方法有时候会报 Cannot round NaN value. 错误
|
||||
// https://sentry.shanqu.cc/organizations/lightgame/issues/301377/?project=22
|
||||
SentryHelper.onEvent(
|
||||
"HOME_NAN_POSITION",
|
||||
"value",
|
||||
"$position+$positionOffset=(${position + positionOffset})"
|
||||
)
|
||||
position
|
||||
}
|
||||
val positionOffsetOnRealSelectedPosition = if (positionOffset >= 0.5) {
|
||||
positionOffset - 1
|
||||
} else {
|
||||
@ -797,8 +808,8 @@ class HomeSearchToolWrapperFragment : SearchToolWrapperFragment() {
|
||||
// positionOffset 小于零,表示 indicator 当前位置处于选中的 tab 的左边
|
||||
val indicatorOnLeft = positionOffset < 0F
|
||||
|
||||
val selectedTabBinding = mTabBindingList[selectedPosition]
|
||||
val selectedTabImageStyle = mTabImageStyleList[selectedPosition]
|
||||
val selectedTabBinding = mTabBindingList.safelyGetInRelease(selectedPosition) ?: return
|
||||
val selectedTabImageStyle = mTabImageStyleList.safelyGetInRelease(selectedPosition) ?: return
|
||||
|
||||
// 前一个 tab、当前选中的 tab、后一个 tab 的显示比例
|
||||
val preScaleRatio = 1 + abs(positionOffset) / 4
|
||||
|
||||
@ -35,6 +35,7 @@ class GameCollectionHotListAdapter(
|
||||
private val mPath: String,
|
||||
private val mBasicExposureSource: List<ExposureSource>
|
||||
) : ListAdapter<GameCollectionListItemData>(context), IExposable {
|
||||
private val mCoverWidth = (DisplayUtils.getScreenWidth() - 40F.dip2px()) / 2
|
||||
override fun getItemViewType(position: Int): Int {
|
||||
return if (position == itemCount - 1) ItemViewType.ITEM_FOOTER else ItemViewType.ITEM_BODY
|
||||
}
|
||||
@ -94,7 +95,7 @@ class GameCollectionHotListAdapter(
|
||||
stampIv.setBackgroundResource(if (entity?.stamp == "official") R.drawable.label_game_collection_official else R.drawable.label_game_collection_special_choice)
|
||||
titleTv.text = entity?.title
|
||||
userTv.text = entity?.user?.name
|
||||
coverImage.setTag(ImageUtils.TAG_TARGET_WIDTH, DisplayUtils.getScreenWidth() - 40F.dip2px())
|
||||
coverImage.setTag(ImageUtils.TAG_TARGET_WIDTH, mCoverWidth)
|
||||
ImageUtils.display(coverImage, entity?.cover)
|
||||
ImageUtils.display(userIv, entity?.user?.icon)
|
||||
|
||||
|
||||
@ -55,6 +55,7 @@ class GameCollectionSquareAdapter(
|
||||
private val mRefreshCallback: () -> Unit
|
||||
) :
|
||||
ListAdapter<GameCollectionListItemData>(context), IExposable {
|
||||
private val mPosterWidth = DisplayUtils.getScreenWidth() - 32F.dip2px()
|
||||
|
||||
override fun setListData(updateData: MutableList<GameCollectionListItemData>?) {
|
||||
if (updateData == null) {
|
||||
@ -409,7 +410,7 @@ class GameCollectionSquareAdapter(
|
||||
}
|
||||
}
|
||||
|
||||
class GameCollectionSquareItemViewHolder(val binding: GameCollectionSquareItemBinding) :
|
||||
inner class GameCollectionSquareItemViewHolder(val binding: GameCollectionSquareItemBinding) :
|
||||
RecyclerView.ViewHolder(binding.root) {
|
||||
@SuppressLint("SetTextI18n")
|
||||
fun bindGameCollection(
|
||||
@ -421,6 +422,7 @@ class GameCollectionSquareAdapter(
|
||||
) {
|
||||
binding.run {
|
||||
val context = root.context
|
||||
poster.setTag(ImageUtils.TAG_TARGET_WIDTH, mPosterWidth)
|
||||
display(poster, gamesCollectionEntity.cover)
|
||||
display(userIv, gamesCollectionEntity.user?.icon)
|
||||
titleTv.text = gamesCollectionEntity.title
|
||||
|
||||
@ -30,6 +30,7 @@ class HomeGameCollectionAdapter(
|
||||
private val mBlockName: String = ""
|
||||
) :
|
||||
BaseRecyclerAdapter<HomeGameCollectionAdapter.HomeGameCollectionCardViewHolder>(context) {
|
||||
private val mPosterWidth = DisplayUtils.getScreenWidth() - 50F.dip2px()
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
|
||||
HomeGameCollectionCardViewHolder(HomeGameCollectionItemCell(mContext).apply { inflate() })
|
||||
@ -69,7 +70,8 @@ class HomeGameCollectionAdapter(
|
||||
}
|
||||
}
|
||||
|
||||
class HomeGameCollectionCardViewHolder(val cell: HomeGameCollectionItemCell) : BaseRecyclerViewHolder<Any>(cell) {
|
||||
inner class HomeGameCollectionCardViewHolder(val cell: HomeGameCollectionItemCell) :
|
||||
BaseRecyclerViewHolder<Any>(cell) {
|
||||
fun bindGameCollectionCard(
|
||||
binding: HomeGameCollectionCardItemBinding,
|
||||
itemData: GameCollectionListItemData,
|
||||
@ -81,9 +83,9 @@ class HomeGameCollectionAdapter(
|
||||
binding.run {
|
||||
val context = root.context
|
||||
val gamesCollectionEntity = itemData.gameCollectionItem
|
||||
root.layoutParams.width = DisplayUtils.getScreenWidth() - 50F.dip2px()
|
||||
root.layoutParams.width = mPosterWidth
|
||||
if (gamesCollectionEntity != null) {
|
||||
poster.setTag(ImageUtils.TAG_TARGET_WIDTH, DisplayUtils.getScreenWidth() - 50F.dip2px())
|
||||
poster.setTag(ImageUtils.TAG_TARGET_WIDTH, mPosterWidth)
|
||||
ImageUtils.display(poster, gamesCollectionEntity.cover)
|
||||
ImageUtils.display(userIv, gamesCollectionEntity.user?.icon)
|
||||
titleTv.text = gamesCollectionEntity.title
|
||||
|
||||
@ -23,6 +23,8 @@ import com.shuyu.gsyvideoplayer.builder.GSYVideoOptionBuilder
|
||||
|
||||
class GameBigImageViewHolder(val binding: ItemGameServerTestBigImageBinding) :
|
||||
BaseRecyclerViewHolder<Any>(binding.root) {
|
||||
private val mGameImageWidth = DisplayUtils.getScreenWidth() - 32F.dip2px()
|
||||
|
||||
fun bindAttachGame(
|
||||
holder: GameBigImageViewHolder,
|
||||
gameEntity: GameEntity,
|
||||
@ -32,7 +34,7 @@ class GameBigImageViewHolder(val binding: ItemGameServerTestBigImageBinding) :
|
||||
) {
|
||||
holder.bindGameInfo(gameEntity, adapter, exposureEvent, entrance)
|
||||
holder.binding.gameImage.goneIf(gameEntity.topVideo != null || gameEntity.homeSetting.image.isEmpty()) {
|
||||
binding.gameImage.setTag(ImageUtils.TAG_TARGET_WIDTH, DisplayUtils.getScreenWidth() - 32F.dip2px())
|
||||
binding.gameImage.setTag(ImageUtils.TAG_TARGET_WIDTH, mGameImageWidth)
|
||||
ImageUtils.display(binding.gameImage, gameEntity.homeSetting.image)
|
||||
val hierarchy = binding.gameImage.hierarchy
|
||||
try {
|
||||
|
||||
@ -102,6 +102,7 @@ class GameServerTestV2ListFragment :
|
||||
}
|
||||
|
||||
override fun initSkeletonScreen() {
|
||||
if (mBinding?.skeleton == null) return
|
||||
mSkeletonScreen = Skeleton.bind(mBinding?.skeleton)
|
||||
.shimmer(true)
|
||||
.angle(Constants.SHIMMER_ANGLE)
|
||||
|
||||
@ -150,7 +150,7 @@ object VArchiveHelper {
|
||||
if (isSuccess) {
|
||||
val vGameEntity = VHelper.getVGameSnapshot(packageName = packageName)
|
||||
runOnIoThread {
|
||||
val fileMd5 = MD5Utils.calculateMD5(mLatestArchiveFile)
|
||||
val fileMd5 = MD5Utils.calculateMD5(mLatestArchiveFile) ?: return@runOnIoThread
|
||||
val vArchiveEntity = VArchiveEntity(
|
||||
id = fileMd5,
|
||||
gameId = vGameEntity?.downloadEntity?.gameId ?: "",
|
||||
|
||||
@ -160,6 +160,9 @@ object VHelper {
|
||||
|
||||
if (it.type == EBPackage.TYPE_INSTALLED) {
|
||||
SensorsBridge.trackEvent("HaloFunInstallDone", "space_schema_type", if (isVSpace32) "32位" else "64位")
|
||||
if (isVSpace32) {
|
||||
SensorsBridge.trackEvent("HaloFunExpandInstallDone")
|
||||
}
|
||||
|
||||
if (skip64VSpaceInstalled) return@PackageChangeListener
|
||||
|
||||
@ -959,11 +962,21 @@ object VHelper {
|
||||
location: String? = null) {
|
||||
Utils.log(LOG_TAG, "检测是需要安装还是启动 ${downloadEntity.gameId}")
|
||||
|
||||
if (downloadEntity.name.isNullOrEmpty()) {
|
||||
SentryHelper.onEvent(
|
||||
"V_GAME_DOWNLOAD_ENTITY_NAME_EMPTY",
|
||||
"game_id",
|
||||
downloadEntity.gameId,
|
||||
"location",
|
||||
location
|
||||
)
|
||||
}
|
||||
|
||||
installOrLaunch(
|
||||
context,
|
||||
downloadEntity.packageName,
|
||||
downloadEntity.gameId,
|
||||
downloadEntity.name,
|
||||
downloadEntity.name ?: "",
|
||||
downloadEntity.getGameCategory(),
|
||||
downloadEntity.getMetaExtra(KEY_BIT),
|
||||
location
|
||||
@ -1343,7 +1356,6 @@ object VHelper {
|
||||
VSpace32DialogFragment.showDownloadDialog(
|
||||
context,
|
||||
getVSpaceDownloadEntity(false),
|
||||
autoDownload = true,
|
||||
gameId = gameId,
|
||||
gameName = gameName
|
||||
)
|
||||
|
||||
@ -46,6 +46,7 @@ class VSpace32DialogFragment : BaseDraggableDialogFragment() {
|
||||
private val mBinding by lazy { DialogVspace32Binding.inflate(layoutInflater) }
|
||||
private var mIsLogInstallShow = false
|
||||
private var mIsLogAutoInstallClick = false
|
||||
private var mIsClickDownloadThisTime = false // 是否本次弹出Dialog点击的下载按钮
|
||||
private val mDataWatcher = object : DataWatcher() {
|
||||
override fun onDataChanged(downloadEntity: DownloadEntity) {
|
||||
if (downloadEntity.url == mDownloadUrl && isAdded) {
|
||||
@ -146,6 +147,8 @@ class VSpace32DialogFragment : BaseDraggableDialogFragment() {
|
||||
downloadType
|
||||
).toJson()
|
||||
|
||||
mIsClickDownloadThisTime = true
|
||||
|
||||
AppExecutor.uiExecutor.executeWithDelay({
|
||||
DownloadManager.getInstance().cancel(mDownloadUrl)
|
||||
DownloadManager.getInstance().add(downloadEntity)
|
||||
@ -165,7 +168,7 @@ class VSpace32DialogFragment : BaseDraggableDialogFragment() {
|
||||
|
||||
// 上面监听安装包名变化的 LiveData 监听有可能被冲掉了
|
||||
// 手动再检查一下安装状态,避免出现已安装但是没有 dismiss 弹窗的问题
|
||||
if (PackageUtils.isInstalled(requireContext(), VHelper.VSPACE_32BIT_PACKAGENAME)) {
|
||||
if (PackageUtils.isInstalledFromAllPackage(requireContext(), VHelper.VSPACE_32BIT_PACKAGENAME)) {
|
||||
dismissAllowingStateLoss()
|
||||
}
|
||||
}
|
||||
@ -221,7 +224,7 @@ class VSpace32DialogFragment : BaseDraggableDialogFragment() {
|
||||
val isVSpace32DownloadOnly =
|
||||
downloadEntity.getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE) == Constants.VSPACE_32_DOWNLOAD_ONLY
|
||||
val isAutoInstall = SPUtils.getBoolean(Constants.SP_AUTO_INSTALL, true)
|
||||
if (!isVSpace32DownloadOnly && isAutoInstall && !mIsLogAutoInstallClick) {
|
||||
if (!isVSpace32DownloadOnly && isAutoInstall && !mIsLogAutoInstallClick && mIsClickDownloadThisTime) {
|
||||
NewFlatLogUtils.logHaloFunEvent("halo_fun_32_install_tip_dialog_click")
|
||||
SensorsBridge.trackEvent("HaloFunExpandInstallButtonClick")
|
||||
mIsLogAutoInstallClick = true
|
||||
@ -260,15 +263,11 @@ class VSpace32DialogFragment : BaseDraggableDialogFragment() {
|
||||
|
||||
companion object {
|
||||
const val KEY_APP_ENTITY_32 = "app_entity_32"
|
||||
const val KEY_AUTO_DOWNLOAD = "auto_download"
|
||||
const val KEY_IS_UPDATE = "is_update"
|
||||
|
||||
@JvmStatic
|
||||
fun showDownloadDialog(
|
||||
context: Context?,
|
||||
appEntity32: AppEntity,
|
||||
autoDownload: Boolean = false,
|
||||
isUpdate: Boolean = false,
|
||||
gameId: String = "",
|
||||
gameName: String = ""
|
||||
) {
|
||||
@ -291,8 +290,6 @@ class VSpace32DialogFragment : BaseDraggableDialogFragment() {
|
||||
putParcelable(KEY_APP_ENTITY_32, appEntity32)
|
||||
putString(EntranceConsts.KEY_GAME_ID, gameId)
|
||||
putString(EntranceConsts.KEY_GAME_NAME, gameName)
|
||||
putBoolean(KEY_AUTO_DOWNLOAD, autoDownload)
|
||||
putBoolean(KEY_IS_UPDATE, isUpdate)
|
||||
}
|
||||
}
|
||||
downloadDialog.show(
|
||||
@ -301,24 +298,6 @@ class VSpace32DialogFragment : BaseDraggableDialogFragment() {
|
||||
)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun showDownloadDialog(
|
||||
context: Context?,
|
||||
appEntity32: AppEntity,
|
||||
gameEntity: GameEntity?,
|
||||
autoDownload: Boolean = false,
|
||||
isUpdate: Boolean = false
|
||||
) {
|
||||
showDownloadDialog(
|
||||
context,
|
||||
appEntity32,
|
||||
autoDownload,
|
||||
isUpdate,
|
||||
gameEntity?.id ?: "",
|
||||
gameEntity?.name ?: ""
|
||||
)
|
||||
}
|
||||
|
||||
private fun hasDialogDisplayedInCurrentActivity(fragmentActivity: FragmentActivity): Boolean {
|
||||
val fragments: List<Fragment> = fragmentActivity.supportFragmentManager.fragments
|
||||
fragments.forEach { fragment ->
|
||||
|
||||
@ -39,6 +39,13 @@ import com.lightgame.download.DownloadStatus.*
|
||||
import com.lightgame.utils.AppManager
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* 1. 单独的 64 位组件的下载和更新使用本 VSpaceDialogFragment
|
||||
* 2. 已经安装了 64 位组件,后续操作所调起的 32 位组件的首次下载使用亦 VSpace32DialogFragment
|
||||
* 3. 64 位组件已安装且 64 位组件无需更新时,32 位组件需要更新时,使用本 VSpaceDialogFragment
|
||||
* 4. 64 位组件已安装且 64,32 位都需要更新时,64 位更新使用本 VSpaceDialogFragment
|
||||
* (同时下载64位组件和32位组件,但是32位在64位安装完成之前不触发安装), 32 位安装使用跳转 VSpaceUpdate32DialogFragment 进行
|
||||
*/
|
||||
class VSpaceDialogFragment : BaseDraggableDialogFragment() {
|
||||
|
||||
private var mAppEntity64: AppEntity? = null
|
||||
@ -52,6 +59,7 @@ class VSpaceDialogFragment : BaseDraggableDialogFragment() {
|
||||
private val mBinding by lazy { DialogVspaceBinding.inflate(layoutInflater) }
|
||||
private var mIsLogInstallShow = false
|
||||
private var mIsLogAutoInstallClick = false
|
||||
private var mIsClickDownloadThisTime = false // 是否本次弹出Dialog点击的下载按钮
|
||||
private val mDataWatcher = object : DataWatcher() {
|
||||
override fun onDataChanged(downloadEntity: DownloadEntity) {
|
||||
if (((mAppEntity64 != null && downloadEntity.url == mDownloadUrl64) || (mAppEntity64 == null && downloadEntity.url == mDownloadUrl32)) && isAdded) {
|
||||
@ -92,13 +100,8 @@ class VSpaceDialogFragment : BaseDraggableDialogFragment() {
|
||||
|
||||
val mViewModel = viewModelProvider<VSpaceDialogViewModel>()
|
||||
mViewModel.packageLiveData.observe(this) {
|
||||
if (it.packageName == VHelper.DEFAULT_VSPACE_PACKAGENAME) {
|
||||
if (mIsUpdate) showVSpace32UpdateDialogIfNeeded() else showVSpace32DownloadDialogIfNeeded()
|
||||
dismissAllowingStateLoss()
|
||||
}
|
||||
if (it.packageName == VHelper.VSPACE_32BIT_PACKAGENAME) {
|
||||
dismissAllowingStateLoss()
|
||||
}
|
||||
show32BitRelatedDialogIfNeeded()
|
||||
dismissDialogIfInstalled()
|
||||
}
|
||||
|
||||
mBinding.downloadBtn.text = "下载畅玩助手服务组件"
|
||||
@ -157,6 +160,7 @@ class VSpaceDialogFragment : BaseDraggableDialogFragment() {
|
||||
DataCollectionUtils.uploadDownload(HaloApp.getInstance(), downloadEntity32, "开始")
|
||||
}
|
||||
|
||||
mIsClickDownloadThisTime = true
|
||||
AppExecutor.uiExecutor.executeWithDelay({
|
||||
if (downloadEntity64 != null) {
|
||||
DownloadManager.getInstance().cancel(mDownloadUrl64)
|
||||
@ -204,13 +208,42 @@ class VSpaceDialogFragment : BaseDraggableDialogFragment() {
|
||||
super.onStart()
|
||||
DownloadManager.getInstance().addObserver(mDataWatcher)
|
||||
|
||||
// 上面监听安装包名变化的 LiveData 监听有可能被冲掉了
|
||||
// 手动再检查一下安装状态,避免出现已安装但是没有 dismiss 弹窗的问题
|
||||
if (PackageUtils.isInstalled(requireContext(), VHelper.DEFAULT_VSPACE_PACKAGENAME)) {
|
||||
if (mIsUpdate) showVSpace32UpdateDialogIfNeeded() else showVSpace32DownloadDialogIfNeeded()
|
||||
dismissAllowingStateLoss()
|
||||
show32BitRelatedDialogIfNeeded()
|
||||
|
||||
// 检查安装状态,避免出现已安装但是没有 dismiss 弹窗的问题
|
||||
dismissDialogIfInstalled()
|
||||
}
|
||||
|
||||
// 弹下载/更新 32 位组件,前提是 64 位组件已经安装并安装了指定的版本
|
||||
private fun show32BitRelatedDialogIfNeeded() {
|
||||
if (PackageUtils.isInstalledFromAllPackage(requireContext(), VHelper.DEFAULT_VSPACE_PACKAGENAME)
|
||||
&& mAppEntity64?.version == PackageUtils.getVersionNameByPackageName(VHelper.DEFAULT_VSPACE_PACKAGENAME)) {
|
||||
// 该游戏需要 32 位组件,且后台配置的 32 位组件不为空
|
||||
if (mBit == "32" && mAppEntity32 != null && !mAppEntity32?.url.isNullOrEmpty()) {
|
||||
if (mIsUpdate) {
|
||||
showVSpace32UpdateDialog()
|
||||
} else {
|
||||
showVSpace32DownloadDialogIfNeeded()
|
||||
}
|
||||
}
|
||||
}
|
||||
if (PackageUtils.isInstalled(requireContext(), VHelper.VSPACE_32BIT_PACKAGENAME)) {
|
||||
}
|
||||
|
||||
/**
|
||||
* dismiss 当前 VSpaceDialogFragment (如果满足入参条件的话)
|
||||
*/
|
||||
private fun dismissDialogIfInstalled() {
|
||||
// 需要下载的 64 位组件是否与已安装的 64 位组件版本一致
|
||||
val is64BitVersionMatched =
|
||||
mAppEntity64 == null
|
||||
|| mAppEntity64?.version == PackageUtils.getVersionNameByPackageName(VHelper.DEFAULT_VSPACE_PACKAGENAME)
|
||||
|
||||
// 需要下载的 32 位组件是否与已安装的 32 位组件版本一致
|
||||
val is32BitVersionMatched =
|
||||
(mAppEntity32 == null || mBit != "32")
|
||||
|| mAppEntity32?.version == PackageUtils.getVersionNameByPackageName(VHelper.VSPACE_32BIT_PACKAGENAME)
|
||||
|
||||
if (is64BitVersionMatched && is32BitVersionMatched) {
|
||||
dismissAllowingStateLoss()
|
||||
}
|
||||
}
|
||||
@ -218,7 +251,7 @@ class VSpaceDialogFragment : BaseDraggableDialogFragment() {
|
||||
private fun showVSpace32DownloadDialogIfNeeded() {
|
||||
val is32VSpaceInstalled =
|
||||
PackageUtils.isInstalledFromAllPackage(requireContext(), VHelper.VSPACE_32BIT_PACKAGENAME)
|
||||
if (!is32VSpaceInstalled && mBit == "32" && mAppEntity32 != null && !mAppEntity32?.url.isNullOrEmpty()) {
|
||||
if (!is32VSpaceInstalled) {
|
||||
VSpace32DialogFragment.showDownloadDialog(
|
||||
requireContext(),
|
||||
mAppEntity32!!,
|
||||
@ -228,15 +261,13 @@ class VSpaceDialogFragment : BaseDraggableDialogFragment() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun showVSpace32UpdateDialogIfNeeded() {
|
||||
if (mBit == "32" && mAppEntity32 != null && !mAppEntity32?.url.isNullOrEmpty()) {
|
||||
VSpaceUpdate32DialogFragment.showDownloadDialog(
|
||||
requireContext(),
|
||||
mAppEntity32!!,
|
||||
gameId = mGameId,
|
||||
gameName = mGameName
|
||||
)
|
||||
}
|
||||
private fun showVSpace32UpdateDialog() {
|
||||
VSpaceUpdate32DialogFragment.showDownloadDialog(
|
||||
requireContext(),
|
||||
mAppEntity32!!,
|
||||
gameId = mGameId,
|
||||
gameName = mGameName
|
||||
)
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
@ -277,6 +308,7 @@ class VSpaceDialogFragment : BaseDraggableDialogFragment() {
|
||||
DownloadManager.getInstance().resume(downloadEntity, false)
|
||||
}
|
||||
}
|
||||
|
||||
done -> {
|
||||
downloadBtn.setText(R.string.install)
|
||||
downloadBtn.buttonStyle = DownloadButton.ButtonStyle.INSTALL_NORMAL
|
||||
@ -288,7 +320,11 @@ class VSpaceDialogFragment : BaseDraggableDialogFragment() {
|
||||
mIsLogInstallShow = true
|
||||
}
|
||||
|
||||
if (SPUtils.getBoolean(Constants.SP_AUTO_INSTALL, true) && !mIsLogAutoInstallClick) {
|
||||
if (SPUtils.getBoolean(
|
||||
Constants.SP_AUTO_INSTALL,
|
||||
true
|
||||
) && !mIsLogAutoInstallClick && mIsClickDownloadThisTime
|
||||
) {
|
||||
SensorsBridge.trackEvent("HaloFunInstallButtonClick", "space_schema_type", vSpaceType)
|
||||
mIsLogAutoInstallClick = true
|
||||
}
|
||||
@ -316,6 +352,7 @@ class VSpaceDialogFragment : BaseDraggableDialogFragment() {
|
||||
DownloadManager.getInstance().resume(downloadEntity, true)
|
||||
}
|
||||
}
|
||||
|
||||
else -> {
|
||||
// do nothing
|
||||
}
|
||||
@ -370,7 +407,6 @@ class VSpaceDialogFragment : BaseDraggableDialogFragment() {
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
val downloadDialog = VSpaceDialogFragment().apply {
|
||||
arguments = Bundle().apply {
|
||||
if (appEntity64 != null) putParcelable(KEY_APP_ENTITY_64, appEntity64)
|
||||
@ -388,6 +424,14 @@ class VSpaceDialogFragment : BaseDraggableDialogFragment() {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示下载弹窗
|
||||
* @param appEntity64 需要下载的 64 位组件实体,不为空即代表需要下载
|
||||
* @param appEntity32 需要下载的 32 位组件实体,不为空即代表需要下载
|
||||
* @param gameEntity 游戏相关的实体
|
||||
* @param autoDownload 是否需要显示弹窗即进行下载
|
||||
* @param isUpdate 是否为更新
|
||||
*/
|
||||
@JvmStatic
|
||||
fun showDownloadDialog(
|
||||
context: Context?,
|
||||
|
||||
@ -141,7 +141,8 @@ class VSpaceUpdate32DialogFragment : BaseDialogFragment() {
|
||||
|
||||
// 上面监听安装包名变化的 LiveData 监听有可能被冲掉了
|
||||
// 手动再检查一下安装状态,避免出现已安装但是没有 dismiss 弹窗的问题
|
||||
if (PackageUtils.isInstalled(requireContext(), VHelper.VSPACE_32BIT_PACKAGENAME)) {
|
||||
if (PackageUtils.isInstalledFromAllPackage(requireContext(), VHelper.VSPACE_32BIT_PACKAGENAME)
|
||||
&& mAppEntity?.version == PackageUtils.getVersionNameByPackageName(VHelper.VSPACE_32BIT_PACKAGENAME)) {
|
||||
dismissAllowingStateLoss()
|
||||
}
|
||||
}
|
||||
|
||||
@ -227,12 +227,12 @@ public class HaloApp extends MultiDexApplication {
|
||||
PlayerFactory.setPlayManager(Exo2PlayerManager.class);
|
||||
CacheFactory.setCacheManager(ExoPlayerCacheManager.class);
|
||||
|
||||
initFresco();
|
||||
|
||||
AppExecutor.getIoExecutor().execute(() -> {
|
||||
initDataHelper();
|
||||
ExtensionsKt.doOnMainProcessOnly(this, () -> Tracker.init(this));
|
||||
|
||||
initFresco();
|
||||
|
||||
deviceRamSize = DeviceUtils.getTotalRamSizeOfDevice(this);
|
||||
mChannel = mFlavorProvider.getChannelStr(this);
|
||||
|
||||
|
||||
@ -7,9 +7,11 @@ import android.text.TextUtils
|
||||
import com.gh.gamecenter.BuildConfig
|
||||
import com.bytedance.hume.readapk.HumeSDK
|
||||
import com.gh.gamecenter.TeaHelper
|
||||
import com.gh.gamecenter.core.AppExecutor
|
||||
import com.gh.gamecenter.core.provider.IFlavorProvider
|
||||
import com.gh.gamecenter.core.utils.SPUtils
|
||||
import com.gh.gamecenter.core.utils.TimeUtils
|
||||
import com.gh.gamecenter.core.utils.ToastUtils
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.utils.Utils
|
||||
import java.io.File
|
||||
@ -58,6 +60,11 @@ class FlavorProviderImp : IFlavorProvider {
|
||||
|
||||
override fun logCoreEvent() {
|
||||
logEvent("game_addiction")
|
||||
if (BuildConfig.ACTIVATE_REPORTING_RATIO == 1) {
|
||||
AppExecutor.uiExecutor.executeWithDelay({
|
||||
ToastUtils.toast("关键行为 game_addiction")
|
||||
}, 500)
|
||||
}
|
||||
}
|
||||
|
||||
private fun amILucky(percentage: Int = 100): Boolean {
|
||||
|
||||
@ -7,8 +7,8 @@ ext {
|
||||
targetSdkVersion = 28
|
||||
|
||||
// application info (每个大版本之间的 versionCode 增加 20)
|
||||
versionCode = 910
|
||||
versionName = "5.28.0"
|
||||
versionCode = 912
|
||||
versionName = "5.28.2"
|
||||
applicationId = "com.gh.gamecenter"
|
||||
|
||||
// AndroidX
|
||||
|
||||
@ -2,6 +2,7 @@ package com.gh.gamecenter.xapk.io
|
||||
|
||||
import android.content.Context
|
||||
import android.content.pm.PackageInstaller
|
||||
import android.content.pm.PackageInstaller.Session
|
||||
import android.content.pm.PackageInstaller.SessionParams
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Build
|
||||
@ -35,9 +36,6 @@ class SplitApksOutput(
|
||||
.packageInstaller
|
||||
// 创建安装会话并获取返回会话ID
|
||||
val sessionId = installer.createSession(it)
|
||||
.also { sessionId ->
|
||||
SessionPool.put(installer, sessionId)
|
||||
}
|
||||
// 开启安装会话
|
||||
val session = installer.openSession(sessionId)
|
||||
try {
|
||||
@ -59,24 +57,4 @@ class SplitApksOutput(
|
||||
} else {
|
||||
throw ApkOutputUnsupportedSplitApksException()
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
private object SessionPool {
|
||||
private val sessionIdList = mutableListOf<Int>()
|
||||
|
||||
|
||||
fun put(installer: PackageInstaller, sessionId: Int) {
|
||||
sessionIdList.removeAll {
|
||||
installer.getSessionInfo(it) == null
|
||||
}
|
||||
|
||||
sessionIdList.add(sessionId)
|
||||
|
||||
installer.mySessions.forEach {
|
||||
if (!sessionIdList.contains(it.sessionId)) {
|
||||
installer.abandonSession(it.sessionId)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Submodule ndownload updated: 47c4714e2b...5fdce39eb9
@ -93,14 +93,14 @@ fi
|
||||
|
||||
# 是否选择了 sdk 类型
|
||||
if [ "${sdk_platform}" != "" ]; then
|
||||
if [ "${activate_reporting_ratio}" == "" ]; then
|
||||
activate_reporting_ratio="100"
|
||||
fi
|
||||
# 调整上报比例
|
||||
sed -i "s/int ACTIVATE_REPORTING_RATIO = 100/int ACTIVATE_REPORTING_RATIO = ${activate_reporting_ratio}/g" app/build.gradle
|
||||
|
||||
# 头条包
|
||||
if [ "${sdk_platform}" == "toutiao" ]; then
|
||||
if [ "${activate_reporting_ratio}" == "" ]; then
|
||||
activate_reporting_ratio="100"
|
||||
fi
|
||||
# 调整上报比例
|
||||
sed -i "s/int ACTIVATE_REPORTING_RATIO = 100/int ACTIVATE_REPORTING_RATIO = ${activate_reporting_ratio}/g" app/build.gradle
|
||||
|
||||
if [ "${sdk_version}" == "5.3.0" ]; then
|
||||
sed -i "s/bytedanceApplog = \"6.14.3\"/bytedanceApplog = \"${sdk_version}\"/g" dependencies.gradle
|
||||
rm app/src/tea/java/com/gh/gamecenter/TeaHelper.kt
|
||||
|
||||
Reference in New Issue
Block a user