Skip to content
Snippets Groups Projects
Commit a92d8cab authored by Igor Zaslavsky's avatar Igor Zaslavsky Committed by Gerrit Code Review
Browse files

Merge "Add RemoteAuthService" into main

parents f180b14d ec344f4c
No related branches found
No related tags found
No related merge requests found
Showing
with 817 additions and 8 deletions
......@@ -203,6 +203,8 @@ bootclasspath_fragment {
// result in a build failure due to inconsistent flags.
package_prefixes: [
"android.nearby.aidl",
"android.remoteauth.aidl",
"android.remoteauth",
"android.net.apf",
"android.net.connectivity",
"android.net.http.apihelpers",
......
......@@ -43,6 +43,7 @@ java_defaults {
":framework-connectivity-tiramisu-updatable-sources",
":framework-nearby-java-sources",
":framework-thread-sources",
":framework-remoteauth-java-sources",
],
libs: [
"unsupportedappusage",
......@@ -130,8 +131,10 @@ java_sdk_library {
"android.net",
"android.net.nsd",
"android.nearby",
"android.remoteauth",
"com.android.connectivity",
"com.android.nearby",
"com.android.remoteauth",
],
hidden_api: {
......@@ -153,6 +156,7 @@ java_sdk_library {
"//packages/modules/Connectivity/service", // For R8 only
"//packages/modules/Connectivity/service-t",
"//packages/modules/Connectivity/nearby:__subpackages__",
"//packages/modules/Connectivity/remoteauth:__subpackages__",
"//frameworks/base",
// Tests using hidden APIs
......
......@@ -207,3 +207,43 @@ package android.net {
}
package android.remoteauth {
public interface DeviceDiscoveryCallback {
method public void onDeviceUpdate(@NonNull android.remoteauth.RemoteDevice, int);
method public void onTimeout();
field public static final int STATE_LOST = 0; // 0x0
field public static final int STATE_SEEN = 1; // 0x1
}
public final class RemoteAuthFrameworkInitializer {
method public static void registerServiceWrappers();
}
public class RemoteAuthManager {
method public boolean isRemoteAuthSupported();
method public boolean startDiscovery(int, @NonNull java.util.concurrent.Executor, @NonNull android.remoteauth.DeviceDiscoveryCallback);
method public void stopDiscovery(@NonNull android.remoteauth.DeviceDiscoveryCallback);
}
public final class RemoteDevice implements android.os.Parcelable {
method public int describeContents();
method @NonNull public int getConnectionId();
method @Nullable public String getName();
method public int getRegistrationState();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.remoteauth.RemoteDevice> CREATOR;
field public static final int STATE_NOT_REGISTERED = 0; // 0x0
field public static final int STATE_REGISTERED = 1; // 0x1
}
public static final class RemoteDevice.Builder {
ctor public RemoteDevice.Builder(int);
method @NonNull public android.remoteauth.RemoteDevice build();
method @NonNull public android.remoteauth.RemoteDevice.Builder setConnectionId(int);
method @NonNull public android.remoteauth.RemoteDevice.Builder setName(@Nullable String);
method @NonNull public android.remoteauth.RemoteDevice.Builder setRegistrationState(int);
}
}
......@@ -62,7 +62,6 @@ java_defaults {
":framework-connectivity-sources",
":net-utils-framework-common-srcs",
":framework-connectivity-api-shared-srcs",
":framework-remoteauth-java-sources",
],
aidl: {
generate_get_transaction_name: true,
......@@ -153,7 +152,6 @@ java_sdk_library {
"//packages/modules/Connectivity/framework-t",
"//packages/modules/Connectivity/service",
"//packages/modules/Connectivity/service-t",
"//packages/modules/Connectivity/remoteauth:__subpackages__",
"//frameworks/base/packages/Connectivity/service",
"//frameworks/base",
......
......@@ -7,7 +7,7 @@
// TODO(b/193602229): uncomment once it's supported.
//"mainline-presubmit": [
// {
// "name": "RemoteAuthUnitTests[com.google.android.tethering.apex]"
// "name": "RemoteAuthUnitTests[com.google.android.remoteauth.apex]"
// }
//]
}
......@@ -25,7 +25,7 @@ filegroup {
],
path: "java",
visibility: [
"//packages/modules/Connectivity/framework:__subpackages__",
"//packages/modules/Connectivity/framework-t:__subpackages__",
],
}
......@@ -43,7 +43,13 @@ java_library {
name: "framework-remoteauth-static",
srcs: [":framework-remoteauth-java-sources"],
sdk_version: "module_current",
libs: [],
static_libs: [],
libs: [
"androidx.annotation_annotation",
"framework-annotations-lib",
"framework-bluetooth",
],
static_libs: [
"modules-utils-preconditions",
],
visibility: ["//packages/modules/Connectivity/remoteauth/tests:__subpackages__"],
}
/*
* Copyright 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 android.remoteauth;
import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
import android.annotation.NonNull;
import android.annotation.SystemApi;
import androidx.annotation.IntDef;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Reports newly discovered remote devices.
*
* @hide
*/
@SystemApi(client = MODULE_LIBRARIES)
public interface DeviceDiscoveryCallback {
/** The device is no longer seen in the discovery process. */
int STATE_LOST = 0;
/** The device is seen in the discovery process */
int STATE_SEEN = 1;
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef({STATE_LOST, STATE_SEEN})
@interface State {}
/**
* Invoked for every change in remote device state.
*
* @param device remote device
* @param state indicates if found or lost
*/
void onDeviceUpdate(@NonNull RemoteDevice device, @State int state);
/** Invoked when discovery is stopped due to timeout. */
void onTimeout();
}
/*
* 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 android.remoteauth;
import android.remoteauth.RemoteDevice;
/**
* Binder callback for DeviceDiscoveryCallback.
*
* {@hide}
*/
oneway interface IDeviceDiscoveryListener {
/** Reports a {@link RemoteDevice} being discovered. */
void onDiscovered(in RemoteDevice remoteDevice);
/** Reports a {@link RemoteDevice} is no longer within range. */
void onLost(in RemoteDevice remoteDevice);
/** Reports a timeout of {@link RemoteDevice} was reached. */
void onTimeout();
}
/*
* 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 android.remoteauth;
import android.remoteauth.IDeviceDiscoveryListener;
/**
* Interface for communicating with the RemoteAuthService.
* These methods are all require MANAGE_REMOTE_AUTH signature permission.
* @hide
*/
interface IRemoteAuthService {
// This is protected by the MANAGE_REMOTE_AUTH signature permission.
boolean isRemoteAuthSupported();
// This is protected by the MANAGE_REMOTE_AUTH signature permission.
boolean registerDiscoveryListener(in IDeviceDiscoveryListener deviceDiscoveryListener,
int userId,
int timeoutMs,
String packageName,
@nullable String attributionTag);
// This is protected by the MANAGE_REMOTE_AUTH signature permission.
void unregisterDiscoveryListener(in IDeviceDiscoveryListener deviceDiscoveryListener,
int userId,
String packageName,
@nullable String attributionTag);
}
\ No newline at end of file
/*
* Copyright 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 android.remoteauth;
import android.annotation.SystemApi;
import android.app.SystemServiceRegistry;
import android.content.Context;
/**
* Class for initializing RemoteAuth service.
*
* @hide
*/
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public final class RemoteAuthFrameworkInitializer {
private RemoteAuthFrameworkInitializer() {}
/**
* Called by {@link SystemServiceRegistry}'s static initializer and registers all Nearby
* services to {@link Context}, so that {@link Context#getSystemService} can return them.
*
* @throws IllegalStateException if this is called from anywhere besides {@link
* SystemServiceRegistry}
*/
public static void registerServiceWrappers() {
// TODO(b/290092977): Change to Context.REMOTE_AUTH_SERVICE after aosp/2681375
// is automerges from aosp-main to udc-mainline-prod
SystemServiceRegistry.registerContextAwareService(
RemoteAuthManager.REMOTE_AUTH_SERVICE,
RemoteAuthManager.class,
(context, serviceBinder) -> {
IRemoteAuthService service = IRemoteAuthService.Stub.asInterface(serviceBinder);
return new RemoteAuthManager(context, service);
});
}
}
/*
* Copyright 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 android.remoteauth;
import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
import static android.remoteauth.DeviceDiscoveryCallback.STATE_LOST;
import static android.remoteauth.DeviceDiscoveryCallback.STATE_SEEN;
import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.annotation.UserIdInt;
import android.content.Context;
import android.os.RemoteException;
import android.util.Log;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.Preconditions;
import java.lang.ref.WeakReference;
import java.util.Objects;
import java.util.WeakHashMap;
import java.util.concurrent.Executor;
/**
* A system service providing a way to perform remote authentication-related operations such as
* discovering, registering and authenticating via remote authenticator.
*
* <p>To get a {@link RemoteAuthManager} instance, call the <code>
* Context.getSystemService(Context.REMOTE_AUTH_SERVICE)</code>.
*
* @hide
*/
@SystemApi(client = MODULE_LIBRARIES)
// TODO(b/290092977): Change to Context.REMOTE_AUTH_SERVICE after aosp/2681375
// is automerges from aosp-main to udc-mainline-prod
@SystemService(RemoteAuthManager.REMOTE_AUTH_SERVICE)
public class RemoteAuthManager {
private static final String TAG = "RemoteAuthManager";
/** @hide */
public static final String REMOTE_AUTH_SERVICE = "remote_auth";
private final Context mContext;
private final IRemoteAuthService mService;
@GuardedBy("mDiscoveryListeners")
private final WeakHashMap<
DeviceDiscoveryCallback, WeakReference<DeviceDiscoveryListenerTransport>>
mDiscoveryListeners = new WeakHashMap<>();
/** @hide */
public RemoteAuthManager(@NonNull Context context, @NonNull IRemoteAuthService service) {
Objects.requireNonNull(context);
Objects.requireNonNull(service);
mContext = context;
mService = service;
}
/**
* Returns if this device can be enrolled in the feature.
*
* @return true if this device can be enrolled
* @hide
*/
@SystemApi(client = MODULE_LIBRARIES)
// TODO(b/297301535): @RequiresPermission(MANAGE_REMOTE_AUTH)
public boolean isRemoteAuthSupported() {
try {
return mService.isRemoteAuthSupported();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Starts remote authenticator discovery process with timeout. Devices that are capable to
* operate as remote authenticators are reported via callback. The discovery stops by calling
* stopDiscovery or after a timeout.
*
* @param timeoutMs the duration in milliseconds after which discovery will stop automatically
* @param executor the callback will be executed in the executor thread
* @param callback to be used by the caller to get notifications about remote devices
* @return {@code true} if discovery began successfully, {@code false} otherwise
* @hide
*/
@SystemApi(client = MODULE_LIBRARIES)
// TODO(b/297301535): @RequiresPermission(MANAGE_REMOTE_AUTH)
public boolean startDiscovery(
int timeoutMs,
@CallbackExecutor @NonNull Executor executor,
@NonNull DeviceDiscoveryCallback callback) {
try {
Preconditions.checkNotNull(callback, "invalid null callback");
Preconditions.checkArgument(timeoutMs > 0, "invalid timeoutMs, must be > 0");
Preconditions.checkNotNull(executor, "invalid null executor");
DeviceDiscoveryListenerTransport transport;
synchronized (mDiscoveryListeners) {
WeakReference<DeviceDiscoveryListenerTransport> reference =
mDiscoveryListeners.get(callback);
transport = (reference != null) ? reference.get() : null;
if (transport == null) {
transport =
new DeviceDiscoveryListenerTransport(
callback, mContext.getUser().getIdentifier(), executor);
}
boolean result =
mService.registerDiscoveryListener(
transport,
mContext.getUser().getIdentifier(),
timeoutMs,
mContext.getPackageName(),
mContext.getAttributionTag());
if (result) {
mDiscoveryListeners.put(callback, new WeakReference<>(transport));
return true;
}
}
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
return false;
}
/**
* Removes this listener from device discovery notifications. The given callback is guaranteed
* not to receive any invocations that happen after this method is invoked.
*
* @param callback the callback for the previously started discovery to be ended
* @hide
*/
// Suppressed lint: Registration methods should have overload that accepts delivery Executor.
// Already have executor in startDiscovery() method.
@SuppressLint("ExecutorRegistration")
@SystemApi(client = MODULE_LIBRARIES)
// TODO(b/297301535): @RequiresPermission(MANAGE_REMOTE_AUTH)
public void stopDiscovery(@NonNull DeviceDiscoveryCallback callback) {
Preconditions.checkNotNull(callback, "invalid null scanCallback");
try {
DeviceDiscoveryListenerTransport transport;
synchronized (mDiscoveryListeners) {
WeakReference<DeviceDiscoveryListenerTransport> reference =
mDiscoveryListeners.remove(callback);
transport = (reference != null) ? reference.get() : null;
}
if (transport != null) {
mService.unregisterDiscoveryListener(
transport,
transport.getUserId(),
mContext.getPackageName(),
mContext.getAttributionTag());
} else {
Log.d(
TAG,
"Cannot stop discovery with this callback "
+ "because it is not registered.");
}
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
private class DeviceDiscoveryListenerTransport extends IDeviceDiscoveryListener.Stub {
private volatile @NonNull DeviceDiscoveryCallback mDeviceDiscoveryCallback;
private Executor mExecutor;
private @UserIdInt int mUserId;
DeviceDiscoveryListenerTransport(
DeviceDiscoveryCallback deviceDiscoveryCallback,
@UserIdInt int userId,
@CallbackExecutor Executor executor) {
Preconditions.checkNotNull(deviceDiscoveryCallback, "invalid null callback");
mDeviceDiscoveryCallback = deviceDiscoveryCallback;
mUserId = userId;
mExecutor = executor;
}
@UserIdInt
int getUserId() {
return mUserId;
}
@Override
public void onDiscovered(RemoteDevice remoteDevice) throws RemoteException {
if (remoteDevice == null) {
Log.w(TAG, "onDiscovered is called with null device");
return;
}
Log.i(TAG, "Notifying the caller about discovered: " + remoteDevice);
mExecutor.execute(
() -> {
mDeviceDiscoveryCallback.onDeviceUpdate(remoteDevice, STATE_SEEN);
});
}
@Override
public void onLost(RemoteDevice remoteDevice) throws RemoteException {
if (remoteDevice == null) {
Log.w(TAG, "onLost is called with null device");
return;
}
Log.i(TAG, "Notifying the caller about lost: " + remoteDevice);
mExecutor.execute(
() -> {
mDeviceDiscoveryCallback.onDeviceUpdate(remoteDevice, STATE_LOST);
});
}
@Override
public void onTimeout() {
Log.i(TAG, "Notifying the caller about discovery timeout");
mExecutor.execute(
() -> {
mDeviceDiscoveryCallback.onTimeout();
});
synchronized (mDiscoveryListeners) {
mDiscoveryListeners.remove(mDeviceDiscoveryCallback);
}
mDeviceDiscoveryCallback = null;
}
}
}
/*
* 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 android.remoteauth;
parcelable RemoteDevice;
\ No newline at end of file
/*
* Copyright 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 android.remoteauth;
import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Objects;
/**
* Remote device that can be registered as remote authenticator.
*
* @hide
*/
// TODO(b/295407748) Change to use @DataClass
@SystemApi(client = MODULE_LIBRARIES)
public final class RemoteDevice implements Parcelable {
/** The remote device is not registered as remote authenticator. */
public static final int STATE_NOT_REGISTERED = 0;
/** The remote device is registered as remote authenticator. */
public static final int STATE_REGISTERED = 1;
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef({STATE_NOT_REGISTERED, STATE_REGISTERED})
@interface RegistrationState {}
@NonNull private final String mName;
private final @RegistrationState int mRegistrationState;
private final int mConnectionId;
public static final @NonNull Creator<RemoteDevice> CREATOR =
new Creator<>() {
@Override
public RemoteDevice createFromParcel(Parcel in) {
RemoteDevice.Builder builder = new RemoteDevice.Builder();
builder.setName(in.readString());
builder.setRegistrationState(in.readInt());
builder.setConnectionId(in.readInt());
return builder.build();
}
@Override
public RemoteDevice[] newArray(int size) {
return new RemoteDevice[size];
}
};
private RemoteDevice(
@Nullable String name,
@RegistrationState int registrationState,
@NonNull int connectionId) {
this.mName = name;
this.mRegistrationState = registrationState;
this.mConnectionId = connectionId;
}
/** Gets the name of the {@link RemoteDevice} device. */
@Nullable
public String getName() {
return mName;
}
/** Returns registration state of the {@link RemoteDevice}. */
public @RegistrationState int getRegistrationState() {
return mRegistrationState;
}
/** Returns connection id of the {@link RemoteDevice}. */
@NonNull
public int getConnectionId() {
return mConnectionId;
}
@Override
public int describeContents() {
return 0;
}
/** Returns a string representation of {@link RemoteDevice}. */
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("RemoteDevice [");
sb.append("name=").append(mName).append(", ");
sb.append("registered=").append(mRegistrationState).append(", ");
sb.append("connectionId=").append(mConnectionId);
sb.append("]");
return sb.toString();
}
/** Returns true if this {@link RemoteDevice} object is equals to other. */
@Override
public boolean equals(Object other) {
if (other instanceof RemoteDevice) {
RemoteDevice otherDevice = (RemoteDevice) other;
return Objects.equals(this.mName, otherDevice.mName)
&& this.getRegistrationState() == otherDevice.getRegistrationState()
&& this.mConnectionId == otherDevice.mConnectionId;
}
return false;
}
@Override
public int hashCode() {
return Objects.hash(mName, mRegistrationState, mConnectionId);
}
/**
* Helper function for writing {@link RemoteDevice} to a Parcel.
*
* @param dest 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 dest, int flags) {
String name = getName();
dest.writeString(name);
dest.writeInt(getRegistrationState());
dest.writeInt(getConnectionId());
}
/** Builder for {@link RemoteDevice} objects. */
public static final class Builder {
@Nullable private String mName;
// represents if device is already registered
private @RegistrationState int mRegistrationState;
private int mConnectionId;
private Builder() {
}
public Builder(final int connectionId) {
this.mConnectionId = connectionId;
}
/**
* Sets the name of the {@link RemoteDevice} device.
*
* @param name of the {@link RemoteDevice}. Can be {@code null} if there is no name.
*/
@NonNull
public RemoteDevice.Builder setName(@Nullable String name) {
this.mName = name;
return this;
}
/**
* Sets the registration state of the {@link RemoteDevice} device.
*
* @param registrationState of the {@link RemoteDevice}.
*/
@NonNull
public RemoteDevice.Builder setRegistrationState(@RegistrationState int registrationState) {
this.mRegistrationState = registrationState;
return this;
}
/**
* Sets the connectionInfo of the {@link RemoteDevice} device.
*
* @param connectionId of the RemoteDevice.
*/
@NonNull
public RemoteDevice.Builder setConnectionId(int connectionId) {
this.mConnectionId = connectionId;
return this;
}
/**
* Creates the {@link RemoteDevice} instance.
*
* @return the configured {@link RemoteDevice} instance.
*/
@NonNull
public RemoteDevice build() {
return new RemoteDevice(mName, mRegistrationState, mConnectionId);
}
}
}
......@@ -29,8 +29,24 @@ java_library {
defaults: [
"framework-system-server-module-defaults"
],
libs: [],
static_libs: [],
libs: [
"androidx.annotation_annotation",
"framework-bluetooth",
"error_prone_annotations",
"framework-configinfrastructure",
"framework-connectivity-pre-jarjar",
"framework-connectivity-t-pre-jarjar",
"framework-statsd",
],
static_libs: [
"libprotobuf-java-lite",
"fast-pair-lite-protos",
"modules-utils-build",
"modules-utils-handlerexecutor",
"modules-utils-preconditions",
"modules-utils-backgroundthread",
"presence-lite-protos",
],
sdk_version: "system_server_current",
// This is included in service-connectivity which is 30+
// TODO (b/293613362): allow APEXes to have service jars with higher min_sdk than the APEX
......
/*
* Copyright 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;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.content.Context;
import android.remoteauth.IDeviceDiscoveryListener;
import android.remoteauth.IRemoteAuthService;
import com.android.internal.util.Preconditions;
/** Service implementing remoteauth functionality. */
public class RemoteAuthService extends IRemoteAuthService.Stub {
public static final String TAG = "RemoteAuthService";
public RemoteAuthService(Context context) {
Preconditions.checkNotNull(context);
// TODO(b/290280702): Create here RemoteConnectivityManager and RangingManager
}
@Override
public boolean isRemoteAuthSupported() {
// TODO(b/297301535): checkPermission(mContext, MANAGE_REMOTE_AUTH);
// TODO(b/290676192): integrate with RangingManager
// (check if UWB is supported by this device)
return true;
}
@Override
public boolean registerDiscoveryListener(
IDeviceDiscoveryListener deviceDiscoveryListener,
@UserIdInt int userId,
int timeoutMs,
String packageName,
@Nullable String attributionTag) {
// TODO(b/297301535): checkPermission(mContext, MANAGE_REMOTE_AUTH);
// TODO(b/290280702): implement register discovery logic
return true;
}
@Override
public void unregisterDiscoveryListener(
IDeviceDiscoveryListener deviceDiscoveryListener,
@UserIdInt int userId,
String packageName,
@Nullable String attributionTag) {
// TODO(b/297301535): checkPermission(mContext, MANAGE_REMOTE_AUTH);
// TODO(b/290094221): implement unregister logic
}
private static void checkPermission(Context context, String permission) {
context.enforceCallingOrSelfPermission(permission,
"Must have " + permission + " permission.");
}
}
......@@ -37,6 +37,7 @@ android_test {
"androidx.test.rules",
"framework-remoteauth-static",
"junit",
"libprotobuf-java-lite",
"platform-test-annotations",
"service-remoteauth-pre-jarjar",
"truth-prebuilt",
......
......@@ -23,6 +23,7 @@ import android.platform.test.annotations.Presubmit;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
......@@ -31,6 +32,9 @@ import org.junit.runner.RunWith;
@SmallTest
@RunWith(AndroidJUnit4.class)
public class RemoteAuthManagerTest {
@Before
public void setUp() {}
@Test
public void testStub() {
assertTrue(true);
......
......@@ -56,6 +56,7 @@ java_library {
"service-connectivity-pre-jarjar",
"service-nearby-pre-jarjar",
"service-thread-pre-jarjar",
"service-remoteauth-pre-jarjar",
"ServiceConnectivityResources",
"unsupportedappusage",
],
......
......@@ -17,6 +17,7 @@
package com.android.server;
import android.content.Context;
import android.remoteauth.RemoteAuthManager;
import android.util.Log;
import com.android.modules.utils.build.SdkLevel;
......@@ -25,6 +26,7 @@ import com.android.server.connectivity.ConnectivityNativeService;
import com.android.server.ethernet.EthernetService;
import com.android.server.ethernet.EthernetServiceImpl;
import com.android.server.nearby.NearbyService;
import com.android.server.remoteauth.RemoteAuthService;
/**
* Connectivity service initializer for core networking. This is called by system server to create
......@@ -38,6 +40,7 @@ public final class ConnectivityServiceInitializer extends SystemService {
private final NsdService mNsdService;
private final NearbyService mNearbyService;
private final EthernetServiceImpl mEthernetServiceImpl;
private final RemoteAuthService mRemoteAuthService;
public ConnectivityServiceInitializer(Context context) {
super(context);
......@@ -49,6 +52,7 @@ public final class ConnectivityServiceInitializer extends SystemService {
mConnectivityNative = createConnectivityNativeService(context);
mNsdService = createNsdService(context);
mNearbyService = createNearbyService(context);
mRemoteAuthService = createRemoteAuthService(context);
}
@Override
......@@ -85,6 +89,11 @@ public final class ConnectivityServiceInitializer extends SystemService {
/* allowIsolated= */ false);
}
if (mRemoteAuthService != null) {
Log.i(TAG, "Registering " + RemoteAuthManager.REMOTE_AUTH_SERVICE);
publishBinderService(RemoteAuthManager.REMOTE_AUTH_SERVICE, mRemoteAuthService,
/* allowIsolated= */ false);
}
}
@Override
......@@ -140,6 +149,20 @@ public final class ConnectivityServiceInitializer extends SystemService {
}
}
/** Return RemoteAuth service instance */
private RemoteAuthService createRemoteAuthService(final Context context) {
if (!SdkLevel.isAtLeastV()) return null;
try {
return new RemoteAuthService(context);
} catch (UnsupportedOperationException e) {
// RemoteAuth is not yet supported in all branches
// TODO: remove catch clause when it is available.
Log.i(TAG, "Skipping unsupported service "
+ RemoteAuthManager.REMOTE_AUTH_SERVICE);
return null;
}
}
/**
* Return EthernetServiceImpl instance or null if current SDK is lower than T or Ethernet
* service isn't necessary.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment