summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author George Chan <georgechan@google.com> 2025-03-03 14:05:26 -0800
committer George Chan <georgechan@google.com> 2025-03-03 14:05:26 -0800
commit8ed5af479ab8ff567c1e7cdf18662d0cf56c71a9 (patch)
tree3be11020f60a163e4d8398e89f6343529ce996e8
parent40b100e3c3ceac4622af53ec5217cd56bd6e849f (diff)
Moved UsbManagerInternal to framework core so other System Services outside of USB can access it (currently there will only be one caller which is UsbDataAdvancedProtectionHook.)
As the UsbManagerInternal is now moved outside of UsbService space, it has been reshaped to be similar to UsbManager to make it more consistent and avoid excess differentiation between Manager clients. Currently no service is consuming the client. But will be in a subsequent CL. Bug: 399146898 Change-Id: Iad36ce274a9c444f7c697503a7a4bd39e9df2986 Test: atest UsbServiceTest, manual test Flag: android.hardware.usb.flags.enable_usb_data_signal_staking_internal
-rw-r--r--core/java/android/hardware/usb/IUsbManagerInternal.aidl26
-rw-r--r--services/usb/java/com/android/server/usb/UsbManagerInternal.java50
-rw-r--r--services/usb/java/com/android/server/usb/UsbService.java48
-rw-r--r--tests/UsbTests/src/com/android/server/usb/UsbServiceTest.java67
4 files changed, 104 insertions, 87 deletions
diff --git a/core/java/android/hardware/usb/IUsbManagerInternal.aidl b/core/java/android/hardware/usb/IUsbManagerInternal.aidl
new file mode 100644
index 000000000000..32479d449f24
--- /dev/null
+++ b/core/java/android/hardware/usb/IUsbManagerInternal.aidl
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2025 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.hardware.usb;
+
+import android.hardware.usb.IUsbOperationInternal;
+
+/** @hide */
+interface IUsbManagerInternal {
+
+ /* Disable/enable USB data on a port for System Service callers. */
+ boolean enableUsbDataSignal(boolean enable, int disableReason);
+}
diff --git a/services/usb/java/com/android/server/usb/UsbManagerInternal.java b/services/usb/java/com/android/server/usb/UsbManagerInternal.java
deleted file mode 100644
index 31c5986c45b8..000000000000
--- a/services/usb/java/com/android/server/usb/UsbManagerInternal.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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 com.android.server.usb;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.hardware.usb.IUsbOperationInternal;
-import android.hardware.usb.UsbPort;
-import android.util.ArraySet;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * UsbManagerInternal provides internal APIs for the UsbService to
- * reduce IPC overhead costs and support internal USB data signal stakers.
- *
- * @hide Only for use within the system server.
- */
-public abstract class UsbManagerInternal {
-
- public static final int OS_USB_DISABLE_REASON_AAPM = 0;
- public static final int OS_USB_DISABLE_REASON_LOCKDOWN_MODE = 1;
-
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(value = {OS_USB_DISABLE_REASON_AAPM,
- OS_USB_DISABLE_REASON_LOCKDOWN_MODE})
- public @interface OsUsbDisableReason {
- }
-
- public abstract boolean enableUsbData(String portId, boolean enable,
- int operationId, IUsbOperationInternal callback, @OsUsbDisableReason int disableReason);
-
- public abstract UsbPort[] getPorts();
-
-} \ No newline at end of file
diff --git a/services/usb/java/com/android/server/usb/UsbService.java b/services/usb/java/com/android/server/usb/UsbService.java
index 4395b76d91cc..7808b2e318b2 100644
--- a/services/usb/java/com/android/server/usb/UsbService.java
+++ b/services/usb/java/com/android/server/usb/UsbService.java
@@ -27,7 +27,10 @@ import static android.hardware.usb.UsbPortStatus.MODE_UFP;
import static android.hardware.usb.UsbPortStatus.POWER_ROLE_SINK;
import static android.hardware.usb.UsbPortStatus.POWER_ROLE_SOURCE;
+import android.hardware.usb.IUsbManagerInternal;
+
import android.annotation.NonNull;
+import android.annotation.IntDef;
import android.annotation.UserIdInt;
import android.app.PendingIntent;
import android.app.admin.DevicePolicyManager;
@@ -80,12 +83,16 @@ import dalvik.annotation.optimization.NeverCompile;
import java.io.File;
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.atomic.AtomicInteger;
+
/**
* UsbService manages all USB related state, including both host and device support.
* Host related events and calls are delegated to UsbHostManager, and device related
@@ -93,6 +100,15 @@ import java.util.concurrent.CompletableFuture;
*/
public class UsbService extends IUsbManager.Stub {
+ public static final int OS_USB_DISABLE_REASON_AAPM = 0;
+ public static final int OS_USB_DISABLE_REASON_LOCKDOWN_MODE = 1;
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(value = {OS_USB_DISABLE_REASON_AAPM,
+ OS_USB_DISABLE_REASON_LOCKDOWN_MODE})
+ public @interface OsUsbDisableReason {
+ }
+
public static class Lifecycle extends SystemService {
private UsbService mUsbService;
private final CompletableFuture<Void> mOnStartFinished = new CompletableFuture<>();
@@ -227,7 +243,7 @@ public class UsbService extends IUsbManager.Stub {
filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
mContext.registerReceiverAsUser(receiver, UserHandle.ALL, filter, null, null);
if(android.hardware.usb.flags.Flags.enableUsbDataSignalStakingInternal()) {
- LocalServices.addService(UsbManagerInternal.class, new UsbManagerInternalImpl());
+ LocalServices.addService(IUsbManagerInternal.class, new UsbManagerInternalImpl());
}
}
@@ -246,7 +262,7 @@ public class UsbService extends IUsbManager.Stub {
mPermissionManager = new UsbPermissionManager(context, this);
if(android.hardware.usb.flags.Flags.enableUsbDataSignalStakingInternal()) {
- LocalServices.addService(UsbManagerInternal.class, new UsbManagerInternalImpl());
+ LocalServices.addService(IUsbManagerInternal.class, new UsbManagerInternalImpl());
}
}
@@ -1536,24 +1552,30 @@ public class UsbService extends IUsbManager.Stub {
enableUsbDataInternal(port.getId(), !lockDownTriggeredByUser,
STRONG_AUTH_OPERATION_ID,
new IUsbOperationInternal.Default(),
- UsbManagerInternal.OS_USB_DISABLE_REASON_LOCKDOWN_MODE,
+ OS_USB_DISABLE_REASON_LOCKDOWN_MODE,
true);
}
}
}
- private class UsbManagerInternalImpl extends UsbManagerInternal {
- @Override
- public boolean enableUsbData(String portId, boolean enable,
- int operationId, IUsbOperationInternal callback,
- @OsUsbDisableReason int disableReason) {
- return enableUsbDataInternal(portId, enable, operationId, callback,
- disableReason, true);
- }
+ private class UsbManagerInternalImpl extends IUsbManagerInternal.Stub {
+ private static final AtomicInteger sUsbOperationCount = new AtomicInteger();
@Override
- public UsbPort[] getPorts() {
- return mPortManager.getPorts();
+ public boolean enableUsbDataSignal(boolean enable,
+ @OsUsbDisableReason int disableReason) {
+ boolean result = true;
+ int operationId = sUsbOperationCount.incrementAndGet() + disableReason;
+ for (UsbPort port : mPortManager.getPorts()) {
+ boolean success = enableUsbDataInternal(port.getId(), enable, operationId,
+ new IUsbOperationInternal.Default(), disableReason, true);
+ if(!success) {
+ Slog.e(TAG, "enableUsbDataInternal failed to change USB port "
+ + port.getId() + "state to " + enable);
+ }
+ result &= success;
+ }
+ return result;
}
}
}
diff --git a/tests/UsbTests/src/com/android/server/usb/UsbServiceTest.java b/tests/UsbTests/src/com/android/server/usb/UsbServiceTest.java
index 51d57f0a0de9..f5d4b0c5e345 100644
--- a/tests/UsbTests/src/com/android/server/usb/UsbServiceTest.java
+++ b/tests/UsbTests/src/com/android/server/usb/UsbServiceTest.java
@@ -24,15 +24,20 @@ import static com.google.common.truth.Truth.assertWithMessage;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import android.content.Context;
+import android.hardware.usb.IUsbManagerInternal;
import android.hardware.usb.IUsbOperationInternal;
import android.hardware.usb.flags.Flags;
import android.hardware.usb.UsbPort;
@@ -70,7 +75,9 @@ public class UsbServiceTest {
@Mock
private IUsbOperationInternal mCallback;
- private static final String TEST_PORT_ID = "123";
+ private static final String TEST_PORT_ID = "1";
+
+ private static final String TEST_PORT_ID_2 = "2";
private static final int TEST_TRANSACTION_ID = 1;
@@ -84,7 +91,7 @@ public class UsbServiceTest {
private UsbService mUsbService;
- private UsbManagerInternal mUsbManagerInternal;
+ private IUsbManagerInternal mIUsbManagerInternal;
@Rule
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
@@ -101,9 +108,9 @@ public class UsbServiceTest {
mUsbService = new UsbService(mContext, mUsbPortManager, mUsbAlsaManager,
mUserManager, mUsbSettingsManager);
- mUsbManagerInternal = LocalServices.getService(UsbManagerInternal.class);
- assertWithMessage("LocalServices.getService(UsbManagerInternal.class)")
- .that(mUsbManagerInternal).isNotNull();
+ mIUsbManagerInternal = LocalServices.getService(IUsbManagerInternal.class);
+ assertWithMessage("LocalServices.getService(IUsbManagerInternal.class)")
+ .that(mIUsbManagerInternal).isNotNull();
}
private void assertToggleUsbSuccessfully(int requester, boolean enable,
@@ -255,30 +262,42 @@ public class UsbServiceTest {
assertToggleUsbSuccessfully(TEST_INTERNAL_REQUESTER_REASON_1, true, false);
}
- /**
- * Verify USB Manager internal calls mPortManager to get UsbPorts
- */
@Test
- public void usbManagerInternal_getPorts_callsPortManager() {
- when(mUsbPortManager.getPorts()).thenReturn(new UsbPort[] {});
-
- UsbPort[] ports = mUsbManagerInternal.getPorts();
-
- verify(mUsbPortManager).getPorts();
- assertEquals(ports.length, 0);
+ public void usbManagerInternal_enableUsbDataSignal_successfullyEnabled() {
+ assertTrue(runInternalUsbDataSignalTest(true, true, true));
}
@Test
- public void usbManagerInternal_enableUsbData_successfullyEnable() {
- boolean desiredEnableState = true;
+ public void usbManagerInternal_enableUsbDataSignal_successfullyDisabled() {
+ assertTrue(runInternalUsbDataSignalTest(false, true, true));
+ }
- assertTrue(mUsbManagerInternal.enableUsbData(TEST_PORT_ID, desiredEnableState,
- TEST_TRANSACTION_ID, mCallback, TEST_INTERNAL_REQUESTER_REASON_1));
+ @Test
+ public void usbManagerInternal_enableUsbDataSignal_returnsFalseIfOnePortFails() {
+ assertFalse(runInternalUsbDataSignalTest(true, true, false));
+ }
- verify(mUsbPortManager).enableUsbData(TEST_PORT_ID,
- desiredEnableState, TEST_TRANSACTION_ID, mCallback, null);
- verifyZeroInteractions(mCallback);
- clearInvocations(mUsbPortManager);
- clearInvocations(mCallback);
+ private boolean runInternalUsbDataSignalTest(boolean desiredEnableState, boolean portOneSuccess,
+ boolean portTwoSuccess) {
+ UsbPort port = mock(UsbPort.class);
+ UsbPort port2 = mock(UsbPort.class);
+ when(port.getId()).thenReturn(TEST_PORT_ID);
+ when(port2.getId()).thenReturn(TEST_PORT_ID_2);
+ when(mUsbPortManager.getPorts()).thenReturn(new UsbPort[] { port, port2 });
+ when(mUsbPortManager.enableUsbData(eq(TEST_PORT_ID),
+ eq(desiredEnableState), anyInt(), any(IUsbOperationInternal.class), isNull()))
+ .thenReturn(portOneSuccess);
+ when(mUsbPortManager.enableUsbData(eq(TEST_PORT_ID_2),
+ eq(desiredEnableState), anyInt(), any(IUsbOperationInternal.class), isNull()))
+ .thenReturn(portTwoSuccess);
+ try {
+ boolean result = mIUsbManagerInternal.enableUsbDataSignal(desiredEnableState,
+ TEST_INTERNAL_REQUESTER_REASON_1);
+ clearInvocations(mUsbPortManager);
+ return result;
+ } catch(RemoteException e) {
+ fail("RemoteException thrown when calling enableUsbDataSignal");
+ return false;
+ }
}
}