Loading vending-app/src/main/kotlin/com/google/android/finsky/assetmoduleservice/AssetModuleService.kt +57 −32 Original line number Diff line number Diff line Loading @@ -56,22 +56,32 @@ class AssetModuleServiceImpl( private val packageDownloadData: MutableMap<String, DownloadData?> ) : AbstractAssetModuleServiceImpl(context, lifecycle) { private val fileDescriptorMap = mutableMapOf<File, ParcelFileDescriptor>() private val lock = Any() private fun checkSessionValid(packageName: String, sessionId: Int) { Log.d(TAG, "checkSessionValid: $packageName $sessionId ${packageDownloadData[packageName]?.sessionIds}") if (packageDownloadData[packageName]?.sessionIds?.values?.contains(sessionId) != true) { Log.w(TAG, "No active session with id $sessionId in $packageName") throw AssetPackException(AssetPackErrorCode.ACCESS_DENIED) } } override fun getDefaultSessionId(packageName: String, moduleName: String): Int = override fun getDefaultSessionId(packageName: String, moduleName: String): Int = synchronized(lock) { packageDownloadData[packageName]?.sessionIds?.get(moduleName) ?: 0 } override suspend fun startDownload(params: StartDownloadParameters, packageName: String, callback: IAssetModuleServiceCallback?) { if (packageDownloadData[packageName] == null || val needInit = synchronized(lock) { packageDownloadData[packageName] == null || packageDownloadData[packageName]?.packageName != packageName || packageDownloadData[packageName]?.moduleNames?.intersect(params.moduleNames.toSet())?.isEmpty() == true) { packageDownloadData[packageName] = httpClient.initAssetModuleData(context, packageName, accountManager, params.moduleNames, params.options) packageDownloadData[packageName]?.moduleNames?.intersect(params.moduleNames.toSet())?.isEmpty() == true } if (needInit) { val newData = httpClient.initAssetModuleData(context, packageName, accountManager, params.moduleNames, params.options) synchronized(lock) { packageDownloadData[packageName] = packageDownloadData[packageName].merge(newData) } if (packageDownloadData[packageName] == null) { throw AssetPackException(AssetPackErrorCode.API_NOT_AVAILABLE) } Loading Loading @@ -114,6 +124,7 @@ class AssetModuleServiceImpl( override suspend fun getSessionStates(params: GetSessionStatesParameters, packageName: String, callback: IAssetModuleServiceCallback?) { val listBundleData: MutableList<Bundle> = mutableListOf() synchronized(lock) { if (packageDownloadData[packageName] != null && packageDownloadData[packageName]?.moduleNames?.all { packageDownloadData[packageName]?.getModuleData(it)?.status == AssetPackStatus.COMPLETED } == true && params.installedAssetModules.isEmpty()) { Loading @@ -135,6 +146,7 @@ class AssetModuleServiceImpl( } } } } Log.d(TAG, "getSessionStates: $listBundleData") callback?.onGetSessionStates(listBundleData) Loading @@ -143,9 +155,11 @@ class AssetModuleServiceImpl( override suspend fun notifyChunkTransferred(params: NotifyChunkTransferredParameters, packageName: String, callback: IAssetModuleServiceCallback?) { checkSessionValid(packageName, params.sessionId) synchronized(lock) { val downLoadFile = context.getChunkFile(params.sessionId, params.moduleName, params.sliceId, params.chunkNumber) fileDescriptorMap[downLoadFile]?.close() fileDescriptorMap.remove(downLoadFile) } // TODO: Remove chunk after successful transfer of chunk or only with module? callback?.onNotifyChunkTransferred( bundleOf(BundleKeys.MODULE_NAME to params.moduleName) + Loading @@ -159,8 +173,10 @@ class AssetModuleServiceImpl( override suspend fun notifyModuleCompleted(params: NotifyModuleCompletedParameters, packageName: String, callback: IAssetModuleServiceCallback?) { checkSessionValid(packageName, params.sessionId) synchronized(lock) { packageDownloadData[packageName]?.updateDownloadStatus(params.moduleName, AssetPackStatus.COMPLETED) sendBroadcastForExistingFile(context, packageDownloadData[packageName]!!, params.moduleName, null, null) } val directory = context.getModuleDir(params.sessionId, params.moduleName) if (directory.exists()) { Loading Loading @@ -192,10 +208,12 @@ class AssetModuleServiceImpl( override suspend fun getChunkFileDescriptor(params: GetChunkFileDescriptorParameters, packageName: String, callback: IAssetModuleServiceCallback?) { checkSessionValid(packageName, params.sessionId) val parcelFileDescriptor = synchronized(lock) { val downLoadFile = context.getChunkFile(params.sessionId, params.moduleName, params.sliceId, params.chunkNumber) val parcelFileDescriptor = ParcelFileDescriptor.open(downLoadFile, ParcelFileDescriptor.MODE_READ_ONLY).also { ParcelFileDescriptor.open(downLoadFile, ParcelFileDescriptor.MODE_READ_ONLY).also { fileDescriptorMap[downLoadFile] = it } } Log.d(TAG, "getChunkFileDescriptor -> $parcelFileDescriptor") callback?.onGetChunkFileDescriptor( Loading @@ -205,10 +223,17 @@ class AssetModuleServiceImpl( } override suspend fun requestDownloadInfo(params: RequestDownloadInfoParameters, packageName: String, callback: IAssetModuleServiceCallback?) { if (packageDownloadData[packageName] == null || val needInit = synchronized(lock) { packageDownloadData[packageName] == null || packageDownloadData[packageName]?.packageName != packageName || packageDownloadData[packageName]?.moduleNames?.intersect(params.moduleNames.toSet())?.isEmpty() == true) { packageDownloadData[packageName] = httpClient.initAssetModuleData(context, packageName, accountManager, params.moduleNames, params.options) packageDownloadData[packageName]?.moduleNames?.intersect(params.moduleNames.toSet())?.isEmpty() == true } if (needInit) { val newData = httpClient.initAssetModuleData(context, packageName, accountManager, params.moduleNames, params.options) synchronized(lock) { packageDownloadData[packageName] = packageDownloadData[packageName].merge(newData) } if (packageDownloadData[packageName] == null) { throw AssetPackException(AssetPackErrorCode.API_NOT_AVAILABLE) } Loading Loading
vending-app/src/main/kotlin/com/google/android/finsky/assetmoduleservice/AssetModuleService.kt +57 −32 Original line number Diff line number Diff line Loading @@ -56,22 +56,32 @@ class AssetModuleServiceImpl( private val packageDownloadData: MutableMap<String, DownloadData?> ) : AbstractAssetModuleServiceImpl(context, lifecycle) { private val fileDescriptorMap = mutableMapOf<File, ParcelFileDescriptor>() private val lock = Any() private fun checkSessionValid(packageName: String, sessionId: Int) { Log.d(TAG, "checkSessionValid: $packageName $sessionId ${packageDownloadData[packageName]?.sessionIds}") if (packageDownloadData[packageName]?.sessionIds?.values?.contains(sessionId) != true) { Log.w(TAG, "No active session with id $sessionId in $packageName") throw AssetPackException(AssetPackErrorCode.ACCESS_DENIED) } } override fun getDefaultSessionId(packageName: String, moduleName: String): Int = override fun getDefaultSessionId(packageName: String, moduleName: String): Int = synchronized(lock) { packageDownloadData[packageName]?.sessionIds?.get(moduleName) ?: 0 } override suspend fun startDownload(params: StartDownloadParameters, packageName: String, callback: IAssetModuleServiceCallback?) { if (packageDownloadData[packageName] == null || val needInit = synchronized(lock) { packageDownloadData[packageName] == null || packageDownloadData[packageName]?.packageName != packageName || packageDownloadData[packageName]?.moduleNames?.intersect(params.moduleNames.toSet())?.isEmpty() == true) { packageDownloadData[packageName] = httpClient.initAssetModuleData(context, packageName, accountManager, params.moduleNames, params.options) packageDownloadData[packageName]?.moduleNames?.intersect(params.moduleNames.toSet())?.isEmpty() == true } if (needInit) { val newData = httpClient.initAssetModuleData(context, packageName, accountManager, params.moduleNames, params.options) synchronized(lock) { packageDownloadData[packageName] = packageDownloadData[packageName].merge(newData) } if (packageDownloadData[packageName] == null) { throw AssetPackException(AssetPackErrorCode.API_NOT_AVAILABLE) } Loading Loading @@ -114,6 +124,7 @@ class AssetModuleServiceImpl( override suspend fun getSessionStates(params: GetSessionStatesParameters, packageName: String, callback: IAssetModuleServiceCallback?) { val listBundleData: MutableList<Bundle> = mutableListOf() synchronized(lock) { if (packageDownloadData[packageName] != null && packageDownloadData[packageName]?.moduleNames?.all { packageDownloadData[packageName]?.getModuleData(it)?.status == AssetPackStatus.COMPLETED } == true && params.installedAssetModules.isEmpty()) { Loading @@ -135,6 +146,7 @@ class AssetModuleServiceImpl( } } } } Log.d(TAG, "getSessionStates: $listBundleData") callback?.onGetSessionStates(listBundleData) Loading @@ -143,9 +155,11 @@ class AssetModuleServiceImpl( override suspend fun notifyChunkTransferred(params: NotifyChunkTransferredParameters, packageName: String, callback: IAssetModuleServiceCallback?) { checkSessionValid(packageName, params.sessionId) synchronized(lock) { val downLoadFile = context.getChunkFile(params.sessionId, params.moduleName, params.sliceId, params.chunkNumber) fileDescriptorMap[downLoadFile]?.close() fileDescriptorMap.remove(downLoadFile) } // TODO: Remove chunk after successful transfer of chunk or only with module? callback?.onNotifyChunkTransferred( bundleOf(BundleKeys.MODULE_NAME to params.moduleName) + Loading @@ -159,8 +173,10 @@ class AssetModuleServiceImpl( override suspend fun notifyModuleCompleted(params: NotifyModuleCompletedParameters, packageName: String, callback: IAssetModuleServiceCallback?) { checkSessionValid(packageName, params.sessionId) synchronized(lock) { packageDownloadData[packageName]?.updateDownloadStatus(params.moduleName, AssetPackStatus.COMPLETED) sendBroadcastForExistingFile(context, packageDownloadData[packageName]!!, params.moduleName, null, null) } val directory = context.getModuleDir(params.sessionId, params.moduleName) if (directory.exists()) { Loading Loading @@ -192,10 +208,12 @@ class AssetModuleServiceImpl( override suspend fun getChunkFileDescriptor(params: GetChunkFileDescriptorParameters, packageName: String, callback: IAssetModuleServiceCallback?) { checkSessionValid(packageName, params.sessionId) val parcelFileDescriptor = synchronized(lock) { val downLoadFile = context.getChunkFile(params.sessionId, params.moduleName, params.sliceId, params.chunkNumber) val parcelFileDescriptor = ParcelFileDescriptor.open(downLoadFile, ParcelFileDescriptor.MODE_READ_ONLY).also { ParcelFileDescriptor.open(downLoadFile, ParcelFileDescriptor.MODE_READ_ONLY).also { fileDescriptorMap[downLoadFile] = it } } Log.d(TAG, "getChunkFileDescriptor -> $parcelFileDescriptor") callback?.onGetChunkFileDescriptor( Loading @@ -205,10 +223,17 @@ class AssetModuleServiceImpl( } override suspend fun requestDownloadInfo(params: RequestDownloadInfoParameters, packageName: String, callback: IAssetModuleServiceCallback?) { if (packageDownloadData[packageName] == null || val needInit = synchronized(lock) { packageDownloadData[packageName] == null || packageDownloadData[packageName]?.packageName != packageName || packageDownloadData[packageName]?.moduleNames?.intersect(params.moduleNames.toSet())?.isEmpty() == true) { packageDownloadData[packageName] = httpClient.initAssetModuleData(context, packageName, accountManager, params.moduleNames, params.options) packageDownloadData[packageName]?.moduleNames?.intersect(params.moduleNames.toSet())?.isEmpty() == true } if (needInit) { val newData = httpClient.initAssetModuleData(context, packageName, accountManager, params.moduleNames, params.options) synchronized(lock) { packageDownloadData[packageName] = packageDownloadData[packageName].merge(newData) } if (packageDownloadData[packageName] == null) { throw AssetPackException(AssetPackErrorCode.API_NOT_AVAILABLE) } Loading