1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.csuite.core;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import com.android.csuite.core.BlankScreenDetectorWithSameColorRectangle.BlankScreen;
22 import com.android.tradefed.log.LogUtil.CLog;
23 
24 import org.junit.Assert;
25 import org.junit.Test;
26 import org.junit.runner.RunWith;
27 import org.junit.runners.JUnit4;
28 
29 import java.awt.Color;
30 import java.awt.Graphics2D;
31 import java.awt.Rectangle;
32 import java.awt.image.BufferedImage;
33 import java.io.IOException;
34 import java.nio.file.Path;
35 
36 import javax.imageio.ImageIO;
37 
38 @RunWith(JUnit4.class)
39 public class BlankScreenDetectorWithSameColorRectangleTest {
40 
41     @Test
maxSubRectangle_returnsBiggestSubRectangle()42     public void maxSubRectangle_returnsBiggestSubRectangle() {
43         int[] row = {1, 0, 2};
44         int index = 2;
45 
46         Rectangle subRectangle =
47                 BlankScreenDetectorWithSameColorRectangle.maxSubRectangle(row, index);
48 
49         assertThat(subRectangle.getX()).isEqualTo(2);
50         assertThat(subRectangle.getY()).isEqualTo(1);
51     }
52 
53     @Test
maxSubRectangle_withWideThinRectangle_returnsBiggestSubRectangle()54     public void maxSubRectangle_withWideThinRectangle_returnsBiggestSubRectangle() {
55         int[] row = {1, 3, 4, 3, 1, 2, 3, 5, 2};
56         int index = 4;
57 
58         Rectangle subRectangle =
59                 BlankScreenDetectorWithSameColorRectangle.maxSubRectangle(row, index);
60 
61         assertThat(subRectangle.getWidth() * subRectangle.getHeight()).isEqualTo(9);
62         assertThat(subRectangle.getX()).isEqualTo(1);
63         assertThat(subRectangle.getY()).isEqualTo(2);
64     }
65 
66     @Test
maxSubRectangle_withOffsetIndex_returnsBiggestSubRectangle()67     public void maxSubRectangle_withOffsetIndex_returnsBiggestSubRectangle() {
68         int[] row = {3, 2, 5, 0};
69         int index = 5;
70 
71         Rectangle subRectangle =
72                 BlankScreenDetectorWithSameColorRectangle.maxSubRectangle(row, index);
73 
74         assertThat(subRectangle.getWidth() * subRectangle.getHeight()).isEqualTo(6);
75         assertThat(subRectangle.getX()).isEqualTo(0);
76         assertThat(subRectangle.getY()).isEqualTo(4);
77     }
78 
79     @Test
maxSameColorRectangle_withFullSameColorRectangle_returnsSameSize()80     public void maxSameColorRectangle_withFullSameColorRectangle_returnsSameSize() {
81         BufferedImage image = new BufferedImage(100, 50, BufferedImage.TYPE_INT_RGB);
82         Rectangle rectangle = new Rectangle(0, 0, 100, 50);
83         drawRectangles(image, rectangle);
84 
85         Rectangle maxRectangle =
86                 BlankScreenDetectorWithSameColorRectangle.maxSameColorRectangle(image);
87 
88         assertThat(maxRectangle.getWidth() * rectangle.getHeight()).isEqualTo(100 * 50);
89         assertThat(maxRectangle.getX()).isEqualTo(0);
90         assertThat(maxRectangle.getY()).isEqualTo(0);
91     }
92 
93     @Test
maxSameColorRectangle_withBottomScreenBand_returnsLargestRectangle()94     public void maxSameColorRectangle_withBottomScreenBand_returnsLargestRectangle() {
95         int imageWidth = 100;
96         int imageHeight = 200;
97         int barWidth = 100;
98         int barHeight = 20;
99         BufferedImage image =
100                 new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB);
101         drawRectangles(image, new Rectangle(0, imageHeight - barHeight, barWidth, barHeight));
102 
103         Rectangle rectangle =
104                 BlankScreenDetectorWithSameColorRectangle.maxSameColorRectangle(image);
105 
106         assertThat(rectangle.getWidth() * rectangle.getHeight())
107                 .isEqualTo((imageHeight - barHeight) * imageWidth);
108         assertThat(rectangle.getX()).isEqualTo(0);
109         assertThat(rectangle.getY()).isEqualTo(0);
110     }
111 
112     @Test
maxSameColorRectangle_withTopScreenBand_returnsLargestRectangle()113     public void maxSameColorRectangle_withTopScreenBand_returnsLargestRectangle() {
114         int imageWidth = 100;
115         int imageHeight = 200;
116         int barWidth = 100;
117         int barHeight = 20;
118         BufferedImage image =
119                 new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB);
120         drawRectangles(image, new Rectangle(0, 0, barWidth, barHeight));
121 
122         Rectangle rectangle =
123                 BlankScreenDetectorWithSameColorRectangle.maxSameColorRectangle(image);
124 
125         assertThat(rectangle.getWidth() * rectangle.getHeight())
126                 .isEqualTo((imageHeight - barHeight) * imageWidth);
127         assertThat(rectangle.getX()).isEqualTo(0);
128         assertThat(rectangle.getY()).isEqualTo(barHeight);
129     }
130 
131     @Test
maxSameColorRectangle_withLowerLeftRectangle_returnsLargestRectangle()132     public void maxSameColorRectangle_withLowerLeftRectangle_returnsLargestRectangle() {
133         int imageWidth = 100;
134         int imageHeight = 60;
135         Rectangle smallRectangle = new Rectangle(30, 30, 10, 20);
136         BufferedImage image =
137                 new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB);
138         drawRectangles(image, smallRectangle);
139 
140         Rectangle rectangle =
141                 BlankScreenDetectorWithSameColorRectangle.maxSameColorRectangle(image);
142 
143         assertThat(rectangle.getWidth() * rectangle.getHeight())
144                 .isEqualTo((imageWidth - smallRectangle.x - smallRectangle.width) * imageHeight);
145         assertThat(rectangle.x).isEqualTo(smallRectangle.x + smallRectangle.width);
146         assertThat(rectangle.y).isEqualTo(0);
147     }
148 
149     @Test
maxSameColorRectangle_withFourRectangles_returnsLargestRectangle()150     public void maxSameColorRectangle_withFourRectangles_returnsLargestRectangle() {
151         int imageWidth = 100;
152         int imageHeight = 60;
153         Rectangle r1 = new Rectangle(30, 20, 10, 10);
154         Rectangle r2 = new Rectangle(20, 40, 10, 10);
155         Rectangle r3 = new Rectangle(70, 10, 10, 10);
156         Rectangle r4 = new Rectangle(90, 40, 10, 10);
157         BufferedImage image =
158                 new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB);
159         drawRectangles(image, r1, r2, r3, r4);
160 
161         Rectangle rectangle =
162                 BlankScreenDetectorWithSameColorRectangle.maxSameColorRectangle(image);
163 
164         assertThat(rectangle.getWidth() * rectangle.getHeight()).isEqualTo(50 * 40);
165         assertThat(rectangle.x).isEqualTo(40);
166         assertThat(rectangle.y).isEqualTo(20);
167     }
168 
169     @Test
getBlankScreen_withFullScreenAndBlank_returnsHighRatio()170     public void getBlankScreen_withFullScreenAndBlank_returnsHighRatio() {
171         Path imagePath = Path.of("BlankScreenWithFullScreen.png");
172 
173         BlankScreen blankScreen =
174                 BlankScreenDetectorWithSameColorRectangle.getBlankScreen(readImage(imagePath));
175 
176         assertThat(blankScreen.getBlankScreenPercent()).isGreaterThan(0.7);
177     }
178 
179     @Test
getBlankScreen_withNavBarsAndBlank_returnsHighRatio()180     public void getBlankScreen_withNavBarsAndBlank_returnsHighRatio() {
181         Path imagePath = Path.of("BlankScreenWithNavBars.png");
182 
183         BlankScreen blankScreen =
184                 BlankScreenDetectorWithSameColorRectangle.getBlankScreen(readImage(imagePath));
185 
186         assertThat(blankScreen.getBlankScreenPercent()).isGreaterThan(0.7);
187     }
188 
189     @Test
getBlankScreen_withWhiteScreenAndBlank_returnsHighRatio()190     public void getBlankScreen_withWhiteScreenAndBlank_returnsHighRatio() {
191         Path imagePath = Path.of("BlankScreenWithWhiteScreen.png");
192 
193         BlankScreen blankScreen =
194                 BlankScreenDetectorWithSameColorRectangle.getBlankScreen(readImage(imagePath));
195 
196         assertThat(blankScreen.getBlankScreenPercent()).isGreaterThan(0.7);
197     }
198 
199     @Test
getBlankScreen_hasNormalScreen_returnsLowRatio()200     public void getBlankScreen_hasNormalScreen_returnsLowRatio() {
201         Path imagePath = Path.of("NotBlankScreen.png");
202 
203         BlankScreen blankScreen =
204                 BlankScreenDetectorWithSameColorRectangle.getBlankScreen(readImage(imagePath));
205 
206         assertThat(blankScreen.getBlankScreenPercent()).isLessThan(0.7);
207     }
208 
drawRectangles(BufferedImage image, Rectangle... rectangles)209     private void drawRectangles(BufferedImage image, Rectangle... rectangles) {
210         Graphics2D graphic = image.createGraphics();
211         graphic.setColor(Color.BLUE);
212         for (Rectangle rectangle : rectangles) {
213             graphic.fillRect(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
214         }
215         graphic.dispose();
216     }
217 
readImage(Path path)218     private BufferedImage readImage(Path path) {
219         BufferedImage image = null;
220         try {
221             image = ImageIO.read(path.toFile());
222         } catch (IOException e) {
223             CLog.e("Failed to read the image at path: " + path.toString());
224             Assert.fail();
225         }
226         return image;
227     }
228 }
229