Merge "Move EvsView to the system window." into sc-dev
diff --git a/tests/CarEvsCameraPreviewApp/AndroidManifest.xml b/tests/CarEvsCameraPreviewApp/AndroidManifest.xml
index bf54d88..6e4c254 100644
--- a/tests/CarEvsCameraPreviewApp/AndroidManifest.xml
+++ b/tests/CarEvsCameraPreviewApp/AndroidManifest.xml
@@ -23,6 +23,8 @@
     <uses-permission android:name="android.car.permission.USE_CAR_EVS_CAMERA" />
     <uses-permission android:name="android.car.permission.MONITOR_CAR_EVS_STATUS" />
 
+    <uses-permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW" />
+
     <application android:label="@string/app_name"
             android:icon="@drawable/rearview"
             android:hardwareAccelerated="true"
@@ -31,11 +33,10 @@
         <activity android:name=".CarEvsCameraPreviewActivity"
                 android:exported="true"
                 android:label="@string/app_name"
-                android:launchMode="singleTask"
                 android:resizeableActivity="false"
                 android:screenOrientation="landscape"
                 android:showForAllUsers="true"
-                android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
+                android:theme="@style/Theme.Transparent"
                 android:turnScreenOn="true">
         </activity>
 
diff --git a/tests/CarEvsCameraPreviewApp/res/layout/evs_preview_activity.xml b/tests/CarEvsCameraPreviewApp/res/layout/evs_preview_activity.xml
index 5745d8d..bfd138b 100644
--- a/tests/CarEvsCameraPreviewApp/res/layout/evs_preview_activity.xml
+++ b/tests/CarEvsCameraPreviewApp/res/layout/evs_preview_activity.xml
@@ -10,21 +10,18 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:id="@+id/evs_preview_container"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:background="@android:color/transparent"
+              android:orientation="vertical">
+    <Button
+        android:id="@+id/close_button"
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:orientation="horizontal">
-      <TextureView
-        android:id="@+id/texture"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_alignParentTop="true" />
-      <SeekBar
-        android:id="@+id/saturationAdjustBar"
-        android:layout_width="600dp"
         android:layout_height="wrap_content"
-        android:layout_gravity="bottom|center_horizontal"
-        android:layout_marginBottom="100dp"
-        android:max="100"
-        android:progress="50"/>
-</FrameLayout>
+        android:text="@string/close_button_text"
+        android:textColor="@color/button_text"
+        android:background="@color/button_background"
+        android:textSize="@dimen/close_button_text_size"/>
+</LinearLayout>
diff --git a/tests/CarEvsCameraPreviewApp/res/values/colors.xml b/tests/CarEvsCameraPreviewApp/res/values/colors.xml
new file mode 100644
index 0000000..36632cb
--- /dev/null
+++ b/tests/CarEvsCameraPreviewApp/res/values/colors.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 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.
+  -->
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+    <color name="button_text">@*android:color/car_body1_light</color>
+    <color name="button_background">@*android:color/car_card_dark</color>
+</resources>
diff --git a/tests/CarEvsCameraPreviewApp/res/values/dimens.xml b/tests/CarEvsCameraPreviewApp/res/values/dimens.xml
new file mode 100644
index 0000000..35bc2c4
--- /dev/null
+++ b/tests/CarEvsCameraPreviewApp/res/values/dimens.xml
@@ -0,0 +1,22 @@
+<!--
+  ~ Copyright (C) 2021 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.
+  -->
+<resources>
+    <!-- dimensions for evs camera preview in the system window -->
+    <dimen name="camera_preview_width">800dp</dimen>
+    <dimen name="camera_preview_height">600dp</dimen>
+
+    <dimen name="close_button_text_size">30sp</dimen>
+</resources>
\ No newline at end of file
diff --git a/tests/CarEvsCameraPreviewApp/res/values/strings.xml b/tests/CarEvsCameraPreviewApp/res/values/strings.xml
index c386e1d..4653f01 100644
--- a/tests/CarEvsCameraPreviewApp/res/values/strings.xml
+++ b/tests/CarEvsCameraPreviewApp/res/values/strings.xml
@@ -17,4 +17,5 @@
 
 <resources>
     <string name="app_name">EvsCameraPreview</string>
+    <string name="close_button_text">Close</string>
 </resources>
diff --git a/tests/CarEvsCameraPreviewApp/res/values/themes.xml b/tests/CarEvsCameraPreviewApp/res/values/themes.xml
new file mode 100644
index 0000000..14b98bb
--- /dev/null
+++ b/tests/CarEvsCameraPreviewApp/res/values/themes.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 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.
+  -->
+<resources>
+    <style name="Theme.Transparent" parent="android:Theme">
+        <item name="android:windowIsTranslucent">true</item>
+        <item name="android:windowBackground">@android:color/transparent</item>
+        <item name="android:windowContentOverlay">@null</item>
+        <item name="android:windowNoTitle">true</item>
+        <item name="android:backgroundDimEnabled">false</item>
+    </style>
+</resources>
\ No newline at end of file
diff --git a/tests/CarEvsCameraPreviewApp/src/com/google/android/car/evs/CarEvsCameraPreviewActivity.java b/tests/CarEvsCameraPreviewApp/src/com/google/android/car/evs/CarEvsCameraPreviewActivity.java
index e34e4e8..bf6e950 100644
--- a/tests/CarEvsCameraPreviewApp/src/com/google/android/car/evs/CarEvsCameraPreviewActivity.java
+++ b/tests/CarEvsCameraPreviewApp/src/com/google/android/car/evs/CarEvsCameraPreviewActivity.java
@@ -25,12 +25,18 @@
 import android.car.evs.CarEvsBufferDescriptor;
 import android.car.evs.CarEvsManager;
 import android.content.Intent;
+import android.graphics.PixelFormat;
 import android.hardware.display.DisplayManager;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.util.Log;
 import android.view.Display;
+import android.view.Gravity;
+import android.view.LayoutInflater;
 import android.view.View;
+import android.view.WindowManager;
+import android.widget.Button;
+import android.widget.LinearLayout;
 
 import java.util.ArrayList;
 import java.util.concurrent.ExecutorService;
@@ -48,7 +54,8 @@
     private final ExecutorService mCallbackExecutor = Executors.newFixedThreadPool(1);
 
     /** GL backed surface view to render the camera preview */
-    private CarEvsCameraGLSurfaceView mView;
+    private CarEvsCameraGLSurfaceView mEvsView;
+    private LinearLayout mPreviewContainer;
 
     /** Display manager to monitor the display's state */
     private DisplayManager mDisplayManager;
@@ -59,13 +66,12 @@
     /** Tells whether or not a video stream is running */
     private boolean mStreamRunning = false;
 
-    /** True if we need to start a video stream */
-    private boolean mActivityResumed = false;
-
     private Car mCar;
     private CarEvsManager mEvsManager;
 
-    private IBinder mSessiontoken;
+    private IBinder mSessionToken;
+
+    private boolean mUseSystemWindow;
 
     /** Callback to listen to EVS stream */
     private final CarEvsManager.CarEvsStreamCallback mStreamHandler =
@@ -75,6 +81,9 @@
         public void onStreamEvent(int event) {
             // This reference implementation only monitors a stream event without any action.
             Log.i(TAG, "Received: " + event);
+            if (event == CarEvsManager.STREAM_EVENT_STREAM_STOPPED) {
+                finish();
+            }
         }
 
         @Override
@@ -141,6 +150,8 @@
         Log.d(TAG, "onCreate");
         super.onCreate(savedInstanceState);
 
+        parseExtra(getIntent());
+
         setShowWhenLocked(true);
         mDisplayManager = getSystemService(DisplayManager.class);
         mDisplayManager.registerDisplayListener(mDisplayListener, null);
@@ -152,83 +163,97 @@
         Car.createCar(getApplicationContext(), /* handler = */ null,
                 Car.CAR_WAIT_TIMEOUT_WAIT_FOREVER, mCarServiceLifecycleListener);
 
-        mView = new CarEvsCameraGLSurfaceView(getApplication(), this);
-        setContentView(mView);
+        mEvsView = new CarEvsCameraGLSurfaceView(getApplication(), this);
+        mPreviewContainer = (LinearLayout) LayoutInflater.from(this).inflate(
+                R.layout.evs_preview_activity, /* root= */ null);
+        LinearLayout.LayoutParams viewParam = new LinearLayout.LayoutParams(
+                LinearLayout.LayoutParams.MATCH_PARENT,
+                LinearLayout.LayoutParams.MATCH_PARENT,
+                1.0f
+        );
+        mEvsView.setLayoutParams(viewParam);
+        mPreviewContainer.addView(mEvsView, 0);
+        Button closeButton = mPreviewContainer.findViewById(R.id.close_button);
+        closeButton.setOnClickListener((v) -> finish());
 
-        setSessionToken(getIntent());
+        int width = WindowManager.LayoutParams.MATCH_PARENT;
+        int height = WindowManager.LayoutParams.MATCH_PARENT;
+        int x = 0;
+        int y = 0;
+        if (mUseSystemWindow) {
+            width = getResources().getDimensionPixelOffset(R.dimen.camera_preview_width);
+            height = getResources().getDimensionPixelOffset(R.dimen.camera_preview_height);
+            x = (getResources().getDisplayMetrics().widthPixels - width) / 2;
+            y = (getResources().getDisplayMetrics().heightPixels - height) / 2;
+        }
+        WindowManager.LayoutParams params = new WindowManager.LayoutParams(
+                width, height, x, y,
+                2020 /* WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY */,
+                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+                        | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
+                PixelFormat.TRANSLUCENT);
+        params.gravity = Gravity.LEFT | Gravity.TOP;
+        if (mUseSystemWindow) {
+            WindowManager wm = getSystemService(WindowManager.class);
+            wm.addView(mPreviewContainer, params);
+        } else {
+            setContentView(mPreviewContainer, params);
+        }
     }
 
     @Override
     protected void onNewIntent(Intent intent) {
         super.onNewIntent(intent);
-        setSessionToken(intent);
+        parseExtra(intent);
     }
 
-    private void setSessionToken(Intent intent) {
+    private void parseExtra(Intent intent) {
         Bundle extras = intent.getExtras();
         if (extras == null) {
-            mSessiontoken = null;
+            mSessionToken = null;
             return;
         }
-        mSessiontoken = extras.getBinder(CarEvsManager.EXTRA_SESSION_TOKEN);
+        mSessionToken = extras.getBinder(CarEvsManager.EXTRA_SESSION_TOKEN);
+        mUseSystemWindow = mSessionToken != null;
     }
 
     @Override
     protected void onStart() {
         Log.d(TAG, "onStart");
         super.onStart();
+        handleVideoStreamLocked();
     }
 
-    @Override
-    protected void onResume() {
-        Log.d(TAG, "onResume");
-        super.onResume();
-
-        synchronized (mLock) {
-            mActivityResumed = true;
-            handleVideoStreamLocked();
-        }
-    }
-
-    @Override
-    protected void onPause() {
-        Log.d(TAG, "onPause");
-        super.onPause();
-
-        synchronized (mLock) {
-            mActivityResumed = false;
-            handleVideoStreamLocked();
-        }
-
-        synchronized (mBufferQueue) {
-            mBufferQueue.clear();
-        }
-    }
 
     @Override
     protected void onStop() {
         Log.d(TAG, "onStop");
         super.onStop();
-
-        // Request to stop current service and unregister a status listener
-        synchronized (mLock) {
-            if (mEvsManager != null) {
-                mEvsManager.stopActivity();
-                mEvsManager.clearStatusListener();
-            }
-        }
     }
 
     @Override
     protected void onDestroy() {
         super.onDestroy();
         Log.d(TAG, "onDestroy");
+        // Request to stop current service and unregister a status listener
+        synchronized (mBufferQueue) {
+            mBufferQueue.clear();
+        }
         synchronized (mLock) {
+            if (mEvsManager != null) {
+                mEvsManager.stopVideoStream();
+                mEvsManager.stopActivity();
+                mEvsManager.clearStatusListener();
+            }
             if (mCar != null) {
                 mCar.disconnect();
             }
         }
         mDisplayManager.unregisterDisplayListener(mDisplayListener);
+        if (mUseSystemWindow) {
+            WindowManager wm = getSystemService(WindowManager.class);
+            wm.removeView(mPreviewContainer);
+        }
     }
 
     private void handleVideoStreamLocked() {
@@ -237,13 +262,13 @@
             return;
         }
 
-        if (mActivityResumed && mDisplayState == Display.STATE_ON) {
+        if (mDisplayState == Display.STATE_ON) {
             // We show a camera preview only when the activity has been resumed and the display is
             // on.
             if (!mStreamRunning) {
                 Log.d(TAG, "Request to start a video stream");
                 mEvsManager.startVideoStream(CarEvsManager.SERVICE_TYPE_REARVIEW,
-                        mSessiontoken, mCallbackExecutor, mStreamHandler);
+                        mSessionToken, mCallbackExecutor, mStreamHandler);
                 mStreamRunning = true;
             }