/* * Copyright © 2014-2021 The Android Password Store Authors. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0 */ package me.msfjarvis.openpgpktx.util import android.content.ComponentName import android.content.Context import android.content.Intent import android.content.ServiceConnection import android.os.IBinder import org.openintents.openpgp.IOpenPgpService2 public class OpenPgpServiceConnection(context: Context, providerPackageName: String?) { // callback interface public interface OnBound { public fun onBound(service: IOpenPgpService2) public fun onError(e: Exception) } private val mApplicationContext: Context = context.applicationContext public var service: IOpenPgpService2? = null private set private val mProviderPackageName: String? = providerPackageName private var mOnBoundListener: OnBound? = null /** * Create new connection with callback * * @param context * @param providerPackageName specify package name of OpenPGP provider, e.g., * "org.sufficientlysecure.keychain" * @param onBoundListener callback, executed when connection to service has been established */ public constructor( context: Context, providerPackageName: String?, onBoundListener: OnBound? ) : this(context, providerPackageName) { mOnBoundListener = onBoundListener } public val isBound: Boolean get() = service != null private val mServiceConnection: ServiceConnection = object : ServiceConnection { override fun onServiceConnected(name: ComponentName, service: IBinder) { this@OpenPgpServiceConnection.service = IOpenPgpService2.Stub.asInterface(service) mOnBoundListener?.onBound(this@OpenPgpServiceConnection.service!!) } override fun onServiceDisconnected(name: ComponentName) { service = null } } /** If not already bound, bind to service! */ public fun bindToService() { if (service == null) { // if not already bound... try { val serviceIntent = Intent(OpenPgpApi.SERVICE_INTENT_2) // NOTE: setPackage is very important to restrict the intent to this provider only! serviceIntent.setPackage(mProviderPackageName) val connect = mApplicationContext.bindService( serviceIntent, mServiceConnection, Context.BIND_AUTO_CREATE ) if (!connect) { throw Exception("bindService() returned false!") } } catch (e: Exception) { mOnBoundListener?.onError(e) } } else { // already bound, but also inform client about it with callback mOnBoundListener?.onBound(service!!) } } public fun unbindFromService() { mApplicationContext.unbindService(mServiceConnection) } }