Revert "remove useless ThreadPoolExecutor in ServiceInstaller.kt" as it is needed for consistent and manageable ServiceConnection

This commit is contained in:
Konstantin Tuev
2021-06-17 20:52:27 +03:00
parent 014d3478f2
commit bcdfb2b8f7

View File

@@ -43,11 +43,11 @@ import java.util.concurrent.LinkedBlockingQueue
import java.util.concurrent.ThreadPoolExecutor import java.util.concurrent.ThreadPoolExecutor
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicBoolean import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicInteger
class ServiceInstaller(context: Context) : InstallerBase(context) { class ServiceInstaller(context: Context) : InstallerBase(context) {
private lateinit var serviceConnection: ServiceConnection private lateinit var serviceConnection: ServiceConnection
private val executor = ThreadPoolExecutor(0, 1, 30L, TimeUnit.SECONDS, LinkedBlockingQueue())
companion object { companion object {
const val ACTION_INSTALL_REPLACE_EXISTING = 2 const val ACTION_INSTALL_REPLACE_EXISTING = 2
@@ -97,227 +97,256 @@ class ServiceInstaller(context: Context) : InstallerBase(context) {
} }
override fun uninstall(packageName: String) { override fun uninstall(packageName: String) {
val attachedToServiceTimeout = AtomicBoolean(false) executor.execute {
val readyWithAction = AtomicBoolean(false)
AuroraApplication.enqueuedInstalls.add(packageName) Handler(Looper.getMainLooper()).post {
val serviceConnection = object : ServiceConnection {
serviceConnection = object : ServiceConnection { override fun onServiceConnected(name: ComponentName, binder: IBinder) {
override fun onServiceConnected(name: ComponentName, binder: IBinder) { if (isAlreadyQueued(packageName)) {
attachedToServiceTimeout.set(true) if (::serviceConnection.isInitialized) {
val service = IPrivilegedService.Stub.asInterface(binder) context.unbindService(serviceConnection)
}
if (service.hasPrivilegedPermissions()) { readyWithAction.set(true)
Log.i(context.getString(R.string.installer_service_available)) return
val callback = object : IPrivilegedCallback.Stub() {
override fun handleResult(packageName: String, returnCode: Int) {
} }
AuroraApplication.enqueuedInstalls.add(packageName)
val service = IPrivilegedService.Stub.asInterface(binder)
override fun handleResultX( if (service.hasPrivilegedPermissions()) {
packageName: String, Log.i(context.getString(R.string.installer_service_available))
returnCode: Int,
extra: String? val callback = object : IPrivilegedCallback.Stub() {
) {
override fun handleResult(packageName: String, returnCode: Int) {}
override fun handleResultX(
packageName: String,
returnCode: Int,
extra: String?
) {
removeFromInstallQueue(packageName)
handleCallbackUninstall(packageName, returnCode, extra)
readyWithAction.set(true)
}
}
try {
service.deletePackageX(
packageName,
2,
BuildConfig.APPLICATION_ID,
callback
)
} catch (e: RemoteException) {
Log.e("Failed to connect Aurora Services")
removeFromInstallQueue(packageName)
readyWithAction.set(true)
}
} else {
removeFromInstallQueue(packageName) removeFromInstallQueue(packageName)
handleCallbackUninstall(packageName, returnCode, extra) postError(
packageName,
context.getString(R.string.installer_status_failure),
context.getString(R.string.installer_service_misconfigured)
)
readyWithAction.set(true)
} }
} }
try { override fun onServiceDisconnected(name: ComponentName) {
service.deletePackageX(
packageName,
2,
BuildConfig.APPLICATION_ID,
callback
)
} catch (e: RemoteException) {
Log.e("Failed to connect Aurora Services")
removeFromInstallQueue(packageName) removeFromInstallQueue(packageName)
Log.e("Disconnected from Aurora Services")
readyWithAction.set(true)
} }
} else {
removeFromInstallQueue(packageName)
postError(
packageName,
context.getString(R.string.installer_status_failure),
context.getString(R.string.installer_service_misconfigured)
)
} }
}
override fun onServiceDisconnected(name: ComponentName) { val intent = Intent(PRIVILEGED_EXTENSION_SERVICE_INTENT)
removeFromInstallQueue(packageName) intent.setPackage(PRIVILEGED_EXTENSION_PACKAGE_NAME)
Log.e("Disconnected from Aurora Services")
context.bindService(
intent,
serviceConnection,
Context.BIND_AUTO_CREATE
)
}
while (!readyWithAction.get()) {
Thread.sleep(1000)
} }
} }
val intent = Intent(PRIVILEGED_EXTENSION_SERVICE_INTENT)
intent.setPackage(PRIVILEGED_EXTENSION_PACKAGE_NAME)
context.bindService(
intent,
serviceConnection,
Context.BIND_AUTO_CREATE
)
Handler(Looper.getMainLooper()).postDelayed({
if (!attachedToServiceTimeout.get()) {
removeFromInstallQueue(packageName)
}
}, 25 * 1000)
} }
@RequiresApi(Build.VERSION_CODES.LOLLIPOP) @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
private fun xInstall(packageName: String, uriList: List<Uri>, fileList: List<String>) { private fun xInstall(packageName: String, uriList: List<Uri>, fileList: List<String>) {
val attachedToServiceTimeout = AtomicBoolean(false) executor.execute {
val readyWithAction = AtomicBoolean(false)
AuroraApplication.enqueuedInstalls.add(packageName) Handler(Looper.getMainLooper()).post {
serviceConnection = object : ServiceConnection {
serviceConnection = object : ServiceConnection { override fun onServiceConnected(name: ComponentName, binder: IBinder) {
override fun onServiceConnected(name: ComponentName, binder: IBinder) { if (isAlreadyQueued(packageName)) {
attachedToServiceTimeout.set(true) if (::serviceConnection.isInitialized) {
val service = IPrivilegedService.Stub.asInterface(binder) context.unbindService(serviceConnection)
}
if (service.hasPrivilegedPermissions()) { readyWithAction.set(true)
Log.i(context.getString(R.string.installer_service_available)) return
val callback = object : IPrivilegedCallback.Stub() {
override fun handleResult(packageName: String, returnCode: Int) {
} }
AuroraApplication.enqueuedInstalls.add(packageName)
val service = IPrivilegedService.Stub.asInterface(binder)
override fun handleResultX( if (service.hasPrivilegedPermissions()) {
packageName: String, Log.i(context.getString(R.string.installer_service_available))
returnCode: Int,
extra: String? val callback = object : IPrivilegedCallback.Stub() {
) {
removeFromInstallQueue(packageName) override fun handleResult(packageName: String, returnCode: Int) {}
handleCallback(packageName, returnCode, extra)
} override fun handleResultX(
} packageName: String,
returnCode: Int,
extra: String?
) {
removeFromInstallQueue(packageName)
handleCallback(packageName, returnCode, extra)
readyWithAction.set(true)
}
}
try {
if (service.isMoreMethodImplemented) {
try { try {
service.installSplitPackageMore( if (service.isMoreMethodImplemented) {
packageName, try {
uriList, service.installSplitPackageMore(
ACTION_INSTALL_REPLACE_EXISTING, packageName,
BuildConfig.APPLICATION_ID, uriList,
callback, ACTION_INSTALL_REPLACE_EXISTING,
fileList BuildConfig.APPLICATION_ID,
) callback,
} catch (e: RemoteException) { fileList
removeFromInstallQueue(packageName) )
postError(packageName, e.localizedMessage, e.stackTraceToString()) } catch (e: RemoteException) {
removeFromInstallQueue(packageName)
postError(packageName, e.localizedMessage, e.stackTraceToString())
readyWithAction.set(true)
}
} else {
throw Exception("New method not implemented")
}
} catch (th: Throwable) {
th.printStackTrace()
try {
service.installSplitPackageX(
packageName,
uriList,
ACTION_INSTALL_REPLACE_EXISTING,
BuildConfig.APPLICATION_ID,
callback
)
} catch (e: RemoteException) {
removeFromInstallQueue(packageName)
postError(packageName, e.localizedMessage, e.stackTraceToString())
readyWithAction.set(true)
}
} }
} else { } else {
throw Exception("New method not implemented")
}
} catch (th: Throwable) {
th.printStackTrace()
try {
service.installSplitPackageX(
packageName,
uriList,
ACTION_INSTALL_REPLACE_EXISTING,
BuildConfig.APPLICATION_ID,
callback
)
} catch (e: RemoteException) {
removeFromInstallQueue(packageName) removeFromInstallQueue(packageName)
postError(packageName, e.localizedMessage, e.stackTraceToString()) postError(
packageName,
context.getString(R.string.installer_status_failure),
context.getString(R.string.installer_service_misconfigured)
)
readyWithAction.set(true)
} }
} }
} else {
removeFromInstallQueue(packageName) override fun onServiceDisconnected(name: ComponentName) {
postError( removeFromInstallQueue(packageName)
packageName, readyWithAction.set(true)
context.getString(R.string.installer_status_failure), Log.e("Disconnected from Aurora Services")
context.getString(R.string.installer_service_misconfigured) }
)
} }
}
override fun onServiceDisconnected(name: ComponentName) { val intent = Intent(PRIVILEGED_EXTENSION_SERVICE_INTENT)
removeFromInstallQueue(packageName) intent.setPackage(PRIVILEGED_EXTENSION_PACKAGE_NAME)
Log.e("Disconnected from Aurora Services")
context.bindService(
intent,
serviceConnection,
Context.BIND_AUTO_CREATE
)
} }
while (!readyWithAction.get()) {
Thread.sleep(1000)
}
Log.i("Services Callback : install wait done")
} }
val intent = Intent(PRIVILEGED_EXTENSION_SERVICE_INTENT)
intent.setPackage(PRIVILEGED_EXTENSION_PACKAGE_NAME)
context.bindService(
intent,
serviceConnection,
Context.BIND_AUTO_CREATE
)
Handler(Looper.getMainLooper()).postDelayed({
if (!attachedToServiceTimeout.get()) {
removeFromInstallQueue(packageName)
}
}, 25 * 1000)
} }
private fun handleCallbackUninstall(packageName: String, returnCode: Int, extra: String?) { private fun handleCallbackUninstall(packageName: String, returnCode: Int, extra: String?) {
Log.i("Services Callback : $packageName $returnCode $extra") Log.i("Services Callback : $packageName $returnCode $extra")
when (returnCode) { try {
PackageInstaller.STATUS_SUCCESS -> { when (returnCode) {
EventBus.getDefault().post( PackageInstaller.STATUS_SUCCESS -> {
BusEvent.UninstallEvent( EventBus.getDefault().post(
packageName, BusEvent.UninstallEvent(
context.getString(R.string.installer_status_success) packageName,
context.getString(R.string.installer_status_success)
)
)
}
else -> {
val error = AppInstaller.getErrorString(
context,
returnCode
) )
)
}
else -> {
val error = AppInstaller.getErrorString(
context,
returnCode
)
postError(packageName, error, extra) postError(packageName, error, extra)
}
} }
} if (::serviceConnection.isInitialized) {
if (::serviceConnection.isInitialized) { context.unbindService(serviceConnection)
context.unbindService(serviceConnection) }
} catch (th: Throwable) {
th.printStackTrace()
} }
} }
private fun handleCallback(packageName: String, returnCode: Int, extra: String?) { private fun handleCallback(packageName: String, returnCode: Int, extra: String?) {
Log.i("Services Callback : $packageName $returnCode $extra") Log.i("Services Callback : $packageName $returnCode $extra")
when (returnCode) { try {
PackageInstaller.STATUS_SUCCESS -> { when (returnCode) {
EventBus.getDefault().post( PackageInstaller.STATUS_SUCCESS -> {
InstallerEvent.Success( EventBus.getDefault().post(
packageName, InstallerEvent.Success(
context.getString(R.string.installer_status_success) packageName,
context.getString(R.string.installer_status_success)
)
)
}
else -> {
val error = AppInstaller.getErrorString(
context,
returnCode
) )
)
}
else -> {
val error = AppInstaller.getErrorString(
context,
returnCode
)
postError(packageName, error, extra) postError(packageName, error, extra)
}
} }
} if (::serviceConnection.isInitialized) {
if (::serviceConnection.isInitialized) { context.unbindService(serviceConnection)
context.unbindService(serviceConnection) }
} catch (th: Throwable) {
th.printStackTrace()
} }
} }
override fun postError(packageName: String, error: String?, extra: String?) { override fun postError(packageName: String, error: String?, extra: String?) {
super.postError(packageName, error, extra) try {
if (::serviceConnection.isInitialized) { super.postError(packageName, error, extra)
context.unbindService(serviceConnection) if (::serviceConnection.isInitialized) {
context.unbindService(serviceConnection)
}
} catch (th: Throwable) {
th.printStackTrace()
} }
} }