Add hidden API to reset stable LOHS credentials
This API supposed to be used by Settings app or a projection receiver
app.
Bug: 192254706
CTS-Coverage-Bug: 206154096
Test: atest CarServiceUnitTests
Change-Id: Ib7cd46a4c67943f0677bca847002ddd84b67e361
Merged-In: Ib7cd46a4c67943f0677bca847002ddd84b67e361
diff --git a/car-lib/src/android/car/CarProjectionManager.java b/car-lib/src/android/car/CarProjectionManager.java
index 66590a5..f283a2c 100644
--- a/car-lib/src/android/car/CarProjectionManager.java
+++ b/car-lib/src/android/car/CarProjectionManager.java
@@ -703,6 +703,21 @@
}
/**
+ * Resets projection access point credentials if system was configured to persist local-only
+ * hotspot credentials.
+ *
+ * @hide
+ */
+ @RequiresPermission(Car.PERMISSION_CAR_PROJECTION)
+ public void resetProjectionAccessPointCredentials() {
+ try {
+ mService.resetProjectionAccessPointCredentials();
+ } catch (RemoteException e) {
+ handleRemoteExceptionFromCarService(e);
+ }
+ }
+
+ /**
* Callback class for applications to receive updates about the LocalOnlyHotspot status.
*/
public abstract static class ProjectionAccessPointCallback {
diff --git a/car-lib/src/android/car/ICarProjection.aidl b/car-lib/src/android/car/ICarProjection.aidl
index 5be9791..e82e83a 100644
--- a/car-lib/src/android/car/ICarProjection.aidl
+++ b/car-lib/src/android/car/ICarProjection.aidl
@@ -91,4 +91,10 @@
/** Returns a list of available Wi-Fi channels */
int[] getAvailableWifiChannels(int band) = 12;
+
+ /**
+ * Resets projection access point credentials if system was configured to persist local-only
+ * hotspot credentials.
+ */
+ void resetProjectionAccessPointCredentials() = 13;
}
diff --git a/car-test-lib/src/android/car/testapi/FakeCarProjectionService.java b/car-test-lib/src/android/car/testapi/FakeCarProjectionService.java
index 275ae1c..49e8fd7 100644
--- a/car-test-lib/src/android/car/testapi/FakeCarProjectionService.java
+++ b/car-test-lib/src/android/car/testapi/FakeCarProjectionService.java
@@ -193,6 +193,10 @@
return new int[] {2412 /* Channel 1 */, 5180 /* Channel 36 */};
}
+ @Override
+ public void resetProjectionAccessPointCredentials() throws RemoteException {
+ // Nothing to do.
+ }
@Override
public void setProjectionOptions(ProjectionOptions projectionOptions) {
diff --git a/service/src/com/android/car/CarProjectionService.java b/service/src/com/android/car/CarProjectionService.java
index 4d2f164..acff9a2 100644
--- a/service/src/com/android/car/CarProjectionService.java
+++ b/service/src/com/android/car/CarProjectionService.java
@@ -651,6 +651,28 @@
}
}
+ @Override
+ public void resetProjectionAccessPointCredentials() {
+ ICarImpl.assertProjectionPermission(mContext);
+
+ if (!mStableLocalOnlyHotspotConfig) {
+ Slog.i(TAG, "Resetting local-only hotspot credentials ignored as credentials do"
+ + " not persist.");
+ return;
+ }
+
+ Slog.i(TAG, "Clearing local-only hotspot credentials.");
+ getSharedPreferences()
+ .edit()
+ .clear()
+ .apply();
+
+ synchronized (mLock) {
+ mApConfiguration = null;
+ }
+ }
+
+ @GuardedBy("mLock")
private void startLocalOnlyApLocked() {
if (mLocalOnlyHotspotReservation != null) {
Slog.i(TAG, "Local-only hotspot is already registered.");
diff --git a/tests/carservice_unit_test/src/com/android/car/CarProjectionServiceTest.java b/tests/carservice_unit_test/src/com/android/car/CarProjectionServiceTest.java
index 428811f..d063b08 100644
--- a/tests/carservice_unit_test/src/com/android/car/CarProjectionServiceTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/CarProjectionServiceTest.java
@@ -222,6 +222,23 @@
}
@Test
+ public void resetProjectionAccessPointCredentials() throws Exception {
+ mService.setStableLocalOnlyHotspotConfig(true);
+
+ WifiManager.LocalOnlyHotspotCallback callback = startProjectionLohs(false);
+
+ // Simulate framework saying AP successfully created.
+ callback.onStarted(mLohsReservation);
+ assertMessageSent(PROJECTION_AP_STARTED, AP_CONFIG);
+ mService.stopProjectionAccessPoint(mToken);
+ verify(mLohsReservation).close();
+
+ mService.resetProjectionAccessPointCredentials();
+
+ assertThat(mService.restoreApConfiguration().isPresent()).isFalse();
+ }
+
+ @Test
public void updateProjectionStatus_subscribeAfterUpdate() throws Exception {
final ProjectionStatus status = createProjectionStatus();
mService.updateProjectionStatus(status, mToken);