Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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 ||
packageDownloadData[packageName]?.packageName != packageName ||
packageDownloadData[packageName]?.moduleNames?.intersect(params.moduleNames.toSet())?.isEmpty() == true) {
packageDownloadData[packageName] = httpClient.initAssetModuleData(context, packageName, accountManager, params.moduleNames, params.options)
val needInit = synchronized(lock) {
packageDownloadData[packageName] == null ||
packageDownloadData[packageName]?.packageName != packageName ||
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)
}
Expand Down Expand Up @@ -114,24 +124,26 @@ class AssetModuleServiceImpl(
override suspend fun getSessionStates(params: GetSessionStatesParameters, packageName: String, callback: IAssetModuleServiceCallback?) {
val listBundleData: MutableList<Bundle> = mutableListOf()

if (packageDownloadData[packageName] != null && packageDownloadData[packageName]?.moduleNames?.all {
packageDownloadData[packageName]?.getModuleData(it)?.status == AssetPackStatus.COMPLETED
} == true && params.installedAssetModules.isEmpty()) {
Log.d(TAG, "getSessionStates: resetAllModuleStatus: $listBundleData")
packageDownloadData[packageName]?.resetAllModuleStatus()
callback?.onGetSessionStates(listBundleData)
return
}
synchronized(lock) {
if (packageDownloadData[packageName] != null && packageDownloadData[packageName]?.moduleNames?.all {
packageDownloadData[packageName]?.getModuleData(it)?.status == AssetPackStatus.COMPLETED
} == true && params.installedAssetModules.isEmpty()) {
Log.d(TAG, "getSessionStates: resetAllModuleStatus: $listBundleData")
packageDownloadData[packageName]?.resetAllModuleStatus()
callback?.onGetSessionStates(listBundleData)
return
}

packageDownloadData[packageName]?.moduleNames?.forEach { moduleName ->
if (moduleName in params.installedAssetModules) return@forEach
packageDownloadData[packageName]?.moduleNames?.forEach { moduleName ->
if (moduleName in params.installedAssetModules) return@forEach

listBundleData.add(sendBroadcastForExistingFile(context, packageDownloadData[packageName]!!, moduleName, null, null))
listBundleData.add(sendBroadcastForExistingFile(context, packageDownloadData[packageName]!!, moduleName, null, null))

packageDownloadData[packageName]?.getModuleData(moduleName)?.chunks?.forEach { chunkData ->
val destination = chunkData.getChunkFile(context)
if (destination.exists() && destination.length() == chunkData.chunkBytesToDownload) {
sendBroadcastForExistingFile(context, packageDownloadData[packageName]!!, moduleName, chunkData, destination)
packageDownloadData[packageName]?.getModuleData(moduleName)?.chunks?.forEach { chunkData ->
val destination = chunkData.getChunkFile(context)
if (destination.exists() && destination.length() == chunkData.chunkBytesToDownload) {
sendBroadcastForExistingFile(context, packageDownloadData[packageName]!!, moduleName, chunkData, destination)
}
}
}
}
Expand All @@ -143,9 +155,11 @@ class AssetModuleServiceImpl(
override suspend fun notifyChunkTransferred(params: NotifyChunkTransferredParameters, packageName: String, callback: IAssetModuleServiceCallback?) {
checkSessionValid(packageName, params.sessionId)

val downLoadFile = context.getChunkFile(params.sessionId, params.moduleName, params.sliceId, params.chunkNumber)
fileDescriptorMap[downLoadFile]?.close()
fileDescriptorMap.remove(downLoadFile)
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) +
Expand All @@ -159,8 +173,10 @@ class AssetModuleServiceImpl(
override suspend fun notifyModuleCompleted(params: NotifyModuleCompletedParameters, packageName: String, callback: IAssetModuleServiceCallback?) {
checkSessionValid(packageName, params.sessionId)

packageDownloadData[packageName]?.updateDownloadStatus(params.moduleName, AssetPackStatus.COMPLETED)
sendBroadcastForExistingFile(context, packageDownloadData[packageName]!!, params.moduleName, null, null)
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()) {
Expand Down Expand Up @@ -192,9 +208,11 @@ class AssetModuleServiceImpl(
override suspend fun getChunkFileDescriptor(params: GetChunkFileDescriptorParameters, packageName: String, callback: IAssetModuleServiceCallback?) {
checkSessionValid(packageName, params.sessionId)

val downLoadFile = context.getChunkFile(params.sessionId, params.moduleName, params.sliceId, params.chunkNumber)
val parcelFileDescriptor = ParcelFileDescriptor.open(downLoadFile, ParcelFileDescriptor.MODE_READ_ONLY).also {
fileDescriptorMap[downLoadFile] = it
val parcelFileDescriptor = synchronized(lock) {
val downLoadFile = context.getChunkFile(params.sessionId, params.moduleName, params.sliceId, params.chunkNumber)
ParcelFileDescriptor.open(downLoadFile, ParcelFileDescriptor.MODE_READ_ONLY).also {
fileDescriptorMap[downLoadFile] = it
}
}

Log.d(TAG, "getChunkFileDescriptor -> $parcelFileDescriptor")
Expand All @@ -205,10 +223,17 @@ class AssetModuleServiceImpl(
}

override suspend fun requestDownloadInfo(params: RequestDownloadInfoParameters, packageName: String, callback: IAssetModuleServiceCallback?) {
if (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)
val needInit = synchronized(lock) {
packageDownloadData[packageName] == null ||
packageDownloadData[packageName]?.packageName != packageName ||
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)
}
Expand Down