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
This commit is contained in:
Igor Zaslavsky 2023-08-30 04:01:04 +00:00
commit 79bb3ca10f
7 changed files with 275 additions and 6 deletions

View file

@ -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);
}
}
}

View file

@ -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);
}

View file

@ -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);
}
}

View file

@ -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;

View file

@ -97,12 +97,9 @@ pub struct JavaPlatform {
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,

View file

@ -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)
}

View file

@ -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()
}