Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fd1323e7 authored by Ken Narita's avatar Ken Narita Committed by Jeff Sharkey
Browse files

Parse Exif OffsetTime in MediaScanner

MediaScanner parses Exif OffsetTime value to use UTC time
for DATE_TAKEN value.

Bug: 62856173
Change-Id: Iffb7e0ae296b73ce6fb6515246871f0dcfe42bb0
parent 4fbd956d
Loading
Loading
Loading
Loading
+26 −4
Original line number Diff line number Diff line
@@ -233,6 +233,12 @@ public class ExifInterface {
    public static final String TAG_NEW_SUBFILE_TYPE = "NewSubfileType";
    /** Type is String. */
    public static final String TAG_OECF = "OECF";
    /** Type is String. {@hide} */
    public static final String TAG_OFFSET_TIME = "OffsetTime";
    /** Type is String. {@hide} */
    public static final String TAG_OFFSET_TIME_ORIGINAL = "OffsetTimeOriginal";
    /** Type is String. {@hide} */
    public static final String TAG_OFFSET_TIME_DIGITIZED = "OffsetTimeDigitized";
    /** Type is int. */
    public static final String TAG_PIXEL_X_DIMENSION = "PixelXDimension";
    /** Type is int. */
@@ -486,6 +492,7 @@ public class ExifInterface {

    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    private static SimpleDateFormat sFormatter;
    private static SimpleDateFormat sFormatterTz;

    // See Exchangeable image file format for digital still cameras: Exif version 2.2.
    // The following values are for parsing EXIF data area. There are tag groups in EXIF data area.
@@ -1041,6 +1048,9 @@ public class ExifInterface {
            new ExifTag(TAG_EXIF_VERSION, 36864, IFD_FORMAT_STRING),
            new ExifTag(TAG_DATETIME_ORIGINAL, 36867, IFD_FORMAT_STRING),
            new ExifTag(TAG_DATETIME_DIGITIZED, 36868, IFD_FORMAT_STRING),
            new ExifTag(TAG_OFFSET_TIME, 36880, IFD_FORMAT_STRING),
            new ExifTag(TAG_OFFSET_TIME_ORIGINAL, 36881, IFD_FORMAT_STRING),
            new ExifTag(TAG_OFFSET_TIME_DIGITIZED, 36882, IFD_FORMAT_STRING),
            new ExifTag(TAG_COMPONENTS_CONFIGURATION, 37121, IFD_FORMAT_UNDEFINED),
            new ExifTag(TAG_COMPRESSED_BITS_PER_PIXEL, 37122, IFD_FORMAT_URATIONAL),
            new ExifTag(TAG_SHUTTER_SPEED_VALUE, 37377, IFD_FORMAT_SRATIONAL),
@@ -1301,6 +1311,8 @@ public class ExifInterface {
    static {
        sFormatter = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss");
        sFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));
        sFormatterTz = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss XXX");
        sFormatterTz.setTimeZone(TimeZone.getTimeZone("UTC"));

        // Build up the hash tables to look up Exif tags for reading Exif tags.
        for (int ifdType = 0; ifdType < EXIF_TAGS.length; ++ifdType) {
@@ -2140,7 +2152,8 @@ public class ExifInterface {
    @UnsupportedAppUsage
    public @CurrentTimeMillisLong long getDateTime() {
        return parseDateTime(getAttribute(TAG_DATETIME),
                getAttribute(TAG_SUBSEC_TIME));
                getAttribute(TAG_SUBSEC_TIME),
                getAttribute(TAG_OFFSET_TIME));
    }

    /**
@@ -2151,7 +2164,8 @@ public class ExifInterface {
     */
    public @CurrentTimeMillisLong long getDateTimeDigitized() {
        return parseDateTime(getAttribute(TAG_DATETIME_DIGITIZED),
                getAttribute(TAG_SUBSEC_TIME_DIGITIZED));
                getAttribute(TAG_SUBSEC_TIME_DIGITIZED),
                getAttribute(TAG_OFFSET_TIME_DIGITIZED));
    }

    /**
@@ -2163,11 +2177,12 @@ public class ExifInterface {
    @UnsupportedAppUsage
    public @CurrentTimeMillisLong long getDateTimeOriginal() {
        return parseDateTime(getAttribute(TAG_DATETIME_ORIGINAL),
                getAttribute(TAG_SUBSEC_TIME_ORIGINAL));
                getAttribute(TAG_SUBSEC_TIME_ORIGINAL),
                getAttribute(TAG_OFFSET_TIME_ORIGINAL));
    }

    private static @CurrentTimeMillisLong long parseDateTime(@Nullable String dateTimeString,
            @Nullable String subSecs) {
            @Nullable String subSecs, @Nullable String offsetString) {
        if (dateTimeString == null
                || !sNonZeroTimePattern.matcher(dateTimeString).matches()) return -1;

@@ -2176,6 +2191,13 @@ public class ExifInterface {
            // The exif field is in local time. Parsing it as if it is UTC will yield time
            // since 1/1/1970 local time
            Date datetime = sFormatter.parse(dateTimeString, pos);

            if (offsetString != null) {
                dateTimeString = dateTimeString + " " + offsetString;
                ParsePosition position = new ParsePosition(0);
                datetime = sFormatterTz.parse(dateTimeString, position);
            }

            if (datetime == null) return -1;
            long msecs = datetime.getTime();