Camera: add next button to improve camera video test

Users click next button to set next resolution of current camera to test.

Bug: 135241427
Test: manual test

Change-Id: Ibb8147d1aeefaaea4bfc33982f4b03bb62510332
Merged-In: Ibb8147d1aeefaaea4bfc33982f4b03bb62510332
diff --git a/apps/CtsVerifier/res/layout/camera_video.xml b/apps/CtsVerifier/res/layout/camera_video.xml
index b81721b..5dd28ab 100644
--- a/apps/CtsVerifier/res/layout/camera_video.xml
+++ b/apps/CtsVerifier/res/layout/camera_video.xml
@@ -85,19 +85,39 @@
                 android:id="@+id/resolution_selection"
                 android:layout_width="fill_parent"
                 android:layout_height="wrap_content"/>
-            <Button
-                android:id="@+id/record_button"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:text="@string/record_button_text"/>
-            <TextView
-                android:id="@+id/status_label"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:text="@string/status_ready"
-                android:padding="2dp"
-                android:textSize="16sp"
-                android:gravity="center" />
+
+            <LinearLayout
+                android:orientation="horizontal"
+                android:layout_width="match_parent"
+                android:layout_height="0dp"
+                android:layout_weight="1" >
+
+                <Button
+                    android:id="@+id/record_button"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/record_button_text"/>
+                <Button
+                    android:id="@+id/next_button"
+                    android:layout_height="wrap_content"
+                    android:layout_width="wrap_content"
+                    android:text="@string/cf_next_button" />
+            </LinearLayout>
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="0dp"
+                android:layout_weight="2" >
+
+                <TextView
+                    android:id="@+id/status_label"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/status_ready"
+                    android:padding="2dp"
+                    android:textSize="16sp"
+                    android:gravity="center" />
+            </LinearLayout>
 
         </LinearLayout>
 
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index 4c25df8..0a4785a 100755
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -1210,10 +1210,11 @@
     seconds of video recording. Playback will show up in the right view
     window after recording is complete. \n - Use the spinners to choose
     camera and resolution combinations. The playback should be similar
-    to what you saw in preview. \n - After all possible combinations
-    are tested, the pass button will be enabled. You may press the pass
-    button to indicate a pass. \n - You may press fail button any time during
-    the test to indicate failure.
+    to what you saw in preview. \n - The next button triggers test for the next
+    untested resolution of the currently selected camera. - After all possible
+    combinations are tested, the pass button will be enabled. You may press the
+    pass button to indicate a pass. \n - You may press fail button any time
+    during the test to indicate failure. \n
     </string>
     <string name="video_capture_label">Video capture</string>
     <string name="video_playback_label">Video playback</string>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/video/CameraVideoActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/video/CameraVideoActivity.java
index ddd949a..e8bdcc7 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/video/CameraVideoActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/video/CameraVideoActivity.java
@@ -56,6 +56,7 @@
 import java.util.Comparator;
 import java.util.Date;
 import java.util.List;
+import java.util.Optional;
 import java.util.TreeSet;
 
 
@@ -105,11 +106,34 @@
 
     private TextView mStatusLabel;
 
-    private TreeSet<String> mTestedCombinations = new TreeSet<String>();
-    private TreeSet<String> mUntestedCombinations = new TreeSet<String>();
+    private TreeSet<CameraCombination> mTestedCombinations = new TreeSet<>(COMPARATOR);
+    private TreeSet<CameraCombination> mUntestedCombinations = new TreeSet<>(COMPARATOR);
+    private TreeSet<String> mUntestedCameras = new TreeSet<>();
 
     private File outputVideoFile;
 
+    private class CameraCombination {
+        private final int mCameraIndex;
+        private final int mVideoSizeIdIndex;
+        private final String mVideoSizeName;
+
+        private CameraCombination(
+            int cameraIndex, int videoSizeIdIndex, String videoSizeName) {
+            this.mCameraIndex = cameraIndex;
+            this.mVideoSizeIdIndex = videoSizeIdIndex;
+            this.mVideoSizeName = videoSizeName;
+        }
+
+        @Override
+        public String toString() {
+            return String.format("Camera %d, %s", mCameraIndex, mVideoSizeName);
+        }
+    }
+
+    private static final Comparator<CameraCombination> COMPARATOR =
+        Comparator.<CameraCombination, Integer>comparing(c -> c.mCameraIndex)
+            .thenComparing(c -> c.mVideoSizeIdIndex);
+
     /**
      * @see #MEDIA_TYPE_IMAGE
      * @see #MEDIA_TYPE_VIDEO
@@ -274,7 +298,7 @@
         String[] cameraNames = new String[numCameras];
         for (int i = 0; i < numCameras; i++) {
             cameraNames[i] = "Camera " + i;
-            mUntestedCombinations.add("All combinations for Camera " + i + "\n");
+            mUntestedCameras.add("All combinations for Camera " + i + "\n");
         }
         if (VERBOSE) {
             Log.v(TAG, "onCreate: number of cameras=" + numCameras);
@@ -289,6 +313,45 @@
         mResolutionSpinner.setOnItemSelectedListener(mResolutionSelectedListener);
 
         mStatusLabel = (TextView) findViewById(R.id.status_label);
+
+        Button mNextButton = (Button) findViewById(R.id.next_button);
+        mNextButton.setOnClickListener(v -> {
+            setUntestedCombination();
+            if (VERBOSE) {
+                Log.v(TAG, "onClick: mCurrentVideoSizeId = " +
+                    mCurrentVideoSizeId + " " + mCurrentVideoSizeName);
+                Log.v(TAG, "onClick: setting preview size "
+                    + mNextPreviewSize.width + "x" + mNextPreviewSize.height);
+            }
+
+            startPreview();
+            if (VERBOSE) {
+                Log.v(TAG, "onClick: started new preview");
+            }
+            captureButton.performClick();
+        });
+    }
+
+    /**
+     * Set an untested combination of the current camera and video size.
+     * Triggered by next button click.
+     */
+    private void setUntestedCombination() {
+        Optional<CameraCombination> combination = mUntestedCombinations.stream().filter(
+            c -> c.mCameraIndex == mCurrentCameraId).findFirst();
+        if (!combination.isPresent()) {
+            Toast.makeText(this, "All Camera " + mCurrentCameraId + " tests are done.",
+                Toast.LENGTH_SHORT).show();
+            return;
+        }
+
+        // There is untested combination for the current camera, set the next untested combination.
+        int mNextVideoSizeIdIndex = combination.get().mVideoSizeIdIndex;
+
+        mCurrentVideoSizeId = mVideoSizeIds.get(mNextVideoSizeIdIndex);
+        mCurrentVideoSizeName = mVideoSizeNames.get(mNextVideoSizeIdIndex);
+        mNextPreviewSize = matchPreviewRecordSize();
+        mResolutionSpinner.setSelection(mNextVideoSizeIdIndex);
     }
 
     @Override
@@ -348,12 +411,17 @@
     public String getTestDetails() {
         StringBuilder reportBuilder = new StringBuilder();
         reportBuilder.append("Tested combinations:\n");
-        for (String combination : mTestedCombinations) {
+        for (CameraCombination combination: mTestedCombinations) {
             reportBuilder.append(combination);
+            reportBuilder.append("\n");
         }
         reportBuilder.append("Untested combinations:\n");
-        for (String combination : mUntestedCombinations) {
+        for (String untestedCam : mUntestedCameras) {
+            reportBuilder.append(untestedCam);
+        }
+        for (CameraCombination combination: mUntestedCombinations) {
             reportBuilder.append(combination);
+            reportBuilder.append("\n");
         }
         return reportBuilder.toString();
     }
@@ -468,8 +536,12 @@
                                     isPlayingBack = true;
                                     mStatusLabel.setText(getResources()
                                             .getString(R.string.status_playback));
-                                    String combination = "Camera " + mCurrentCameraId + ", " +
-                                            mCurrentVideoSizeName + "\n";
+
+                                    int resIdx = mResolutionSpinner.getSelectedItemPosition();
+                                    CameraCombination combination = new CameraCombination(
+                                            mCurrentCameraId, resIdx,
+                                            mVideoSizeNames.get(resIdx));
+
                                     mUntestedCombinations.remove(combination);
                                     mTestedCombinations.add(combination);
 
@@ -750,9 +822,13 @@
                 this, R.layout.cf_format_list_item, availableVideoSizeNames));
 
         // Update untested
-        mUntestedCombinations.remove("All combinations for Camera " + id + "\n");
-        for (String videoSizeName : mVideoSizeNames) {
-            String combination = "Camera " + id + ", " + videoSizeName + "\n";
+        mUntestedCameras.remove("All combinations for Camera " + id + "\n");
+
+        for (int videoSizeIdIndex = 0;
+                videoSizeIdIndex < mVideoSizeIds.size(); videoSizeIdIndex++) {
+            CameraCombination combination = new CameraCombination(
+                id, videoSizeIdIndex, mVideoSizeNames.get(videoSizeIdIndex));
+
             if (!mTestedCombinations.contains(combination)) {
                 mUntestedCombinations.add(combination);
             }