[go: nahoru, domu]

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;