summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author maheshkkv <maheshkkv@google.com> 2024-11-08 11:02:11 -0800
committer maheshkkv <maheshkkv@google.com> 2024-11-22 08:56:27 -0800
commit04d2edc4feeac84fe0de33633263fafbdfb665e7 (patch)
tree0db3431fe70e1bbcba1ef87787108a6f46df4003
parentdf7a809ff77014aa24c753d6baf7b9350af0ac40 (diff)
Add USD publish and subscribe APIs
Flag: android.net.wifi.flags.usd Bug: 340878198 Test: atest FrameworksWifiApiTests Change-Id: Iee93c15a8914fcd9fb4ae9fb06112ed9c96e453b
-rw-r--r--framework/aidl-export/android/net/wifi/usd/PublishConfig.aidl19
-rw-r--r--framework/aidl-export/android/net/wifi/usd/SubscribeConfig.aidl19
-rw-r--r--framework/api/system-current.txt2
-rw-r--r--framework/java/android/net/wifi/usd/IPublishSessionCallback.aidl30
-rw-r--r--framework/java/android/net/wifi/usd/ISubscribeSessionCallback.aidl30
-rw-r--r--framework/java/android/net/wifi/usd/IUsdManager.aidl6
-rw-r--r--framework/java/android/net/wifi/usd/UsdManager.java186
-rw-r--r--service/java/com/android/server/wifi/usd/UsdServiceImpl.java34
8 files changed, 325 insertions, 1 deletions
diff --git a/framework/aidl-export/android/net/wifi/usd/PublishConfig.aidl b/framework/aidl-export/android/net/wifi/usd/PublishConfig.aidl
new file mode 100644
index 0000000000..80e5421eab
--- /dev/null
+++ b/framework/aidl-export/android/net/wifi/usd/PublishConfig.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2024, 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 android.net.wifi.usd;
+
+parcelable PublishConfig;
diff --git a/framework/aidl-export/android/net/wifi/usd/SubscribeConfig.aidl b/framework/aidl-export/android/net/wifi/usd/SubscribeConfig.aidl
new file mode 100644
index 0000000000..71a168423b
--- /dev/null
+++ b/framework/aidl-export/android/net/wifi/usd/SubscribeConfig.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2024, 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 android.net.wifi.usd;
+
+parcelable SubscribeConfig;
diff --git a/framework/api/system-current.txt b/framework/api/system-current.txt
index b44a7a5433..75eb99a950 100644
--- a/framework/api/system-current.txt
+++ b/framework/api/system-current.txt
@@ -1976,7 +1976,9 @@ package android.net.wifi.usd {
method @RequiresPermission(android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION) public boolean isPublisherSupported();
method @RequiresPermission(android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION) public boolean isSubscriberAvailable();
method @RequiresPermission(android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION) public boolean isSubscriberSupported();
+ method @RequiresPermission(android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION) public void publish(@NonNull android.net.wifi.usd.PublishConfig, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.usd.PublishSessionCallback);
method @RequiresPermission(android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION) public void registerAvailabilityCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.usd.UsdManager.AvailabilityCallback);
+ method @RequiresPermission(android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION) public void subscribe(@NonNull android.net.wifi.usd.SubscribeConfig, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.usd.SubscribeSessionCallback);
method @RequiresPermission(android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION) public void unregisterAvailabilityCallback(@NonNull android.net.wifi.usd.UsdManager.AvailabilityCallback);
}
diff --git a/framework/java/android/net/wifi/usd/IPublishSessionCallback.aidl b/framework/java/android/net/wifi/usd/IPublishSessionCallback.aidl
new file mode 100644
index 0000000000..5037085644
--- /dev/null
+++ b/framework/java/android/net/wifi/usd/IPublishSessionCallback.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2024 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 android.net.wifi.usd;
+
+/**
+ * Interface for USD publish session callback.
+ *
+ * @hide
+ */
+oneway interface IPublishSessionCallback {
+ void onPublishFailed(int reasonCode);
+ void onPublishStarted(int sessionId);
+ void onPublishReplied(int peerId, in byte[] ssi, int protoType, boolean isFsdEnabled);
+ void onPublishSessionTerminated(int reasonCode);
+ void onMessageReceived(int peerId, in byte[] message);
+}
diff --git a/framework/java/android/net/wifi/usd/ISubscribeSessionCallback.aidl b/framework/java/android/net/wifi/usd/ISubscribeSessionCallback.aidl
new file mode 100644
index 0000000000..581d50dfeb
--- /dev/null
+++ b/framework/java/android/net/wifi/usd/ISubscribeSessionCallback.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2024 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 android.net.wifi.usd;
+
+/**
+ * Interface for USD subscribe session callback.
+ *
+ * @hide
+ */
+oneway interface ISubscribeSessionCallback {
+ void onSubscribeFailed(int reasonCode);
+ void onSubscribeStarted(int sessionId);
+ void onSubscribeDiscovered(int peerId, in byte[] ssi, int protoType, boolean isFsdEnabled);
+ void onSubscribeSessionTerminated(int reasonCode);
+ void onMessageReceived(int peerId, in byte[] message);
+}
diff --git a/framework/java/android/net/wifi/usd/IUsdManager.aidl b/framework/java/android/net/wifi/usd/IUsdManager.aidl
index 084b9d7948..f591639b0e 100644
--- a/framework/java/android/net/wifi/usd/IUsdManager.aidl
+++ b/framework/java/android/net/wifi/usd/IUsdManager.aidl
@@ -19,6 +19,10 @@ package android.net.wifi.usd;
import android.net.wifi.IBooleanListener;
import android.net.wifi.usd.Characteristics;
import android.net.wifi.usd.IAvailabilityCallback;
+import android.net.wifi.usd.IPublishSessionCallback;
+import android.net.wifi.usd.ISubscribeSessionCallback;
+import android.net.wifi.usd.PublishConfig;
+import android.net.wifi.usd.SubscribeConfig;
/**
* Interface that UsdService implements
@@ -37,4 +41,6 @@ interface IUsdManager {
void cancelSubscribe(int sessionId);
void cancelPublish(int sessionId);
void updatePublish(int sessionId, in byte[] ssi);
+ void publish(in PublishConfig publishConfig, IPublishSessionCallback callback);
+ void subscribe(in SubscribeConfig subscribeConfig, ISubscribeSessionCallback callback);
}
diff --git a/framework/java/android/net/wifi/usd/UsdManager.java b/framework/java/android/net/wifi/usd/UsdManager.java
index dd6654788f..fa762f2d2f 100644
--- a/framework/java/android/net/wifi/usd/UsdManager.java
+++ b/framework/java/android/net/wifi/usd/UsdManager.java
@@ -221,7 +221,6 @@ public class UsdManager {
Binder.clearCallingIdentity();
mExecutor.execute(mAvailabilityCallback::onPublisherAvailable);
}
-
}
/**
@@ -320,4 +319,189 @@ public class UsdManager {
throw e.rethrowFromSystemServer();
}
}
+
+ private static class PublishSessionCallbackProxy extends IPublishSessionCallback.Stub {
+ private final Executor mExecutor;
+ private final PublishSessionCallback mPublishSessionCallback;
+ private final UsdManager mUsdManager;
+
+ private PublishSessionCallbackProxy(UsdManager usdManager, Executor executor,
+ PublishSessionCallback publishSessionCallback) {
+ mUsdManager = usdManager;
+ mExecutor = executor;
+ mPublishSessionCallback = publishSessionCallback;
+ }
+
+ @Override
+ public void onPublishFailed(int reasonCode) throws RemoteException {
+ Log.d(TAG, "onPublishFailed (reasonCode = " + reasonCode + " )");
+ Binder.clearCallingIdentity();
+ mExecutor.execute(() -> mPublishSessionCallback.onPublishFailed(reasonCode));
+ }
+
+ @Override
+ public void onPublishStarted(int sessionId) throws RemoteException {
+ Log.d(TAG, "onPublishStarted ( sessionId = " + sessionId + " )");
+ Binder.clearCallingIdentity();
+ mExecutor.execute(() -> mPublishSessionCallback.onPublishStarted(
+ new PublishSession(mUsdManager, sessionId)));
+ }
+
+ @Override
+ public void onPublishReplied(int peerId, byte[] ssi, int protoType, boolean isFsdEnabled)
+ throws RemoteException {
+ Log.d(TAG, "onPublishReplied ( peerId = " + peerId + ", protoType = " + protoType
+ + ", isFsdEnabled = " + isFsdEnabled + " )");
+ Binder.clearCallingIdentity();
+ DiscoveryResult discoveryResult = new DiscoveryResult.Builder(peerId)
+ .setServiceSpecificInfo(ssi)
+ .setServiceProtoType(protoType)
+ .setFsdEnabled(isFsdEnabled)
+ .build();
+ mExecutor.execute(() -> mPublishSessionCallback.onPublishReplied(discoveryResult));
+ }
+
+ @Override
+ public void onPublishSessionTerminated(int reasonCode) throws RemoteException {
+ Log.d(TAG, "onPublishSessionTerminated ( reasonCode = " + reasonCode + " )");
+ Binder.clearCallingIdentity();
+ mExecutor.execute(() -> mPublishSessionCallback.onSessionTerminated(reasonCode));
+ }
+
+ @Override
+ public void onMessageReceived(int peerId, byte[] message) throws RemoteException {
+ Log.d(TAG, "onMessageReceived ( peerId = " + peerId + " )");
+ Binder.clearCallingIdentity();
+ mExecutor.execute(() -> mPublishSessionCallback.onMessageReceived(peerId, message));
+ }
+ }
+
+
+ /**
+ * Issue a request to the USD service to create a new publish session using the specified
+ * {@link PublishConfig} configuration. The result of the publish operation are routed to the
+ * callbacks of {@link PublishSessionCallback}.
+ *
+ * <p>Note: Maximum number of publish sessions are limited by
+ * {@link Characteristics#getMaxNumberOfPublishSessions()}.
+ *
+ * @param publishConfig The {@link PublishConfig} specifying the configuration of the
+ * requested publish session.
+ * @param executor The Executor on whose thread to execute the callbacks of the
+ * {@link PublishSessionCallback}
+ * @param publishSessionCallback A {@link PublishSessionCallback} object to be used for session
+ * event callback
+ */
+ @RequiresPermission(MANAGE_WIFI_NETWORK_SELECTION)
+ public void publish(@NonNull PublishConfig publishConfig,
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull PublishSessionCallback publishSessionCallback) {
+ Objects.requireNonNull(publishConfig, "publishConfig must not be null");
+ Objects.requireNonNull(executor, "executor must not be null");
+ Objects.requireNonNull(publishSessionCallback, "publishSessionCallback must not be null");
+ if (!Environment.isSdkAtLeastB()) {
+ throw new UnsupportedOperationException();
+ }
+ try {
+ PublishSessionCallbackProxy publishSessionCallbackProxy =
+ new PublishSessionCallbackProxy(this, executor, publishSessionCallback);
+ mService.publish(publishConfig, publishSessionCallbackProxy);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ private static class SubscribeSessionCallbackProxy extends ISubscribeSessionCallback.Stub {
+ private final UsdManager mUsdManager;
+ private final Executor mExecutor;
+ private final SubscribeSessionCallback mSubscribeSessionCallback;
+
+ private SubscribeSessionCallbackProxy(UsdManager usdManager, Executor executor,
+ SubscribeSessionCallback subscribeSessionCallback) {
+ mUsdManager = usdManager;
+ mExecutor = executor;
+ mSubscribeSessionCallback = subscribeSessionCallback;
+ }
+
+ @Override
+ public void onSubscribeFailed(int reasonCode) throws RemoteException {
+ Log.d(TAG, "onSubscribeFailed (reasonCode = " + reasonCode + " )");
+ Binder.clearCallingIdentity();
+ mExecutor.execute(() -> mSubscribeSessionCallback.onSubscribeFailed(reasonCode));
+ }
+
+ @Override
+ public void onSubscribeStarted(int sessionId) throws RemoteException {
+ Log.d(TAG, "onSubscribeStarted ( sessionId = " + sessionId + " )");
+ Binder.clearCallingIdentity();
+ mExecutor.execute(() -> mSubscribeSessionCallback.onSubscribeStarted(
+ new SubscribeSession(mUsdManager, sessionId)));
+ }
+
+ @Override
+ public void onSubscribeDiscovered(int peerId, byte[] ssi, int protoType,
+ boolean isFsdEnabled)
+ throws RemoteException {
+ Log.d(TAG, "onSubscribeDiscovered ( peerId = " + peerId + ", protoType = " + protoType
+ + ", isFsdEnabled = " + isFsdEnabled + " )");
+ Binder.clearCallingIdentity();
+ DiscoveryResult discoveryResult = new DiscoveryResult.Builder(peerId)
+ .setServiceSpecificInfo(ssi)
+ .setServiceProtoType(protoType)
+ .setFsdEnabled(isFsdEnabled)
+ .build();
+ mExecutor.execute(() -> mSubscribeSessionCallback.onServiceDiscovered(discoveryResult));
+ }
+
+ @Override
+ public void onSubscribeSessionTerminated(int reasonCode) throws RemoteException {
+ Log.d(TAG, "onSubscribeSessionTerminated ( reasonCode = " + reasonCode + " )");
+ Binder.clearCallingIdentity();
+ mExecutor.execute(() -> mSubscribeSessionCallback.onSessionTerminated(reasonCode));
+ }
+
+ @Override
+ public void onMessageReceived(int peerId, byte[] message) throws RemoteException {
+ Log.d(TAG, "onMessageReceived ( peerId = " + peerId + " )");
+ Binder.clearCallingIdentity();
+ mExecutor.execute(() -> mSubscribeSessionCallback.onMessageReceived(peerId, message));
+ }
+ }
+
+
+ /**
+ * Issue a request to the USD service to create a new subscribe session using the specified
+ * {@link SubscribeConfig} configuration. The result of the subscribe operation are
+ * routed to
+ * the callbacks of {@link SubscribeSessionCallback}.
+ *
+ * <p>Note: Maximum number of subscribe sessions are limited by
+ * {@link Characteristics#getMaxNumberOfSubscribeSessions()}.
+ *
+ * @param subscribeConfig The {@link SubscribeConfig} specifying the
+ * configuration of the requested subscribe session.
+ * @param executor The Executor on whose thread to execute the callbacks of
+ * the {@link SubscribeSessionCallback}
+ * @param subscribeSessionCallback A {@link SubscribeSessionCallback} object to be used for
+ * session event callback
+ */
+ @RequiresPermission(MANAGE_WIFI_NETWORK_SELECTION)
+ public void subscribe(@NonNull SubscribeConfig subscribeConfig,
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull SubscribeSessionCallback subscribeSessionCallback) {
+ Objects.requireNonNull(subscribeConfig, "subscribeConfig must not be null");
+ Objects.requireNonNull(executor, "executor must not be null");
+ Objects.requireNonNull(subscribeSessionCallback,
+ "subscribeSessionCallback must not be null");
+ if (!Environment.isSdkAtLeastB()) {
+ throw new UnsupportedOperationException();
+ }
+ try {
+ SubscribeSessionCallbackProxy subscribeSessionCallbackProxy =
+ new SubscribeSessionCallbackProxy(this, executor, subscribeSessionCallback);
+ mService.subscribe(subscribeConfig, subscribeSessionCallbackProxy);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
}
diff --git a/service/java/com/android/server/wifi/usd/UsdServiceImpl.java b/service/java/com/android/server/wifi/usd/UsdServiceImpl.java
index f54f8eb128..5b4ad7b95d 100644
--- a/service/java/com/android/server/wifi/usd/UsdServiceImpl.java
+++ b/service/java/com/android/server/wifi/usd/UsdServiceImpl.java
@@ -21,9 +21,15 @@ import android.content.Context;
import android.net.wifi.IBooleanListener;
import android.net.wifi.usd.Characteristics;
import android.net.wifi.usd.IAvailabilityCallback;
+import android.net.wifi.usd.IPublishSessionCallback;
+import android.net.wifi.usd.ISubscribeSessionCallback;
import android.net.wifi.usd.IUsdManager;
+import android.net.wifi.usd.PublishConfig;
import android.net.wifi.usd.PublishSession;
+import android.net.wifi.usd.PublishSessionCallback;
+import android.net.wifi.usd.SubscribeConfig;
import android.net.wifi.usd.SubscribeSession;
+import android.net.wifi.usd.SubscribeSessionCallback;
import android.net.wifi.usd.UsdManager;
import android.os.Binder;
import android.os.Bundle;
@@ -221,4 +227,32 @@ public class UsdServiceImpl extends IUsdManager.Stub {
}
Log.i(TAG, "updatePublish: ( sessionId = " + sessionId + " )");
}
+
+ /**
+ * See {@link UsdManager#publish(PublishConfig, Executor, PublishSessionCallback)}
+ */
+ @Override
+ public void publish(PublishConfig publishConfig, IPublishSessionCallback callback) {
+ Objects.requireNonNull(publishConfig, "publishConfig must not be null");
+ Objects.requireNonNull(callback, "callback must not be null");
+ int uid = getMockableCallingUid();
+ if (!mWifiPermissionsUtil.checkManageWifiNetworkSelectionPermission(uid)) {
+ throw new SecurityException("App not allowed to use USD (uid = " + uid + ")");
+ }
+ Log.i(TAG, "publish " + publishConfig);
+ }
+
+ /**
+ * See {@link UsdManager#subscribe(SubscribeConfig, Executor, SubscribeSessionCallback)}
+ */
+ @Override
+ public void subscribe(SubscribeConfig subscribeConfig, ISubscribeSessionCallback callback) {
+ Objects.requireNonNull(subscribeConfig, "subscribeConfig must not be null");
+ Objects.requireNonNull(callback, "callback must not be null");
+ int uid = getMockableCallingUid();
+ if (!mWifiPermissionsUtil.checkManageWifiNetworkSelectionPermission(uid)) {
+ throw new SecurityException("App not allowed to use USD (uid = " + uid + ")");
+ }
+ Log.i(TAG, "subscribe " + subscribeConfig);
+ }
}