1 /* 2 * Copyright (C) 2020 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.providers.media.util; 18 19 import android.media.ExifInterface; 20 21 import org.junit.Test; 22 23 import java.io.File; 24 import java.util.concurrent.CountDownLatch; 25 import java.util.concurrent.TimeUnit; 26 import java.util.concurrent.atomic.AtomicInteger; 27 import java.util.function.ToLongFunction; 28 29 import static org.junit.Assert.assertEquals; 30 31 public class ExifUtilsTest { 32 @Test testConstructor()33 public void testConstructor() { 34 new ExifUtils(); 35 } 36 37 @Test testGetDateTime()38 public void testGetDateTime() throws Exception { 39 final ExifInterface exif = createTestExif(); 40 assertParseDateTime(exif, ExifUtils::getDateTime); 41 } 42 43 @Test testGetDateTimeOriginal()44 public void testGetDateTimeOriginal() throws Exception { 45 final ExifInterface exif = createTestExif(); 46 assertParseDateTime(exif, ExifUtils::getDateTimeOriginal); 47 } 48 49 @Test testGetDateTimeDigitized()50 public void testGetDateTimeDigitized() throws Exception { 51 final ExifInterface exif = createTestExif(); 52 assertParseDateTime(exif, ExifUtils::getDateTimeDigitized); 53 } 54 55 @Test testGetGpsDateTime()56 public void testGetGpsDateTime() throws Exception { 57 final ExifInterface exif = createTestExif(); 58 assertParseDateTime(exif, ExifUtils::getGpsDateTime); 59 } 60 createTestExif()61 private ExifInterface createTestExif() throws Exception { 62 final File file = File.createTempFile("test", ".jpg"); 63 final ExifInterface exif = new ExifInterface(file); 64 exif.setAttribute(ExifInterface.TAG_DATETIME, "2016:01:28 09:17:34"); 65 exif.setAttribute(ExifInterface.TAG_DATETIME_ORIGINAL, "2016:01:28 09:17:34"); 66 exif.setAttribute(ExifInterface.TAG_DATETIME_DIGITIZED, "2016:01:28 09:17:34 UTC"); 67 exif.setAttribute(ExifInterface.TAG_GPS_DATESTAMP, "2016:01:28"); 68 exif.setAttribute(ExifInterface.TAG_GPS_TIMESTAMP, "09:14:00"); 69 return exif; 70 } 71 assertParseDateTime(ExifInterface exif, ToLongFunction<ExifInterface> func)72 private void assertParseDateTime(ExifInterface exif, ToLongFunction<ExifInterface> func) { 73 final int numOfThreads = 5; 74 final CountDownLatch latch = new CountDownLatch(numOfThreads); 75 final AtomicInteger count = new AtomicInteger(numOfThreads); 76 77 for (int i = 0; i < numOfThreads; i++) { 78 new Thread(() -> { 79 if (parseDateTime(exif, func)) count.decrementAndGet(); 80 latch.countDown(); 81 }).start(); 82 } 83 84 try { 85 latch.await(10, TimeUnit.SECONDS); 86 } catch (InterruptedException ignored) { 87 } 88 89 assertEquals(0, count.get()); 90 } 91 parseDateTime(ExifInterface exif, ToLongFunction<ExifInterface> func)92 private boolean parseDateTime(ExifInterface exif, ToLongFunction<ExifInterface> func) { 93 final long expected = func.applyAsLong(exif); 94 try { 95 for (int i = 0; i < 1000; ++i) { 96 final long actual = func.applyAsLong(exif); 97 if (expected != actual) { 98 return false; 99 } 100 } 101 } catch (ArrayIndexOutOfBoundsException | NumberFormatException e) { 102 return false; 103 } 104 return true; 105 } 106 } 107 108