Clear the surface once it is destroyed.
Test: Manual
Change-Id: I21a3659d7c7f9272b3faefbe461fa74e58b80af4
diff --git a/car/app/app-automotive/src/main/aidl/androidx/car/app/activity/renderer/surface/ISurfaceListener.aidl b/car/app/app-automotive/src/main/aidl/androidx/car/app/activity/renderer/surface/ISurfaceListener.aidl
index e97c626..cfb822b 100644
--- a/car/app/app-automotive/src/main/aidl/androidx/car/app/activity/renderer/surface/ISurfaceListener.aidl
+++ b/car/app/app-automotive/src/main/aidl/androidx/car/app/activity/renderer/surface/ISurfaceListener.aidl
@@ -23,4 +23,12 @@
* surface.
*/
void onSurfaceChanged(in Bundleable surfaceWrapper) = 2;
+
+ /**
+ * Notifies that the surface is destroyed.
+ *
+ * @param surfaceWrapper a {@link SurfaceWrapper} that contains the updated information on the
+ * surface.
+ */
+ void onSurfaceDestroyed(in Bundleable surfaceWrapper) = 3;
}
diff --git a/car/app/app-automotive/src/main/java/androidx/car/app/activity/ServiceDispatcher.java b/car/app/app-automotive/src/main/java/androidx/car/app/activity/ServiceDispatcher.java
index 8f2a450..d8d2d84 100644
--- a/car/app/app-automotive/src/main/java/androidx/car/app/activity/ServiceDispatcher.java
+++ b/car/app/app-automotive/src/main/java/androidx/car/app/activity/ServiceDispatcher.java
@@ -84,6 +84,14 @@
});
}
+ /** Dispatches the given {@link OneWayCall}. Ignores any errors. This is a non-blocking call. */
+ public void dispatchNoFail(@NonNull String description, @NonNull OneWayCall call) {
+ fetchNoFail(description, null, (ReturnCall<Void>) () -> {
+ call.invoke();
+ return null;
+ });
+ }
+
/**
* Retrieves a value from the service handling any communication error and displaying the
* error to the user.
diff --git a/car/app/app-automotive/src/main/java/androidx/car/app/activity/renderer/surface/SurfaceHolderListener.java b/car/app/app-automotive/src/main/java/androidx/car/app/activity/renderer/surface/SurfaceHolderListener.java
index 6ba5fe9..7f089a2 100644
--- a/car/app/app-automotive/src/main/java/androidx/car/app/activity/renderer/surface/SurfaceHolderListener.java
+++ b/car/app/app-automotive/src/main/java/androidx/car/app/activity/renderer/surface/SurfaceHolderListener.java
@@ -73,7 +73,9 @@
@Override
public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
+ requireNonNull(holder);
mIsSurfaceAvailable = false;
+ notifySurfaceDestroyed();
}
private void notifySurfaceCreated() {
@@ -93,4 +95,13 @@
Bundleable.create(mSurfaceWrapperProvider.createSurfaceWrapper())));
}
}
+
+ private void notifySurfaceDestroyed() {
+ ISurfaceListener surfaceListener = mSurfaceListener;
+ if (surfaceListener != null) {
+ mServiceDispatcher.dispatchNoFail("onSurfaceDestroyed",
+ () -> surfaceListener.onSurfaceDestroyed(
+ Bundleable.create(mSurfaceWrapperProvider.createSurfaceWrapper())));
+ }
+ }
}
diff --git a/car/app/app-automotive/src/test/java/androidx/car/app/activity/ServiceDispatcherTest.java b/car/app/app-automotive/src/test/java/androidx/car/app/activity/ServiceDispatcherTest.java
index d02c077..10b285d 100644
--- a/car/app/app-automotive/src/test/java/androidx/car/app/activity/ServiceDispatcherTest.java
+++ b/car/app/app-automotive/src/test/java/androidx/car/app/activity/ServiceDispatcherTest.java
@@ -18,6 +18,7 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
@@ -90,6 +91,34 @@
}
@Test
+ public void dispatchNoFail_serviceBound_invoked() throws RemoteException {
+ IRendererService rendererService = mock(IRendererService.class);
+ Intent intent = mock(Intent.class);
+ ComponentName componentName = mock(ComponentName.class);
+
+
+ ServiceDispatcher.OneWayCall call = () -> rendererService.onNewIntent(intent,
+ componentName, 0);
+
+ mServiceDispatcher.setOnBindingListener(() -> true);
+ mServiceDispatcher.dispatchNoFail("test", call);
+
+ verify(rendererService, times(1)).onNewIntent(intent, componentName, 0);
+ }
+
+ @Test
+ public void dispatchNoFail_serviceThrowsError_errorHandlerNotInvoked() {
+ ServiceDispatcher.OneWayCall call = () -> {
+ throw new RemoteException();
+ };
+
+ mServiceDispatcher.setOnBindingListener(() -> true);
+ mServiceDispatcher.dispatchNoFail("test", call);
+
+ verify(mViewModel, never()).onError(any());
+ }
+
+ @Test
public void fetch_serviceBound_valueReturned() {
ServiceDispatcher.ReturnCall<Integer> call = () -> 123;