Initial commit for connectivity.
Bug: 290265761
Bug: 291146480
Bug: 290275468
Test: None
Change-Id: Iaba64415cf81454b6e999f10bad54810884fc3da
diff --git a/remoteauth/README.md b/remoteauth/README.md
index 384fcf7..f28154d 100644
--- a/remoteauth/README.md
+++ b/remoteauth/README.md
@@ -23,7 +23,6 @@
### AIDEGen
-AIDEGen is deprecated, prefer ASfP [go/asfp](http://go/asfp)
```sh
$ source build/envsetup.sh && lunch <TARGET>
$ cd packages/modules/Connectivity
@@ -31,17 +30,13 @@
# This will launch Intellij project for RemoteAuth module.
```
-### ASfP
-
-See full instructions for ASfP at [go/asfp-getting-started](http://go/asfp-getting-started)
-
## Build and Install
```sh
$ source build/envsetup.sh && lunch <TARGET>
-$ m com.google.android.tethering deapexer
+$ m com.android.tethering deapexer
$ $ANDROID_BUILD_TOP/out/host/linux-x86/bin/deapexer decompress --input \
- ${ANDROID_PRODUCT_OUT}/system/apex/com.google.android.tethering.capex \
+ ${ANDROID_PRODUCT_OUT}/system/apex/com.android.tethering.capex \
--output /tmp/tethering.apex
$ adb install -r /tmp/tethering.apex
```
diff --git a/remoteauth/service/java/com/android/server/remoteauth/README.md b/remoteauth/service/java/com/android/server/remoteauth/README.md
index 423ab45..2f8b096 100644
--- a/remoteauth/service/java/com/android/server/remoteauth/README.md
+++ b/remoteauth/service/java/com/android/server/remoteauth/README.md
@@ -1 +1,4 @@
-This is the source root for the RemoteAuthService
\ No newline at end of file
+This is the source root for the RemoteAuthService
+
+## Remote connectivity manager
+Provides the connectivity manager to manage connections with the peer device.
diff --git a/remoteauth/service/java/com/android/server/remoteauth/connectivity/CdmConnectionInfo.java b/remoteauth/service/java/com/android/server/remoteauth/connectivity/CdmConnectionInfo.java
new file mode 100644
index 0000000..8bfdd36
--- /dev/null
+++ b/remoteauth/service/java/com/android/server/remoteauth/connectivity/CdmConnectionInfo.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2023 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.android.server.remoteauth.connectivity;
+
+import android.annotation.NonNull;
+import android.annotation.TargetApi;
+import android.companion.AssociationInfo;
+import android.os.Build;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/**
+ * Encapsulates the connection information for companion device manager connections.
+ *
+ * <p>Connection information captures the details of underlying connection such as connection id,
+ * type of connection and peer device mac address.
+ */
+// TODO(b/295407748): Change to use @DataClass.
+// TODO(b/296625303): Change to VANILLA_ICE_CREAM when AssociationInfo is available in V.
+@TargetApi(Build.VERSION_CODES.TIRAMISU)
+public final class CdmConnectionInfo extends ConnectionInfo {
+ @NonNull private final AssociationInfo mAssociationInfo;
+
+ public CdmConnectionInfo(int connectionId, @NonNull AssociationInfo associationInfo) {
+ super(connectionId);
+ mAssociationInfo = associationInfo;
+ }
+
+ private CdmConnectionInfo(@NonNull Parcel in) {
+ super(in);
+ mAssociationInfo = in.readTypedObject(AssociationInfo.CREATOR);
+ }
+
+ /** Used to read CdmConnectionInfo from a Parcel */
+ @NonNull
+ public static final Parcelable.Creator<CdmConnectionInfo> CREATOR =
+ new Parcelable.Creator<CdmConnectionInfo>() {
+ public CdmConnectionInfo createFromParcel(@NonNull Parcel in) {
+ return new CdmConnectionInfo(in);
+ }
+
+ public CdmConnectionInfo[] newArray(int size) {
+ return new CdmConnectionInfo[size];
+ }
+ };
+
+ /** No special parcel contents. */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /**
+ * Flatten this CdmConnectionInfo in to a Parcel.
+ *
+ * @param out The Parcel in which the object should be written.
+ * @param flags Additional flags about how the object should be written.
+ */
+ @Override
+ public void writeToParcel(@NonNull Parcel out, int flags) {
+ super.writeToParcel(out, flags);
+ out.writeTypedObject(mAssociationInfo, 0);
+ }
+
+ public AssociationInfo getAssociationInfo() {
+ return mAssociationInfo;
+ }
+
+ /** Returns a string representation of ConnectionInfo. */
+ @Override
+ public String toString() {
+ return super.toString();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == null || !(o instanceof CdmConnectionInfo)) {
+ return false;
+ }
+ if (!super.equals(o)) {
+ return false;
+ }
+
+ CdmConnectionInfo other = (CdmConnectionInfo) o;
+ return mAssociationInfo.equals(other.getAssociationInfo());
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mAssociationInfo);
+ }
+}
diff --git a/remoteauth/service/java/com/android/server/remoteauth/connectivity/Connection.java b/remoteauth/service/java/com/android/server/remoteauth/connectivity/Connection.java
new file mode 100644
index 0000000..eb5458d
--- /dev/null
+++ b/remoteauth/service/java/com/android/server/remoteauth/connectivity/Connection.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2023 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.android.server.remoteauth.connectivity;
+
+import android.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * A connection with the peer device.
+ *
+ * <p>Connections are used to exchange data with the peer device.
+ *
+ */
+public interface Connection {
+ /** Unknown error. */
+ int ERROR_UNKNOWN = 0;
+
+ /** Message was sent successfully. */
+ int ERROR_OK = 1;
+
+ /** Timeout occurred while waiting for response from the peer. */
+ int ERROR_DEADLINE_EXCEEDED = 2;
+
+ /** Device became unavailable while sending the message. */
+ int ERROR_DEVICE_UNAVAILABLE = 3;
+
+ /** Represents error code. */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({ERROR_UNKNOWN, ERROR_OK, ERROR_DEADLINE_EXCEEDED, ERROR_DEVICE_UNAVAILABLE})
+ @interface ErrorCode {}
+
+ /**
+ * Callback for clients to get the response of sendRequest. {@link onSuccess} is called if the
+ * peer device responds with Status::OK, otherwise runs the {@link onFailure} callback.
+ */
+ abstract class MessageResponseCallback {
+ /**
+ * Called on a success.
+ *
+ * @param buffer response from the device.
+ */
+ public void onSuccess(byte[] buffer) {}
+
+ /**
+ * Called when message sending fails.
+ *
+ * @param errorCode indicating the error.
+ */
+ public void onFailure(@ErrorCode int errorCode) {}
+ }
+
+ /**
+ * Sends a request to the peer.
+ *
+ * @param request byte array to be sent to the peer device.
+ * @param messageResponseCallback callback to be run when the peer response is received or if an
+ * error occurred.
+ */
+ void sendRequest(byte[] request, MessageResponseCallback messageResponseCallback);
+
+ /** Triggers a disconnect from the peer device. */
+ void disconnect();
+
+ /**
+ * Returns the connection information.
+ *
+ * @return A connection information object.
+ */
+ ConnectionInfo getConnectionInfo();
+}
diff --git a/remoteauth/service/java/com/android/server/remoteauth/connectivity/ConnectionException.java b/remoteauth/service/java/com/android/server/remoteauth/connectivity/ConnectionException.java
new file mode 100644
index 0000000..a8c7860
--- /dev/null
+++ b/remoteauth/service/java/com/android/server/remoteauth/connectivity/ConnectionException.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2023 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.android.server.remoteauth.connectivity;
+
+import static com.android.server.remoteauth.connectivity.ConnectivityManager.ReasonCode;
+
+import android.annotation.Nullable;
+
+/** Exception that signals that the connection request failed. */
+public final class ConnectionException extends RuntimeException {
+ private final @ReasonCode int mReasonCode;
+
+ public ConnectionException(@ReasonCode int reasonCode) {
+ super();
+ this.mReasonCode = reasonCode;
+ }
+
+ public ConnectionException(@ReasonCode int reasonCode, @Nullable String message) {
+ super(message);
+ this.mReasonCode = reasonCode;
+ }
+
+ public ConnectionException(@ReasonCode int reasonCode, @Nullable Throwable cause) {
+ super(cause);
+ this.mReasonCode = reasonCode;
+ }
+
+ public ConnectionException(
+ @ReasonCode int reasonCode, @Nullable String message, @Nullable Throwable cause) {
+ super(message, cause);
+ this.mReasonCode = reasonCode;
+ }
+
+ public @ReasonCode int getReasonCode() {
+ return this.mReasonCode;
+ }
+
+ @Override
+ public String getMessage() {
+ return super.getMessage() + " Reason code: " + this.mReasonCode;
+ }
+}
diff --git a/remoteauth/service/java/com/android/server/remoteauth/connectivity/ConnectionInfo.java b/remoteauth/service/java/com/android/server/remoteauth/connectivity/ConnectionInfo.java
new file mode 100644
index 0000000..39bfa8d
--- /dev/null
+++ b/remoteauth/service/java/com/android/server/remoteauth/connectivity/ConnectionInfo.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2023 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.android.server.remoteauth.connectivity;
+
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/**
+ * Encapsulates the connection information.
+ *
+ * <p>Connection information captures the details of underlying connection such as connection id,
+ * type of connection and peer device mac address.
+ *
+ */
+// TODO(b/295407748) Change to use @DataClass.
+public abstract class ConnectionInfo implements Parcelable {
+ int mConnectionId;
+
+ public ConnectionInfo(int connectionId) {
+ mConnectionId = connectionId;
+ }
+
+ /** Create object from Parcel */
+ public ConnectionInfo(@NonNull Parcel in) {
+ mConnectionId = in.readInt();
+ }
+
+ public int getConnectionId() {
+ return mConnectionId;
+ }
+
+ /** No special parcel contents. */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /**
+ * Flattens this ConnectionInfo in to a Parcel.
+ *
+ * @param out The Parcel in which the object should be written.
+ * @param flags Additional flags about how the object should be written.
+ */
+ @Override
+ public void writeToParcel(@NonNull Parcel out, int flags) {
+ out.writeInt(mConnectionId);
+ }
+
+ /** Returns string representation of ConnectionInfo. */
+ @Override
+ public String toString() {
+ return "ConnectionInfo[" + "connectionId= " + mConnectionId + "]";
+ }
+
+ /** Returns true if this ConnectionInfo object is equal to the other. */
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof ConnectionInfo)) {
+ return false;
+ }
+
+ ConnectionInfo other = (ConnectionInfo) o;
+ return mConnectionId == other.getConnectionId();
+ }
+
+ /** Returns the hashcode of this object */
+ @Override
+ public int hashCode() {
+ return Objects.hash(mConnectionId);
+ }
+}
diff --git a/remoteauth/service/java/com/android/server/remoteauth/connectivity/ConnectivityManager.java b/remoteauth/service/java/com/android/server/remoteauth/connectivity/ConnectivityManager.java
new file mode 100644
index 0000000..bc0d77e
--- /dev/null
+++ b/remoteauth/service/java/com/android/server/remoteauth/connectivity/ConnectivityManager.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2023 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.android.server.remoteauth.connectivity;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Performs discovery and triggers a connection to an associated device.
+ */
+public interface ConnectivityManager {
+ /**
+ * Starts device discovery.
+ *
+ * <p>Discovery continues until stopped using {@link stopDiscovery} or times out.
+ *
+ * @param discoveryFilter to filter for devices during discovery.
+ * @param discoveredDeviceReceiver callback to run when device is found or lost.
+ */
+ void startDiscovery(
+ @NonNull DiscoveryFilter discoveryFilter,
+ @NonNull DiscoveredDeviceReceiver discoveredDeviceReceiver);
+
+ /**
+ * Stops device discovery.
+ *
+ * @param discoveryFilter filter used to start discovery.
+ * @param discoveredDeviceReceiver callback passed with startDiscovery.
+ */
+ void stopDiscovery(
+ @NonNull DiscoveryFilter discoveryFilter,
+ @NonNull DiscoveredDeviceReceiver discoveredDeviceReceiver);
+
+ /** Unknown reason for connection failure. */
+ int ERROR_REASON_UNKNOWN = 0;
+
+ /** Indicates that the connection request timed out. */
+ int ERROR_CONNECTION_TIMED_OUT = 1;
+
+ /** Indicates that the connection request was refused by the peer. */
+ int ERROR_CONNECTION_REFUSED = 2;
+
+ /** Indicates that the peer device was unavailable. */
+ int ERROR_DEVICE_UNAVAILABLE = 3;
+
+ /** Reason codes for connect failure. */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({ERROR_REASON_UNKNOWN, ERROR_CONNECTION_TIMED_OUT, ERROR_CONNECTION_REFUSED,
+ ERROR_DEVICE_UNAVAILABLE})
+ @interface ReasonCode {}
+
+ /**
+ * Initiates a connection with the peer device.
+ *
+ * @param connectionInfo of the device discovered using {@link startDiscovery}.
+ * @param eventListener to listen for events from the underlying transport.
+ * @return {@link Connection} object or null connection is not established.
+ * @throws ConnectionException in case connection cannot be established.
+ */
+ @Nullable
+ Connection connect(
+ @NonNull ConnectionInfo connectionInfo, @NonNull EventListener eventListener);
+
+ /**
+ * Message received callback.
+ *
+ * <p>Clients should implement this callback to receive messages from the peer device.
+ */
+ abstract class MessageReceiver {
+ /**
+ * Receive message from the peer device.
+ *
+ * <p>Clients can set empty buffer as an ACK to the request.
+ *
+ * @param messageIn message from peer device.
+ * @param responseCallback {@link ResponseCallback} callback to send the response back.
+ */
+ public void onMessageReceived(byte[] messageIn, ResponseCallback responseCallback) {}
+ }
+
+ /**
+ * Starts listening for incoming messages.
+ *
+ * <p>Runs MessageReceiver callback when a message is received.
+ *
+ * @param messageReceiver to receive messages.
+ * @throws AssertionError if a listener is already configured.
+ */
+ void startListening(MessageReceiver messageReceiver);
+
+ /**
+ * Stops listening to incoming messages.
+ *
+ * @param messageReceiver to receive messages.
+ */
+ void stopListening(MessageReceiver messageReceiver);
+}
diff --git a/remoteauth/service/java/com/android/server/remoteauth/connectivity/DiscoveredDevice.java b/remoteauth/service/java/com/android/server/remoteauth/connectivity/DiscoveredDevice.java
new file mode 100644
index 0000000..a3e1e58
--- /dev/null
+++ b/remoteauth/service/java/com/android/server/remoteauth/connectivity/DiscoveredDevice.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2023 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.android.server.remoteauth.connectivity;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import java.util.Objects;
+
+/** Device discovered on a network interface like Bluetooth. */
+public final class DiscoveredDevice {
+ private @NonNull ConnectionInfo mConnectionInfo;
+ private @Nullable String mDisplayName;
+
+ public DiscoveredDevice(
+ @NonNull ConnectionInfo connectionInfo, @Nullable String displayName) {
+ this.mConnectionInfo = connectionInfo;
+ this.mDisplayName = displayName;
+ }
+
+ /**
+ * Returns connection information.
+ *
+ * @return connection information.
+ */
+ @NonNull
+ public ConnectionInfo getConnectionInfo() {
+ return this.mConnectionInfo;
+ }
+
+ /**
+ * Returns display name of the device.
+ *
+ * @return display name string.
+ */
+ @Nullable
+ public String getDisplayName() {
+ return this.mDisplayName;
+ }
+
+ /**
+ * Checks for equality between this and other object.
+ *
+ * @return true if equal, false otherwise.
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof DiscoveredDevice)) {
+ return false;
+ }
+
+ DiscoveredDevice other = (DiscoveredDevice) o;
+ return mConnectionInfo.equals(other.getConnectionInfo())
+ && mDisplayName.equals(other.getDisplayName());
+ }
+
+ /**
+ * Returns hash code of the object.
+ *
+ * @return hash code.
+ */
+ @Override
+ public int hashCode() {
+ return Objects.hash(mDisplayName, mConnectionInfo.getConnectionId());
+ }
+}
diff --git a/remoteauth/service/java/com/android/server/remoteauth/connectivity/DiscoveredDeviceReceiver.java b/remoteauth/service/java/com/android/server/remoteauth/connectivity/DiscoveredDeviceReceiver.java
new file mode 100644
index 0000000..90a3e30
--- /dev/null
+++ b/remoteauth/service/java/com/android/server/remoteauth/connectivity/DiscoveredDeviceReceiver.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2023 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.android.server.remoteauth.connectivity;
+
+/** Callbacks triggered on discovery. */
+public abstract class DiscoveredDeviceReceiver {
+ /**
+ * Callback called when a device matching the discovery filter is found.
+ *
+ * @param discoveredDevice the discovered device.
+ */
+ public void onDiscovered(DiscoveredDevice discoveredDevice) {}
+
+ /**
+ * Callback called when a previously discovered device using {@link
+ * ConnectivityManager#startDiscovery} is lost.
+ *
+ * @param discoveredDevice the lost device
+ */
+ public void onLost(DiscoveredDevice discoveredDevice) {}
+}
diff --git a/remoteauth/service/java/com/android/server/remoteauth/connectivity/DiscoveryFilter.java b/remoteauth/service/java/com/android/server/remoteauth/connectivity/DiscoveryFilter.java
new file mode 100644
index 0000000..36c4b60
--- /dev/null
+++ b/remoteauth/service/java/com/android/server/remoteauth/connectivity/DiscoveryFilter.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2023 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.android.server.remoteauth.connectivity;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Filter for device discovery.
+ *
+ * <p>Callers can use this class to provide a discovery filter to the {@link
+ * ConnectivityManager.startDiscovery} method. A device is discovered if it matches at least one of
+ * the filter criteria (device type, name or peer address).
+ */
+public final class DiscoveryFilter {
+
+ /** Device type WATCH. */
+ public static final int WATCH = 0;
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({WATCH})
+ public @interface DeviceType {}
+
+ private @DeviceType int mDeviceType;
+ private final @Nullable String mDeviceName;
+ private final @Nullable String mPeerAddress;
+
+ public DiscoveryFilter(
+ @DeviceType int deviceType, @Nullable String deviceName, @Nullable String peerAddress) {
+ this.mDeviceType = deviceType;
+ this.mDeviceName = deviceName;
+ this.mPeerAddress = peerAddress;
+ }
+
+ /**
+ * Returns device type.
+ *
+ * @return device type.
+ */
+ public @DeviceType int getDeviceType() {
+ return this.mDeviceType;
+ }
+
+ /**
+ * Returns device name.
+ *
+ * @return device name.
+ */
+ public @Nullable String getDeviceName() {
+ return this.mDeviceName;
+ }
+
+ /**
+ * Returns mac address of the peer device .
+ *
+ * @return mac address string.
+ */
+ public @Nullable String getPeerAddress() {
+ return this.mPeerAddress;
+ }
+
+ /** Builder for {@link DiscoverFilter} */
+ public static class Builder {
+ private @DeviceType int mDeviceType;
+ private @Nullable String mDeviceName;
+ private @Nullable String mPeerAddress;
+
+ private Builder() {}
+
+ /** Static method to create a new builder */
+ public static Builder newInstance() {
+ return new Builder();
+ }
+
+ /**
+ * Sets the device type of the DiscoveryFilter.
+ *
+ * @param deviceType of the peer device.
+ */
+ @NonNull
+ public Builder setDeviceType(@DeviceType int deviceType) {
+ mDeviceType = deviceType;
+ return this;
+ }
+
+ /**
+ * Sets the device name.
+ *
+ * @param deviceName May be null.
+ */
+ @NonNull
+ public Builder setDeviceName(String deviceName) {
+ mDeviceName = deviceName;
+ return this;
+ }
+
+ /**
+ * Sets the peer address.
+ *
+ * @param peerAddress Mac address of the peer device.
+ */
+ @NonNull
+ public Builder setPeerAddress(String peerAddress) {
+ mPeerAddress = peerAddress;
+ return this;
+ }
+
+ /** Builds the DiscoveryFilter object. */
+ @NonNull
+ public DiscoveryFilter build() {
+ return new DiscoveryFilter(this.mDeviceType, this.mDeviceName, this.mPeerAddress);
+ }
+ }
+}
diff --git a/remoteauth/service/java/com/android/server/remoteauth/connectivity/EventListener.java b/remoteauth/service/java/com/android/server/remoteauth/connectivity/EventListener.java
new file mode 100644
index 0000000..d07adb1
--- /dev/null
+++ b/remoteauth/service/java/com/android/server/remoteauth/connectivity/EventListener.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2023 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.android.server.remoteauth.connectivity;
+
+import android.annotation.NonNull;
+
+/**
+ * Listens to the events from underlying transport.
+ */
+interface EventListener {
+ /** Called when remote device is disconnected from the underlying transport. */
+ void onDisconnect(@NonNull ConnectionInfo connectionInfo);
+}
diff --git a/remoteauth/service/java/com/android/server/remoteauth/connectivity/ResponseCallback.java b/remoteauth/service/java/com/android/server/remoteauth/connectivity/ResponseCallback.java
new file mode 100644
index 0000000..8a09ab3
--- /dev/null
+++ b/remoteauth/service/java/com/android/server/remoteauth/connectivity/ResponseCallback.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2023 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.android.server.remoteauth.connectivity;
+
+import android.annotation.NonNull;
+
+/**
+ * Abstract class to expose a callback for clients to send a response to the peer device.
+ *
+ * <p>When a device receives a message on a connection, this object is constructed using the
+ * connection information of the connection and the message id from the incoming message. This
+ * object is forwarded to the clients of the connection to allow them to send a response to the peer
+ * device.
+ */
+public abstract class ResponseCallback {
+ private final long mMessageId;
+ private final ConnectionInfo mConnectionInfo;
+
+ public ResponseCallback(long messageId, @NonNull ConnectionInfo connectionInfo) {
+ mMessageId = messageId;
+ mConnectionInfo = connectionInfo;
+ }
+
+ /**
+ * Returns message id identifying the message.
+ *
+ * @return message id of this message.
+ */
+ public long getMessageId() {
+ return mMessageId;
+ }
+
+ /**
+ * Returns connection info from the response.
+ *
+ * @return connection info.
+ */
+ @NonNull
+ public ConnectionInfo getConnectionInfo() {
+ return mConnectionInfo;
+ }
+
+ /**
+ * Callback to send a response to the peer device.
+ *
+ * @param response buffer to send to the peer device.
+ */
+ public void onResponse(@NonNull byte[] response) {}
+}