uf-client-service/src/main/kotlin/com/kynetics/uf/android/update/application/InstallerSession.kt
/*
* Copyright © 2017-2023 Kynetics LLC
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/
package com.kynetics.uf.android.update.application
import android.content.Context
import android.content.pm.PackageInstaller
import android.content.pm.PackageInstaller.SessionParams
import android.os.Build
import android.util.Log
import androidx.annotation.RequiresApi
import com.kynetics.uf.android.update.CurrentUpdateState
import org.eclipse.hara.ddiclient.api.Updater
import java.io.File
import java.io.FileInputStream
import java.io.IOException
import java.util.concurrent.CountDownLatch
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
class InstallerSession private constructor(private val context: Context,
private val packageInstaller: PackageInstaller,
// TODO: 07/02/19 unregister sessionCallback
private val sessionId: Int) {
fun writeSession(file: File, name: String) {
val sizeBytes = file.length()
Log.v(TAG, "apk size :$sizeBytes")
try {
packageInstaller.openSession(sessionId).use { session ->
FileInputStream(file).use { `in` ->
session.openWrite(name, 0, sizeBytes).use { out ->
val buffer = ByteArray(65536)
var c: Int
while (`in`.read(buffer).also { c = it } != -1) {
out.write(buffer, 0, c)
}
session.fsync(out)
}
}
}
} catch (e: IOException) {
Log.d(TAG, e.message, e)
}
}
fun commitSession() {
try {
packageInstaller.openSession(sessionId).use { session -> session.commit(
PackageInstallerBRHandler.createIntentSender(context, sessionId)
) }
} catch (e: IOException) {
Log.d(TAG, e.message, e)
}
}
companion object {
@Throws(IOException::class)
fun newInstance(context: Context,
countDownLatch: CountDownLatch?,
packageName: String?,
packageVersion: Long?,
artifact: Updater.SwModuleWithPath.Artifact?,
messenger: Updater.Messenger?,
currentUpdateState: CurrentUpdateState?): InstallerSession {
val packageInstaller = context.packageManager
.packageInstaller
val params = SessionParams(
SessionParams.MODE_FULL_INSTALL)
params.setAppPackageName(packageName)
val sessionId = packageInstaller.createSession(params)
PackageInstallerBRHandler.registerReceiver(
context,
PackageInstallerBroadcastReceiver(
sessionId,
countDownLatch!!,
artifact!!,
currentUpdateState!!,
messenger!!,
packageName!!,
packageVersion
)
)
return InstallerSession(context, packageInstaller, sessionId)
}
private val TAG = InstallerSession::class.java.simpleName
}
}