diff --git a/app/src/main/java/com/gh/common/databind/BindingAdapters.java b/app/src/main/java/com/gh/common/databind/BindingAdapters.java index 5c5e7101a9..66bbd68eb7 100644 --- a/app/src/main/java/com/gh/common/databind/BindingAdapters.java +++ b/app/src/main/java/com/gh/common/databind/BindingAdapters.java @@ -451,8 +451,10 @@ public class BindingAdapters { case INSTALL_NORMAL: if (gameEntity.getApk().size() == 1) { DownloadEntity downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity); + String packageName = gameEntity.getApk().get(0).getPackageName(); + if (gameEntity.isVGame()) { - VHelper.installOrLaunch((AppCompatActivity) v.getContext(), gameEntity.getApk().get(0).getPackageName()); + VHelper.installOrLaunch((AppCompatActivity) v.getContext(), packageName); return; } diff --git a/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java b/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java index 4a314291a7..a4af35009e 100644 --- a/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java +++ b/app/src/main/java/com/gh/common/util/DetailDownloadUtils.java @@ -83,8 +83,16 @@ public class DetailDownloadUtils { } viewHolder.mDownloadPb.setText(downloadText); - String url = viewHolder.gameEntity.getApk().get(0).getUrl(); DownloadEntity downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(viewHolder.gameEntity); + + // 在下载管理找不到下载实体,到畅玩数据库里找 + if (downloadEntity == null) { + String packageName = viewHolder.gameEntity.getUniquePackageName(); + if (!TextUtils.isEmpty(packageName)) { + downloadEntity = VHelper.getDownloadEntitySnapshotByPackageName(packageName); + } + } + if (downloadEntity != null) { viewHolder.downloadEntity = downloadEntity; detailInvalidate(viewHolder); @@ -149,8 +157,16 @@ public class DetailDownloadUtils { } if (isCheck && viewHolder.gameEntity.getApk().size() == 1) { - String url = viewHolder.gameEntity.getApk().get(0).getUrl(); DownloadEntity downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(viewHolder.gameEntity); + + // 在下载管理找不到下载实体,到畅玩数据库里找 + if (downloadEntity == null) { + String packageName = viewHolder.gameEntity.getUniquePackageName(); + if (!TextUtils.isEmpty(packageName)) { + downloadEntity = VHelper.getDownloadEntitySnapshotByPackageName(packageName); + } + } + if (downloadEntity != null) { viewHolder.downloadEntity = downloadEntity; detailInvalidate(viewHolder); diff --git a/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt b/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt index 66d503bd67..97d4419c04 100644 --- a/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt +++ b/app/src/main/java/com/gh/common/util/DownloadItemUtils.kt @@ -225,7 +225,12 @@ object DownloadItemUtils { } } } else if (gameEntity.getApk().size == 1) { - val downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity) + var downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity) + + if (downloadEntity == null && gameEntity.isVGame()) { + downloadEntity = VHelper.getDownloadEntitySnapshotByPackageName(gameEntity.getUniquePackageName() ?: "") + } + if (downloadEntity != null) { downloadBtn.apply { val status = downloadEntity.status @@ -249,7 +254,7 @@ object DownloadItemUtils { } if (downloadEntity.isSimulatorGame() && gameEntity.simulator != null) { GameUtils.setDownloadBtnStatus(context, gameEntity, downloadBtn, pluginLocation) - } else if (downloadEntity.isSmoothGame()) { + } else if (downloadEntity.isVGame()) { if (PackagesManager.isCanUpdate(downloadEntity.gameId, downloadEntity.packageName)) { setText(R.string.update) } else { @@ -331,7 +336,7 @@ object DownloadItemUtils { ) { val status = downloadEntity.status // 畅玩游戏下载完成时不再需要显示进度条 - val shouldShowDownload = !(downloadEntity.isSmoothGame() && status == DownloadStatus.done) + val shouldShowDownload = !(downloadEntity.isVGame() && status == DownloadStatus.done) val platform = PlatformUtils.getInstance(context).getPlatformName(downloadEntity.platform) updateItemViewStatus(holder, shouldShowDownload, null, null, isShowRecommendStar) diff --git a/app/src/main/java/com/gh/common/util/DownloadNotificationHelper.kt b/app/src/main/java/com/gh/common/util/DownloadNotificationHelper.kt index ddd36d1516..4e79ad543d 100644 --- a/app/src/main/java/com/gh/common/util/DownloadNotificationHelper.kt +++ b/app/src/main/java/com/gh/common/util/DownloadNotificationHelper.kt @@ -56,7 +56,7 @@ object DownloadNotificationHelper { intent.putExtra(EntranceConsts.KEY_DATA, entity.toJson()) intent.putExtra(EntranceConsts.KEY_PATH, entity.path) intent.action = ACTION_INSTALL - } else if (entity.isSmoothGame()) { + } else if (entity.isVGame()) { intent.action = ACTION_VDOWNLOAD } else { intent.action = ACTION_DOWNLOAD diff --git a/app/src/main/java/com/gh/common/util/DownloadObserver.kt b/app/src/main/java/com/gh/common/util/DownloadObserver.kt index 78fa86a1f3..6123dc05cf 100644 --- a/app/src/main/java/com/gh/common/util/DownloadObserver.kt +++ b/app/src/main/java/com/gh/common/util/DownloadObserver.kt @@ -218,7 +218,7 @@ object DownloadObserver { ) downloadEntity.isPlugin -> Utils.toast(mApplication, downloadEntity.name + " - " + platform + " - 下载完成") else -> { - if (downloadEntity.isSmoothGame()) { + if (downloadEntity.isVGame()) { VHelper.showFloatingWindow(downloadEntity.packageName) } else { Utils.toast(mApplication, downloadEntity.name + " - 下载完成") @@ -226,7 +226,7 @@ object DownloadObserver { } } } else { - if (downloadEntity.isSmoothGame()) { + if (downloadEntity.isVGame()) { VHelper.showFloatingWindow(downloadEntity.packageName) } else { Utils.toast(mApplication, downloadEntity.name + " - 下载完成") @@ -325,7 +325,7 @@ object DownloadObserver { private fun statDoneEvent(downloadEntity: DownloadEntity) { var type: ExposureUtils.DownloadType if (downloadEntity.isUpdate) { - if (downloadEntity.isSmoothGame()) { + if (downloadEntity.isVGame()) { type = ExposureUtils.DownloadType.FUN_UPDATE } else { type = ExposureUtils.DownloadType.UPDATE @@ -334,7 +334,7 @@ object DownloadObserver { } } } else { - type = if (downloadEntity.isSmoothGame()) { + type = if (downloadEntity.isVGame()) { ExposureUtils.DownloadType.FUN_DOWNLOAD } else { ExposureUtils.DownloadType.DOWNLOAD diff --git a/app/src/main/java/com/gh/common/util/GameUtils.java b/app/src/main/java/com/gh/common/util/GameUtils.java index 3cd9eaa0aa..9fb8e4e690 100644 --- a/app/src/main/java/com/gh/common/util/GameUtils.java +++ b/app/src/main/java/com/gh/common/util/GameUtils.java @@ -107,6 +107,11 @@ public class GameUtils { downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity); + // 在下载管理找不到下载实体,并且为畅玩游戏的时候到畅玩数据库里找 + if (downloadEntity == null && gameEntity.isVGame()) { + downloadEntity = VHelper.getDownloadEntitySnapshotByPackageName(apkEntity.getPackageName()); + } + if (downloadEntity != null) { if (downloadEntity.getStatus().equals(DownloadStatus.done)) { doneCount++; diff --git a/app/src/main/java/com/gh/common/util/PackageUtils.java b/app/src/main/java/com/gh/common/util/PackageUtils.java index 7b24cfaf06..a31ba82f3a 100644 --- a/app/src/main/java/com/gh/common/util/PackageUtils.java +++ b/app/src/main/java/com/gh/common/util/PackageUtils.java @@ -31,6 +31,8 @@ import com.gh.gamecenter.entity.ApkEntity; import com.gh.gamecenter.entity.GameEntity; import com.gh.gamecenter.entity.GameUpdateEntity; import com.gh.gamecenter.manager.PackagesManager; +import com.gh.vspace.VHelper; +import com.gh.vspace.db.VGameEntity; import com.halo.assistant.HaloApp; import com.lightgame.download.DownloadEntity; import com.lightgame.utils.Utils; @@ -127,12 +129,14 @@ public class PackageUtils { // 畅玩游戏根据 md5 是否一致确定是否需要更新 if (gameEntity.isVGame()) { - DownloadEntity entity = DownloadManager.getInstance().getDownloadEntitySnapshotByPackageName(apkEntity.getPackageName()); - if (entity != null) { - String md5FromInstalledVGame = ExtensionsKt.getMetaExtra(entity, Constants.APK_MD5); + VGameEntity vGameEntity = VHelper.getVGameSnapshot(apkEntity.getPackageName()); + if (vGameEntity != null) { + String md5FromInstalledVGame = ExtensionsKt.getMetaExtra(vGameEntity.getDownloadEntity(), Constants.APK_MD5); String md5FromRequest = apkEntity.getMd5(); shouldShowUpdate = md5FromRequest != null && !md5FromRequest.equals(md5FromInstalledVGame); + } else { + shouldShowUpdate = false; } } diff --git a/app/src/main/java/com/gh/download/DownloadManager.java b/app/src/main/java/com/gh/download/DownloadManager.java index 34d8842c6c..f102aba568 100644 --- a/app/src/main/java/com/gh/download/DownloadManager.java +++ b/app/src/main/java/com/gh/download/DownloadManager.java @@ -88,12 +88,7 @@ public class DownloadManager implements DownloadStatusListener { private final ArrayMap statusMap; private final ArrayMap downloadingMap; - // 下载任务列表快照,非完全实时状态,只保证数量和基础状态,不保证下载进度和速度匹配 - // TODO 使用 mDownloadSnapshotList 来服务 getDownloadEntityByUrl -// private final List mDownloadSnapshotList; - private ArrayList mInvisiblePendingTaskList; // 用户不可见的 pending 任务 - private final DownloadDao mDownloadDao; private final DownloadedGameIdAndPackageNameDao mDownloadedGameIdAndPackageNameDao; @@ -607,18 +602,6 @@ public class DownloadManager implements DownloadStatusListener { return mDownloadDao.getSnapshotByPackageName(packageName); } - /** - * 根据 url 获取下载任务快照 (仅保证下载状态一致) - * - * @param gameId 游戏名 (若使用场景里有多包名,请使用 url 获取下载任务) - * @return null 表示下载列表中不存在该任务,否则返回下载任务 - */ - @Nullable - public DownloadEntity getDownloadEntitySnapshotByGameId(String gameId) { - if (TextUtils.isEmpty(gameId)) return null; - return mDownloadDao.getSnapshotByGameId(gameId); - } - /** * 根据包名获取某一个下载任务 (涉及数据库查询,请优先在子线程调用) * diff --git a/app/src/main/java/com/gh/download/PackageObserver.kt b/app/src/main/java/com/gh/download/PackageObserver.kt index ab51b38e2c..2c3cd125dc 100644 --- a/app/src/main/java/com/gh/download/PackageObserver.kt +++ b/app/src/main/java/com/gh/download/PackageObserver.kt @@ -12,7 +12,7 @@ import com.gh.gamecenter.common.constant.Constants import com.gh.gamecenter.common.loghub.LoghubUtils import com.gh.gamecenter.common.retrofit.EmptyResponse import com.gh.gamecenter.common.retrofit.Response -import com.gh.gamecenter.common.utils.getMetaExtra +import com.gh.gamecenter.common.utils.isVGame import com.gh.gamecenter.core.runOnIoThread import com.gh.gamecenter.core.utils.ThirdPartyPackageHelper import com.gh.gamecenter.core.utils.UrlFilterUtils @@ -99,12 +99,12 @@ object PackageObserver { if (gh_id == null) { ThirdPartyPackageHelper.saveGameId(mDownloadEntity.packageName, mDownloadEntity.gameId) } - if (mDownloadEntity.getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE) == Constants.SMOOTH_GAME) { + if (mDownloadEntity.isVGame()) { // 畅玩游戏安装完成的同时直接删除文件 runOnIoThread { FileUtils.deleteFile(mDownloadEntity.path) } - } else { - DownloadManager.getInstance().cancel(mDownloadEntity.url, false, true, false) } + + DownloadManager.getInstance().cancel(mDownloadEntity.url, false, true, false) } if (sp.getBoolean(CONCERN_GAME_SP_KEY, true)) { //设置页面控制是否安装后自动关注 // 安装后关注游戏 diff --git a/app/src/main/java/com/gh/gamecenter/download/GameDownloadFragment.java b/app/src/main/java/com/gh/gamecenter/download/GameDownloadFragment.java index f95e7e0fdd..6d303ed94b 100644 --- a/app/src/main/java/com/gh/gamecenter/download/GameDownloadFragment.java +++ b/app/src/main/java/com/gh/gamecenter/download/GameDownloadFragment.java @@ -172,7 +172,7 @@ public class GameDownloadFragment extends BaseFragment implements View.OnClickLi // 静默更新任务,下载模拟器任务,畅玩游戏不需要添加 if (ExtensionsKt.isSilentUpdate(downloadEntity) || ExtensionsKt.isSimulatorDownload(downloadEntity) - || ExtensionsKt.isSmoothGame(downloadEntity)) { + || ExtensionsKt.isVGame(downloadEntity)) { return; } diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt index ae54cab3f0..b361daa700 100644 --- a/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/home/HomeViewModel.kt @@ -30,6 +30,7 @@ import com.gh.vspace.VGameItemData import com.gh.vspace.VHelper import com.halo.assistant.HaloApp import com.halo.assistant.fragment.SettingsFragment +import com.lightgame.download.DownloadEntity import com.lightgame.utils.Utils import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.schedulers.Schedulers @@ -125,29 +126,47 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) { * 完成下载且已启动过的游戏:按照游戏的畅玩时长从左(长)向右(短)排列 */ private fun getSortedVEntityList() : List { - val rawEntityList = DownloadManager.getInstance().allVDownloadTaskSnapshots + val rawDownloadEntityList = DownloadManager.getInstance().allVDownloadTaskSnapshots + val rawInstalledEntityList = VHelper.getAllVGameSnapshots() + val rawEntityList = arrayListOf() + var fixedTopEntity: VGameItemData? = null val unplayedEntityList = arrayListOf() val playedEntityList = arrayListOf() val sortedEntityList = arrayListOf() + val distinctIdSet = hashSetOf() + // 将下载任务的实体放进待排序列表里 + for (rawDownloadEntity in rawDownloadEntityList) { + distinctIdSet.add(rawDownloadEntity.gameId) + rawEntityList.add(rawDownloadEntity) + } + // 将已安装任务的实体放进待排序列表里 + for (rawInstalledEntity in rawInstalledEntityList) { + if (distinctIdSet.contains(rawInstalledEntity.downloadEntity.gameId)) { + continue + } + rawEntityList.add(rawInstalledEntity.downloadEntity) + } + distinctIdSet.clear() + for (rawEntity in rawEntityList) { val lastPlayedTime = VHelper.getLastPlayedTime(rawEntity) val latestModifiedTime = maxOf(rawEntity.start, VHelper.getLastPlayedTime(rawEntity)) if (fixedTopEntity == null) { - fixedTopEntity = VGameItemData.fromDownloadEntity(rawEntity) + fixedTopEntity = VGameItemData.from(rawEntity) } else { val fixedTopLatestModifiedTime = maxOf(fixedTopEntity.downloadEntity.start, VHelper.getLastPlayedTime(fixedTopEntity.downloadEntity)) if (latestModifiedTime > fixedTopLatestModifiedTime) { - fixedTopEntity = VGameItemData.fromDownloadEntity(rawEntity) + fixedTopEntity = VGameItemData.from(rawEntity) } } if (lastPlayedTime == 0L) { - unplayedEntityList.add(VGameItemData.fromDownloadEntity(rawEntity)) + unplayedEntityList.add(VGameItemData.from(rawEntity)) } else { - playedEntityList.add(VGameItemData.fromDownloadEntity(rawEntity)) + playedEntityList.add(VGameItemData.from(rawEntity)) } } diff --git a/app/src/main/java/com/gh/vspace/VBackupHelper.kt b/app/src/main/java/com/gh/vspace/VBackupHelper.kt index 65449fbbab..a4cade8519 100644 --- a/app/src/main/java/com/gh/vspace/VBackupHelper.kt +++ b/app/src/main/java/com/gh/vspace/VBackupHelper.kt @@ -3,9 +3,9 @@ package com.gh.vspace import android.content.Context import android.os.Environment import com.gh.download.DownloadManager -import com.gh.gamecenter.common.utils.isSmoothGame +import com.gh.gamecenter.common.utils.isVGame import com.gh.gamecenter.core.runOnIoThread -import com.lightgame.download.DBHelper +import com.gh.vspace.db.VGameDatabase import com.lightgame.download.DownloadStatus import com.lightgame.utils.Utils import java.io.File @@ -22,7 +22,7 @@ object VBackupHelper { val entityList = DownloadManager.getInstance().allDownloadEntity for (entity in entityList) { - if (!entity.isSmoothGame() || entity.status != DownloadStatus.done) { + if (!entity.isVGame() || entity.status != DownloadStatus.done) { DownloadManager.getInstance().cancel(entity.url) } } @@ -33,8 +33,8 @@ object VBackupHelper { try { val rootDir: File = Environment.getExternalStorageDirectory() if (rootDir.canWrite()) { - val appDB: File = context.getDatabasePath(DBHelper.DB_NAME) - val backupDBPath = String.format("/gh-files/%s.bak", DBHelper.DB_NAME) + val appDB: File = context.getDatabasePath(VGameDatabase.DATABASE) + val backupDBPath = String.format("/gh-files/%s.bak", VGameDatabase.DATABASE) val externalDB = File(rootDir, backupDBPath) val src: FileChannel = FileInputStream(externalDB).channel val dst: FileChannel = FileOutputStream(appDB).channel @@ -58,8 +58,8 @@ object VBackupHelper { try { val rootDir: File = Environment.getExternalStorageDirectory() if (rootDir.canWrite()) { - val appDB: File = context.getDatabasePath(DBHelper.DB_NAME) - val externalDBPath = String.format("/gh-files/%s.bak", DBHelper.DB_NAME) + val appDB: File = context.getDatabasePath(VGameDatabase.DATABASE) + val externalDBPath = String.format("/gh-files/%s.bak", VGameDatabase.DATABASE) val externalDB = File(rootDir, externalDBPath) val src: FileChannel = FileInputStream(appDB).channel val dst: FileChannel = FileOutputStream(externalDB).channel diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt index bd09feb554..43ea3fc825 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerAdapter.kt @@ -271,6 +271,8 @@ class VDownloadManagerAdapter( downloadBtn.goneIf(mCurrentOption != ManageOption.OPTION_MANAGER) val downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity) + ?: VHelper.getDownloadEntitySnapshotByPackageName(gameEntity.getUniquePackageName() ?: "") + if (downloadEntity != null) { val status = downloadEntity.status var btnText = context.getText(R.string.downloading) diff --git a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt index 67a509e4ef..965e507913 100644 --- a/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt +++ b/app/src/main/java/com/gh/vspace/VDownloadManagerViewModel.kt @@ -8,7 +8,6 @@ import com.gh.gamecenter.common.utils.toProperReadableSize import com.gh.gamecenter.core.utils.NumberUtils import com.gh.gamecenter.entity.GameEntity import com.gh.gamecenter.eventbus.EBPackage -import com.lightgame.download.DownloadStatus import io.reactivex.Observable import io.reactivex.Single import org.greenrobot.eventbus.EventBus @@ -30,46 +29,44 @@ class VDownloadManagerViewModel(application: Application) : override fun provideDataSingle(page: Int): Single> { if (type == TYPE_DOWNLOADED) { return Single.create { emitter -> - val vDownloadList = DownloadManager.getInstance().allVDownloadTaskSnapshots - val gameIdSet = hashSetOf() // 游戏 id set,避免下载任务和已安装任务同时出现 + val vGameList = VHelper.getAllVGame() + val gameList = arrayListOf() - val vGameList = arrayListOf() - - for (downloadEntity in vDownloadList) { - if (downloadEntity.status == DownloadStatus.done) { - gameIdSet.add(downloadEntity.gameId) - - val gameEntity = VHelper.toGameEntity(downloadEntity) - if (gameEntity.playedTime != 0L) { - gameEntity.des = "已畅玩${NumberUtils.transSimpleUsageTime(gameEntity.playedTime / 1000)}" - } else { - val occupiedSpace = VHelper.getAppOccupiedSpace(downloadEntity.packageName) - if (occupiedSpace > 0 ) { - gameEntity.des = "已占用 ${occupiedSpace.toProperReadableSize()}" - } - } - - vGameList.add(gameEntity) - } + // 为空直接返回 + if (vGameList.isEmpty()) { + emitter.onSuccess(gameList) + return@create } - emitter.onSuccess(vGameList) + for (vGame in vGameList) { + val gameEntity = VHelper.toGameEntity(vGame.downloadEntity) + if (gameEntity.playedTime != 0L) { + gameEntity.des = + "已畅玩${NumberUtils.transSimpleUsageTime(gameEntity.playedTime / 1000)}" + } else { + val occupiedSpace = + VHelper.getAppOccupiedSpace(vGame.downloadEntity.packageName) + if (occupiedSpace > 0) { + gameEntity.des = "已占用 ${occupiedSpace.toProperReadableSize()}" + } + } + + gameList.add(gameEntity) + } + + emitter.onSuccess(gameList) } } else { return Single.create { emitter -> - val vDownloadList = DownloadManager.getInstance().allVDownloadTaskSnapshots - val gameIdSet = hashSetOf() // 游戏 id set,避免下载任务和已安装任务同时出现 + val downloadList = DownloadManager.getInstance().allVDownloadTaskSnapshots - val vGameList = arrayListOf() + val gameList = arrayListOf() - for (downloadEntity in vDownloadList) { - if (downloadEntity.status != DownloadStatus.done) { - gameIdSet.add(downloadEntity.gameId) - vGameList.add(VHelper.toGameEntity(downloadEntity)) - } + for (downloadEntity in downloadList) { + gameList.add(VHelper.toGameEntity(downloadEntity)) } - emitter.onSuccess(vGameList) + emitter.onSuccess(gameList) } } } diff --git a/app/src/main/java/com/gh/vspace/VGameItemData.kt b/app/src/main/java/com/gh/vspace/VGameItemData.kt index 8d78e6a45b..7de042db50 100644 --- a/app/src/main/java/com/gh/vspace/VGameItemData.kt +++ b/app/src/main/java/com/gh/vspace/VGameItemData.kt @@ -15,7 +15,7 @@ data class VGameItemData( var controlText: String = "继续" ) { companion object { - fun fromDownloadEntity(downloadEntity: DownloadEntity): VGameItemData { + fun from(downloadEntity: DownloadEntity): VGameItemData { return VGameItemData(downloadEntity).apply { if (downloadEntity.status == DownloadStatus.done && VHelper.getLastPlayedTime(downloadEntity) == 0L diff --git a/app/src/main/java/com/gh/vspace/VHelper.kt b/app/src/main/java/com/gh/vspace/VHelper.kt index 257d9e0689..499f0813bc 100644 --- a/app/src/main/java/com/gh/vspace/VHelper.kt +++ b/app/src/main/java/com/gh/vspace/VHelper.kt @@ -6,6 +6,7 @@ import android.content.Context import android.content.Intent import android.text.TextUtils import android.view.View +import androidx.annotation.WorkerThread import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData @@ -38,6 +39,8 @@ import com.gh.gamecenter.eventbus.EBReuse import com.gh.gamecenter.manager.PackagesManager import com.gh.gamecenter.packagehelper.PackageRepository import com.gh.gamecenter.retrofit.RetrofitManager +import com.gh.vspace.db.VGameDatabase +import com.gh.vspace.db.VGameEntity import com.halo.assistant.HaloApp import com.lg.vspace.VirtualAppManager import com.lg.vspace.remote.listener.RemoteConnectListener @@ -49,6 +52,7 @@ import io.reactivex.schedulers.Schedulers import org.greenrobot.eventbus.EventBus import java.io.File import java.util.* +import kotlin.collections.ArrayList object VHelper { @@ -62,11 +66,18 @@ object VHelper { private val mInstallationLiveData by lazy { MutableLiveData() } private var mLastSuccessfullyLaunchedGame: Pair? = null + private val mVGameDao by lazy { + VGameDatabase.buildDatabase(HaloApp.getInstance().application).vGameDao() + } + private var mVGameSnapshotList = arrayListOf() + private var mUpdateEntity: AppEntity? = null // 当前正卡在安装中的 VA 游戏,避免重复调用安装 private val mInstallingVaPathSet by lazy { Collections.synchronizedSet(hashSetOf()) } + val vGameLiveData by lazy { mVGameDao.getAllLiveData() } + private val mPackageObserver by lazy { PackageObserver.PackageChangeListener { val vaConfig = Config.getVSettingEntity()?.va ?: return@PackageChangeListener @@ -99,6 +110,10 @@ object VHelper { checkVSpaceUpdate(config.arch64!!) } PackageObserver.registerPackageChangeChangeListener(mPackageObserver) + + vGameLiveData.observeForever { + mVGameSnapshotList = ArrayList(it) + } } /** @@ -125,12 +140,28 @@ object VHelper { }) } - private fun invokeVSpace() { -// tryWithDefaultCatch { -// val intent = Intent(Intent.ACTION_VIEW, Uri.parse("vsserver://invoke_only")) -// intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) -// HaloApp.getInstance().startActivity(intent) -// } + /** + * 获取数据库里所有的畅玩游戏 + * + * (查询数据库,请在工作线程调用) + */ + @WorkerThread + fun getAllVGame(): List { + return mVGameDao.getAll() + } + + fun getAllVGameSnapshots(): ArrayList { + return ArrayList(mVGameSnapshotList) + } + + /** + * 获取内存里的畅玩游戏快照 + * + * @param packageName 需要获取的畅玩游戏的包名 + */ + @JvmStatic + fun getVGameSnapshot(packageName: String): VGameEntity? { + return mVGameSnapshotList.find { it.packageName == packageName } } private fun updateInstalledList() { @@ -170,19 +201,18 @@ object VHelper { * 启动成功,五秒内退出才显示反馈弹框 */ fun showFeedbackDialogIfLastSuccessfulLaunchedGameExitUnexpectedly(activity: AppCompatActivity) { - val timeOfLastSuccessfullyLaunchedGame = mLastSuccessfullyLaunchedGame?.first - val gameIdOfLastSuccessfullyLaunchedGame = mLastSuccessfullyLaunchedGame?.second + val time = mLastSuccessfullyLaunchedGame?.first + val packageName = mLastSuccessfullyLaunchedGame?.second if (activity !is SplashScreenActivity) { - if (timeOfLastSuccessfullyLaunchedGame != null - && gameIdOfLastSuccessfullyLaunchedGame != null - && System.currentTimeMillis() - timeOfLastSuccessfullyLaunchedGame < 5000 - && !VFeedbackSuppressedSimpleDao().contains(gameIdOfLastSuccessfullyLaunchedGame) + if (time != null + && packageName != null + && System.currentTimeMillis() - time < 5000 + && !VFeedbackSuppressedSimpleDao().contains(packageName) ) { - DownloadManager.getInstance() - .getDownloadEntitySnapshotByGameId(gameIdOfLastSuccessfullyLaunchedGame)?.let { - VFeedbackDialogFragment.show(activity, toGameEntity(it)) - mLastSuccessfullyLaunchedGame = null - } + getVGameSnapshot(packageName)?.let { + VFeedbackDialogFragment.show(activity, toGameEntity(it.downloadEntity)) + mLastSuccessfullyLaunchedGame = null + } } } } @@ -365,13 +395,15 @@ object VHelper { } // 安装过程会比较漫长,所以得放在工作线程运行 - AppExecutor.ioExecutor.execute { + runOnIoThread { try { mInstallingVaPathSet.add(downloadEntity.path) val result = VirtualAppManager.get().installGame(downloadEntity.path) + if (result.status == 0) { updateInstalledList() + mVGameDao.insert(VGameEntity.from(downloadEntity)) PackageObserver.onPackageChanged( EBPackage( "安装", @@ -421,7 +453,10 @@ object VHelper { return@checkStoragePermissionBeforeAction } - val downloadEntity = getDownloadEntitySnapshotByPackageName(packageName) + // 检查下载管理是否有下载实体,有实体表明未安装成功 + val downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshotByPackageName(packageName) + ?: getDownloadEntitySnapshotByPackageName(packageName) + if (downloadEntity != null) { if (File(downloadEntity.path).exists()) { install(context, downloadEntity, true) @@ -448,10 +483,7 @@ object VHelper { intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) context.startActivity(intent) - DownloadManager.getInstance().getDownloadEntitySnapshotByPackageName(packageName) - ?.let { - mLastSuccessfullyLaunchedGame = Pair(System.currentTimeMillis(), it.gameId) - } + mLastSuccessfullyLaunchedGame = Pair(System.currentTimeMillis(), packageName) updateLastPlayedTime(packageName) } catch (e: Exception) { @@ -465,6 +497,12 @@ object VHelper { fun uninstall(packageName: String?) { Utils.log(LOG_TAG, "卸载游戏 $packageName") + if (packageName.isNullOrBlank()) return + + runOnIoThread { + mVGameDao.delete(packageName) + } + val uninstallClosure: () -> Unit = { try { val result = VirtualAppManager.get().uninstallGame(packageName) @@ -510,8 +548,9 @@ object VHelper { /** * 根据包名获取下载快照 */ + @JvmStatic fun getDownloadEntitySnapshotByPackageName(packageName: String): DownloadEntity? { - return DownloadManager.getInstance().getDownloadEntitySnapshotByPackageName(packageName) + return getVGameSnapshot(packageName)?.downloadEntity } /** @@ -519,10 +558,13 @@ object VHelper { */ private fun updateLastPlayedTime(packageName: String) { runOnIoThread { - val entity = - DownloadManager.getInstance().allVDownloadTaskSnapshots.find { it.packageName == packageName } - entity?.addMetaExtra(KEY_LAST_PLAYED_TIME, System.currentTimeMillis().toString()) - DownloadManager.getInstance().updateDownloadEntity(entity) + getVGameSnapshot(packageName)?.let { + it.downloadEntity.addMetaExtra( + KEY_LAST_PLAYED_TIME, + System.currentTimeMillis().toString() + ) + mVGameDao.insert(it) + } // 更新首页排序 EventBus.getDefault().post(EBReuse("vgame")) @@ -584,11 +626,13 @@ object VHelper { */ @JvmStatic fun updateOrReDownload(gameEntity: GameEntity) { - PackagesManager.getUpdateList().firstOrNull { it.id == gameEntity.id }?.let { updateEntity -> - getDownloadEntitySnapshotByPackageName(gameEntity.getUniquePackageName() ?: "")?.let { downloadEntity -> - updateOrReDownload(downloadEntity, updateEntity) + PackagesManager.getUpdateList().firstOrNull { it.id == gameEntity.id } + ?.let { updateEntity -> + getVGameSnapshot(updateEntity.packageName) + ?.let { vGame -> + updateOrReDownload(vGame.downloadEntity, updateEntity) + } } - } } /** @@ -603,8 +647,6 @@ object VHelper { ) { Utils.log(LOG_TAG, "更新应用${originDownloadEntity.packageName}") - DownloadManager.getInstance().cancel(originDownloadEntity.url, false, false, true) - if (updateEntity != null) { originDownloadEntity.url = updateEntity.url originDownloadEntity.name = updateEntity.name @@ -630,7 +672,8 @@ object VHelper { originDownloadEntity.percent = 0.0 // 确定下载类型 - val downloadType = if (updateEntity == null) ExposureUtils.DownloadType.FUN_DOWNLOAD else ExposureUtils.DownloadType.FUN_UPDATE + val downloadType = + if (updateEntity == null) ExposureUtils.DownloadType.FUN_DOWNLOAD else ExposureUtils.DownloadType.FUN_UPDATE val gameEntity = GameEntity(originDownloadEntity.gameId, originDownloadEntity.name) gameEntity.gameVersion = originDownloadEntity.versionName ?: "" @@ -704,7 +747,7 @@ object VHelper { val rawInstalledPackageList = getInstalledPackageList() val validInstalledPackageList = arrayListOf() for (packageName in rawInstalledPackageList) { - if (getDownloadEntitySnapshotByPackageName(packageName) != null) { + if (getVGameSnapshot(packageName) != null) { validInstalledPackageList.add(packageName) } } diff --git a/app/src/main/java/com/gh/vspace/db/VGameConverter.kt b/app/src/main/java/com/gh/vspace/db/VGameConverter.kt new file mode 100644 index 0000000000..25c1608785 --- /dev/null +++ b/app/src/main/java/com/gh/vspace/db/VGameConverter.kt @@ -0,0 +1,19 @@ +package com.gh.vspace.db + +import androidx.room.TypeConverter +import com.gh.gamecenter.core.utils.GsonUtils +import com.lightgame.download.DownloadEntity + +class VGameConverter { + + @TypeConverter + fun convertDownload2String(any: DownloadEntity): String { + return GsonUtils.toJson(any) + } + + @TypeConverter + fun convertString2DownloadEntity(string: String): DownloadEntity { + return GsonUtils.fromJson(string, DownloadEntity::class.java) + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/vspace/db/VGameDao.kt b/app/src/main/java/com/gh/vspace/db/VGameDao.kt new file mode 100644 index 0000000000..fb79e7cbbc --- /dev/null +++ b/app/src/main/java/com/gh/vspace/db/VGameDao.kt @@ -0,0 +1,27 @@ +package com.gh.vspace.db + +import androidx.lifecycle.LiveData +import androidx.room.* + +@Dao +interface VGameDao { + + @Insert(onConflict = OnConflictStrategy.REPLACE) + fun insert(game: VGameEntity) + + @Query("SELECT * FROM v_game") + fun getAll(): List + + @Query("SELECT * FROM v_game") + fun getAllLiveData(): LiveData> + + @Delete + fun delete(gameList: List) + + @Delete + fun delete(game: VGameEntity) + + @Query("DELETE FROM v_game WHERE packageName = :packageName") + fun delete(packageName: String) + +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/vspace/db/VGameDatabase.kt b/app/src/main/java/com/gh/vspace/db/VGameDatabase.kt new file mode 100644 index 0000000000..105fb4564f --- /dev/null +++ b/app/src/main/java/com/gh/vspace/db/VGameDatabase.kt @@ -0,0 +1,25 @@ +package com.gh.vspace.db + +import android.content.Context +import androidx.room.Database +import androidx.room.Room +import androidx.room.RoomDatabase +import androidx.room.TypeConverters + +@TypeConverters(VGameConverter::class) +@Database(entities = [VGameEntity::class], version = 1, exportSchema = false) +abstract class VGameDatabase : RoomDatabase() { + + abstract fun vGameDao(): VGameDao + + companion object { + const val DATABASE = "v_game_database" + + fun buildDatabase(context: Context): VGameDatabase { + return Room.databaseBuilder(context, VGameDatabase::class.java, DATABASE) + .fallbackToDestructiveMigration() + .build() + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/vspace/db/VGameEntity.kt b/app/src/main/java/com/gh/vspace/db/VGameEntity.kt new file mode 100644 index 0000000000..f7b067b01d --- /dev/null +++ b/app/src/main/java/com/gh/vspace/db/VGameEntity.kt @@ -0,0 +1,21 @@ +package com.gh.vspace.db + +import android.os.Parcelable +import androidx.room.Entity +import androidx.room.PrimaryKey +import com.lightgame.download.DownloadEntity +import kotlinx.parcelize.Parcelize + +@Parcelize +@Entity(tableName = "v_game") +data class VGameEntity( + @PrimaryKey + var packageName: String, + var downloadEntity: DownloadEntity, +) : Parcelable { + companion object { + fun from(downloadEntity: DownloadEntity): VGameEntity { + return VGameEntity(downloadEntity.packageName, downloadEntity) + } + } +} \ No newline at end of file diff --git a/libraries/LGLibrary b/libraries/LGLibrary index aa56298ed0..2fb219f6c0 160000 --- a/libraries/LGLibrary +++ b/libraries/LGLibrary @@ -1 +1 @@ -Subproject commit aa56298ed01b07adbad83fcc4d5175f3b3ac59f7 +Subproject commit 2fb219f6c06a14cb78341c14f5b8c847484df6cf diff --git a/module_common/src/main/java/com/gh/gamecenter/common/utils/Extensions.kt b/module_common/src/main/java/com/gh/gamecenter/common/utils/Extensions.kt index 62bbeae0b7..037ca77214 100644 --- a/module_common/src/main/java/com/gh/gamecenter/common/utils/Extensions.kt +++ b/module_common/src/main/java/com/gh/gamecenter/common/utils/Extensions.kt @@ -973,7 +973,7 @@ fun DownloadEntity.isSimulatorGame(): Boolean { return getMetaExtra(Constants.SIMULATOR_GAME).isNotEmpty() } -fun DownloadEntity.isSmoothGame(): Boolean { +fun DownloadEntity.isVGame(): Boolean { return Constants.SMOOTH_GAME == getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE) }