blob: 0f29c62e24e36f728e5f237c2aa8a3fc799666df [file] [log] [blame]
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.connecteddevice.transport
import com.google.android.connecteddevice.util.SafeLog.logd
/** Delegate for registering protocols to the platform. */
class ProtocolDelegate : IProtocolDelegate.Stub() {
private val _protocols = mutableListOf<IConnectionProtocol>()
/** The list of currently attached [IConnectionProtocol]s. */
val protocols: List<IConnectionProtocol>
get() {
scrubDeadProtocols(_protocols)
return _protocols
}
private val _oobProtocols = mutableListOf<IConnectionProtocol>()
/** Protocols that support OOB data exchange. */
val oobProtocols: List<IConnectionProtocol>
get() {
scrubDeadProtocols(_oobProtocols)
return _oobProtocols
}
/** `true` if there are currently no general transport protocols attached. `false` otherwise. */
val isEmpty: Boolean
get() = protocols.isEmpty()
/** `true` if there is at least one protocol currently attached. `false` otherwise. */
val isNotEmpty: Boolean
get() = protocols.isNotEmpty()
/** Callback registered for protocol changes. */
var callback: Callback? = null
override fun addOobProtocol(protocol: IConnectionProtocol) {
_oobProtocols.add(protocol)
logd(
TAG,
"Added a new OOB protocol. There are now ${oobProtocols.size} attached OOB " + "protocols."
)
}
override fun removeOobProtocol(protocol: IConnectionProtocol) {
scrubDeadProtocols(_oobProtocols)
_oobProtocols.removeAll { it.asBinder() == protocol.asBinder() }
logd(
TAG,
"Removed a OOB protocol. There are ${oobProtocols.size} remaining OOB attached " +
"protocols."
)
}
override fun addProtocol(protocol: IConnectionProtocol) {
_protocols.add(protocol)
logd(TAG, "Added a new protocol. There are now ${protocols.size} attached protocols.")
callback?.onProtocolAdded(protocol)
}
override fun removeProtocol(protocol: IConnectionProtocol) {
scrubDeadProtocols(_protocols)
if (!_protocols.removeAll { it.asBinder() == protocol.asBinder() }) {
return
}
logd(TAG, "Removed a protocol. There are ${protocols.size} remaining attached protocols.")
callback?.onProtocolRemoved(protocol)
}
private fun scrubDeadProtocols(protocols: MutableList<IConnectionProtocol>) =
protocols.removeAll {
val isNotAlive = !it.asBinder().isBinderAlive
if (isNotAlive) {
callback?.onProtocolRemoved(it)
}
isNotAlive
}
/** Callback to be invoked for protocol changes. */
interface Callback {
/** Invoked when a protocol has been added. */
fun onProtocolAdded(protocol: IConnectionProtocol)
/** Invoked when a protocol has been removed. */
fun onProtocolRemoved(protocol: IConnectionProtocol)
}
companion object {
private const val TAG = "ProtocolDelegate"
}
}