1b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher/* 2b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher * Copyright (C) 2014 The Android Open Source Project 3b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher * 4b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher * Licensed under the Apache License, Version 2.0 (the "License"); 5b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher * you may not use this file except in compliance with the License. 6b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher * You may obtain a copy of the License at 7b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher * 8b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher * http://www.apache.org/licenses/LICENSE-2.0 9b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher * 10b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher * Unless required by applicable law or agreed to in writing, software 11b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher * distributed under the License is distributed on an "AS IS" BASIS, 12b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher * See the License for the specific language governing permissions and 14b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher * limitations under the License. 15b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher */ 16b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher 17b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucherpackage com.example.android.camera2.cameratoo; 18b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher 19b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucherimport static org.junit.Assert.assertEquals; 20b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucherimport static org.junit.Assert.assertTrue; 21b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucherimport static org.mockito.Mockito.mock; 22b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucherimport static org.mockito.Mockito.when; 23b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher 24b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucherimport android.media.Image; 25b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucherimport android.os.Environment; 26b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucherimport android.util.Size; 27b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher 28b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucherimport java.io.File; 29b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucherimport java.io.FileInputStream; 30b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucherimport java.io.FileNotFoundException; 31b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucherimport java.io.FilenameFilter; 32b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucherimport java.io.IOException; 33b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucherimport java.nio.ByteBuffer; 34b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucherimport java.util.Arrays; 35b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucherimport java.util.Comparator; 36b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucherimport java.util.HashSet; 37b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucherimport java.util.Set; 38b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher 39b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucherimport com.example.android.camera2.cameratoo.CameraTooActivity; 40b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucherimport org.junit.Test; 41b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher 42b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucherpublic class CameraTooTest { 43b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher private <T> void assertComparatorEq(T lhs, T rhs, Comparator<T> rel) { 44b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertEquals(String.format("%s should be equal to %s", lhs, rhs), rel.compare(lhs, rhs), 0); 45b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertEquals(String.format("%s should be equal to %s (reverse check)", lhs, rhs), 46b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher rel.compare(rhs, lhs), 0); 47b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher } 48b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher 49b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher private <T> void assertComparatorLt(T lhs, T rhs, Comparator<T> rel) { 50b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertTrue(String.format("%s should be less than %s", lhs, rhs), rel.compare(lhs, rhs) < 0); 51b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertTrue(String.format("%s should be less than %s (reverse check)", lhs, rhs), 52b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher rel.compare(rhs, lhs) > 0); 53b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher } 54b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher 55b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher @Test 56b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher public void compareSizesByArea() { 57b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher Size empty = new Size(0, 0), fatAndFlat = new Size(100, 0), tallAndThin = new Size(0, 100); 58b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher Size smallSquare = new Size(4, 4), horizRect = new Size(8, 2), vertRect = new Size(2, 8); 59b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher Size largeSquare = new Size(5, 5); 60b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher Comparator<Size> rel = new CameraTooActivity.CompareSizesByArea(); 61b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher 62b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertComparatorEq(empty, fatAndFlat, rel); 63b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertComparatorEq(empty, tallAndThin, rel); 64b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertComparatorEq(fatAndFlat, empty, rel); 65b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertComparatorEq(fatAndFlat, tallAndThin, rel); 66b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertComparatorEq(tallAndThin, empty, rel); 67b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertComparatorEq(tallAndThin, fatAndFlat, rel); 68b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher 69b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertComparatorEq(smallSquare, horizRect, rel); 70b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertComparatorEq(smallSquare, vertRect, rel); 71b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertComparatorEq(horizRect, smallSquare, rel); 72b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertComparatorEq(horizRect, vertRect, rel); 73b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertComparatorEq(vertRect, smallSquare, rel); 74b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertComparatorEq(vertRect, horizRect, rel); 75b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher 76b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertComparatorLt(empty, smallSquare, rel); 77b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertComparatorLt(empty, horizRect, rel); 78b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertComparatorLt(empty, vertRect, rel); 79b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher 80b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertComparatorLt(fatAndFlat, smallSquare, rel); 81b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertComparatorLt(fatAndFlat, horizRect, rel); 82b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertComparatorLt(fatAndFlat, vertRect, rel); 83b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher 84b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertComparatorLt(tallAndThin, smallSquare, rel); 85b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertComparatorLt(tallAndThin, horizRect, rel); 86b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertComparatorLt(tallAndThin, vertRect, rel); 87b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher 88b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertComparatorLt(empty, largeSquare, rel); 89b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertComparatorLt(fatAndFlat, largeSquare, rel); 90b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertComparatorLt(tallAndThin, largeSquare, rel); 91b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertComparatorLt(smallSquare, largeSquare, rel); 92b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertComparatorLt(horizRect, largeSquare, rel); 93b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertComparatorLt(vertRect, largeSquare, rel); 94b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher } 95b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher 96b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher private void assertOptimalSize(Size[] options, int minWidth, int minHeight, Size expected) { 97b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher Size verdict = CameraTooActivity.chooseBigEnoughSize(options, minWidth, minHeight); 98b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertEquals(String.format("Expected optimal size %s but got %s", expected, verdict), 99b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher verdict, expected); 100b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher } 101b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher 102b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher @Test 103b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher public void chooseBigEnoughSize() { 104b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher Size empty = new Size(0, 0), fatAndFlat = new Size(100, 0), tallAndThin = new Size(0, 100); 105b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher Size smallSquare = new Size(4, 4), horizRect = new Size(8, 2), vertRect = new Size(2, 8); 106b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher Size largeSquare = new Size(5, 5); 107b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher Size[] siz = 108b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher { empty, fatAndFlat, tallAndThin, smallSquare, horizRect, vertRect, largeSquare }; 109b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher 110b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertOptimalSize(siz, 0, 0, empty); 111b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher 112b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertOptimalSize(siz, 1, 0, fatAndFlat); 113b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertOptimalSize(siz, 0, 1, tallAndThin); 114b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher 115b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertOptimalSize(siz, 4, 4, smallSquare); 116b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertOptimalSize(siz, 1, 1, smallSquare); 117b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertOptimalSize(siz, 2, 1, smallSquare); 118b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertOptimalSize(siz, 1, 2, smallSquare); 119b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertOptimalSize(siz, 3, 4, smallSquare); 120b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertOptimalSize(siz, 4, 3, smallSquare); 121b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher 122b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertOptimalSize(siz, 8, 2, horizRect); 123b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertOptimalSize(siz, 5, 1, horizRect); 124b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertOptimalSize(siz, 5, 2, horizRect); 125b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher 126b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertOptimalSize(siz, 2, 8, vertRect); 127b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertOptimalSize(siz, 1, 5, vertRect); 128b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertOptimalSize(siz, 2, 5, vertRect); 129b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher 130b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertOptimalSize(siz, 5, 5, largeSquare); 131b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertOptimalSize(siz, 3, 5, largeSquare); 132b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertOptimalSize(siz, 5, 3, largeSquare); 133b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher } 134b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher 135b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher private static final FilenameFilter OUTPUT_FILE_DECIDER = new FilenameFilter() { 136b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher @Override 137b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher public boolean accept(File dir, String filename) { 138b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher return filename.indexOf("cameratoo") == 0 && 139b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher filename.indexOf(".jpg") == filename.length() - ".jpg".length(); 140b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher }}; 141b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher 142b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher private static <T> Set<T> newlyAddedElements(Set<T> before, Set<T> after) { 143b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher Set<T> result = new HashSet<T>(after); 144b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher result.removeAll(before); 145b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher return result; 146b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher } 147b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher 148b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher @Test 149b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher public void capturedImageSaver() throws FileNotFoundException, IOException { 150b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher ByteBuffer buf = ByteBuffer.allocate(25); 151b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher for(int index = 0; index < buf.capacity(); ++index) 152b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher buf.put(index, (byte) index); 153b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher 154b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher Image.Plane plane = mock(Image.Plane.class); 155b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher when(plane.getBuffer()).thenReturn(buf); 156b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher when(plane.getPixelStride()).thenReturn(1); 157b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher when(plane.getRowStride()).thenReturn(5); 158b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher 159b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher Image.Plane[] onlyPlaneThatMatters = { plane }; 160b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher Image image = mock(Image.class); 161b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher when(image.getPlanes()).thenReturn(onlyPlaneThatMatters); 162b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher when(image.getWidth()).thenReturn(5); 163b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher when(image.getHeight()).thenReturn(5); 164b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher 165b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher File picturesFolder = 166b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES); 167b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher Set<File> preListing = 168b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher new HashSet<File>(Arrays.asList(picturesFolder.listFiles(OUTPUT_FILE_DECIDER))); 169b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher 170b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher CameraTooActivity.CapturedImageSaver saver = 171b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher new CameraTooActivity.CapturedImageSaver(image); 172b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher saver.run(); 173b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher 174b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher Set<File> postListing = 175b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher new HashSet<File>(Arrays.asList(picturesFolder.listFiles(OUTPUT_FILE_DECIDER))); 176b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher Set<File> newFiles = newlyAddedElements(preListing, postListing); 177b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher 178b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertEquals(newFiles.size(), 1); 179b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher 180b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher File picture = newFiles.iterator().next(); 181b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher FileInputStream istream = new FileInputStream(picture); 182b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher 183b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher for(int count = 0; count < buf.capacity(); ++count) { 184b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertEquals(istream.read(), buf.get(count)); 185b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher } 186b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertEquals(istream.read(), -1); 187b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher assertTrue(picture.delete()); 188b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher } 189b84fdffad40226ca642680c7d1eec7c7799f07aaSol Boucher} 190