Implement Discovery PLATFORM logic in Rust
This commit introduces NativeRemoteAuthService used by ReamoteAuth as an
interface toward Rust platform and protocol implementation
Design doc: go/remote-auth-manager-fishfood-design
Test: built successfully.
Bug: : 291333048
Change-Id: If2fcfee1c637d17bbc417a26ea39dc97062e6bc3
diff --git a/remoteauth/service/java/com/android/server/remoteauth/jni/INativeRemoteAuthService.java b/remoteauth/service/java/com/android/server/remoteauth/jni/INativeRemoteAuthService.java
new file mode 100644
index 0000000..f79ec7e
--- /dev/null
+++ b/remoteauth/service/java/com/android/server/remoteauth/jni/INativeRemoteAuthService.java
@@ -0,0 +1,67 @@
+/*
+ * 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.jni;
+
+/**
+ * Interface defining a proxy between Rust and Java implementation of RemoteAuth protocol.
+ *
+ * @hide
+ */
+public interface INativeRemoteAuthService {
+ /**
+ * Interface for RemoteAuth PAL
+ *
+ * @hide
+ */
+ interface IPlatform {
+ /**
+ * Sends message to the remote authenticator
+ *
+ * @param connectionId connection ID of the {@link android.remoteauth.RemoteAuthenticator}
+ * @param request payload of the request
+ * @param callback to be used to pass the response result
+ *
+ * @hide
+ */
+ void sendRequest(int connectionId, byte[] request, ResponseCallback callback);
+
+ /**
+ * Interface for a callback to send a response back.
+ *
+ * @hide
+ */
+ interface ResponseCallback {
+ /**
+ * Invoked when message sending succeeds.
+ *
+ * @param response contains response
+ *
+ * @hide
+ */
+ void onSuccess(byte[] response);
+
+ /**
+ * Invoked when message sending fails.
+ *
+ * @param errorCode indicating the error
+ *
+ * @hide
+ */
+ void onFailure(int errorCode);
+ }
+ }
+}
diff --git a/remoteauth/service/java/com/android/server/remoteauth/jni/NativeRemoteAuthService.java b/remoteauth/service/java/com/android/server/remoteauth/jni/NativeRemoteAuthService.java
new file mode 100644
index 0000000..39c2a74
--- /dev/null
+++ b/remoteauth/service/java/com/android/server/remoteauth/jni/NativeRemoteAuthService.java
@@ -0,0 +1,92 @@
+/*
+ * 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.jni;
+
+import com.android.internal.annotations.Keep;
+import com.android.server.remoteauth.jni.INativeRemoteAuthService.IPlatform;
+
+/**
+ * A service providing a proxy between Rust implementation and {@link
+ * com.android.server.remoteauth.RemoteAuthService}.
+ *
+ * @hide
+ */
+public class NativeRemoteAuthService {
+ private static final String TAG = NativeRemoteAuthService.class.getSimpleName();
+
+ private IPlatform mPlatform;
+ public final Object mNativeLock = new Object();
+
+ // Constructor should receive pointers to:
+ // ConnectivityManager, RangingManager and DB
+ public NativeRemoteAuthService() {
+ System.loadLibrary("remoteauth_jni_rust");
+ synchronized (mNativeLock) {
+ native_init();
+ }
+ }
+
+ public void setDeviceListener(final IPlatform platform) {
+ mPlatform = platform;
+ }
+
+ /**
+ * Sends message to the remote authenticator
+ *
+ * @param connectionId connection ID of the {@link android.remoteauth.RemoteAuthenticator}
+ * @param request payload of the request
+ * @param responseHandle a handle associated with the request, used to pass the response to the
+ * platform
+ * @param platformHandle a handle associated with the platform object, used to pass the response
+ * to the specific platform
+ *
+ * @hide
+ */
+ @Keep
+ public void sendRequest(
+ int connectionId, byte[] request, long responseHandle, long platformHandle) {
+ mPlatform.sendRequest(
+ connectionId,
+ request,
+ new IPlatform.ResponseCallback() {
+ @Override
+ public void onSuccess(byte[] response) {
+ synchronized (mNativeLock) {
+ native_on_send_request_success(
+ response, platformHandle, responseHandle);
+ }
+ }
+
+ @Override
+ public void onFailure(int errorCode) {
+ synchronized (mNativeLock) {
+ native_on_send_request_error(errorCode, platformHandle, responseHandle);
+ }
+ }
+ });
+ }
+
+ /* Native functions implemented in JNI */
+ // This function should be implemented in remoteauth_jni_android_protocol
+ private native boolean native_init();
+
+ private native void native_on_send_request_success(
+ byte[] appResponse, long platformHandle, long responseHandle);
+
+ private native void native_on_send_request_error(
+ int errorCode, long platformHandle, long responseHandle);
+}
diff --git a/remoteauth/service/java/com/android/server/remoteauth/jni/PlatformBadHandleException.java b/remoteauth/service/java/com/android/server/remoteauth/jni/PlatformBadHandleException.java
new file mode 100644
index 0000000..3ae9838
--- /dev/null
+++ b/remoteauth/service/java/com/android/server/remoteauth/jni/PlatformBadHandleException.java
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+/**
+ * Represents an unrecoverable error (invalid handle) that has occurred during accessing the
+ * platform.
+ */
+package com.android.server.remoteauth.jni;
+
+import com.android.internal.annotations.Keep;
+/**
+ * Exception thrown by native platform rust implementation of {@link
+ * com.android.server.remoteauth.RemoteAuthService}.
+ *
+ * @hide
+ */
+@Keep
+public class PlatformBadHandleException extends Exception {
+ public PlatformBadHandleException(final String message) {
+ super(message);
+ }
+
+ public PlatformBadHandleException(final Exception e) {
+ super(e);
+ }
+
+ public PlatformBadHandleException(final String message, final Exception e) {
+ super(message, e);
+ }
+}
diff --git a/remoteauth/service/jni/src/lib.rs b/remoteauth/service/jni/src/lib.rs
index 0c18679..a816c94 100644
--- a/remoteauth/service/jni/src/lib.rs
+++ b/remoteauth/service/jni/src/lib.rs
@@ -19,6 +19,7 @@
mod jnames;
mod unique_jvm;
+mod utils;
-//pub mod remoteauth_jni_android_protocol;
pub mod remoteauth_jni_android_platform;
+pub mod remoteauth_jni_android_protocol;
diff --git a/remoteauth/service/jni/src/remoteauth_jni_android_platform.rs b/remoteauth/service/jni/src/remoteauth_jni_android_platform.rs
index 4597561..f3cf3ea 100644
--- a/remoteauth/service/jni/src/remoteauth_jni_android_platform.rs
+++ b/remoteauth/service/jni/src/remoteauth_jni_android_platform.rs
@@ -97,12 +97,9 @@
impl JavaPlatform {
// Method to create JavaPlatform
- pub async fn create<'a>(
- env: JNIEnv<'a>,
- java_platform_native: JObject<'a>,
+ pub async fn create(
+ java_platform_native: JObject<'_>,
) -> Result<Arc<Mutex<impl Platform>>, JNIError> {
- let jvm = env.get_java_vm()?;
- let _ = unique_jvm::set_once(jvm);
let platform_handle = generate_platform_handle();
let platform = Arc::new(Mutex::new(JavaPlatform::new(
platform_handle,
diff --git a/remoteauth/service/jni/src/remoteauth_jni_android_protocol.rs b/remoteauth/service/jni/src/remoteauth_jni_android_protocol.rs
new file mode 100644
index 0000000..1f73207
--- /dev/null
+++ b/remoteauth/service/jni/src/remoteauth_jni_android_protocol.rs
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+
+use crate::unique_jvm;
+use crate::utils::get_boolean_result;
+use jni::objects::JObject;
+use jni::sys::jboolean;
+use jni::JNIEnv;
+
+#[no_mangle]
+pub extern "system" fn Java_com_android_server_remoteauth_jni_NativeRemoteAuthJavaPlatform_native_init(
+ env: JNIEnv,
+ _: JObject,
+) -> jboolean {
+ logger::init(
+ logger::Config::default()
+ .with_tag_on_device("remoteauth")
+ .with_min_level(log::Level::Trace)
+ .with_filter("trace,jni=info"),
+ );
+ get_boolean_result(native_init(env), "native_init")
+}
+
+fn native_init(env: JNIEnv) -> anyhow::Result<()> {
+ let jvm = env.get_java_vm()?;
+ unique_jvm::set_once(jvm)
+}
diff --git a/remoteauth/service/jni/src/utils.rs b/remoteauth/service/jni/src/utils.rs
new file mode 100644
index 0000000..e61b895
--- /dev/null
+++ b/remoteauth/service/jni/src/utils.rs
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+use jni::sys::jboolean;
+use log::error;
+
+pub(crate) fn get_boolean_result<T>(result: anyhow::Result<T>, error_msg: &str) -> jboolean {
+ match result {
+ Ok(_) => true,
+ Err(e) => {
+ error!("{} failed with {:?}", error_msg, &e);
+ false
+ }
+ }
+ .into()
+}