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

Commit 2d9d80aa authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Write timestamp information into screenshots.

Now that ExifInterface has support for writing metadata into PNG
files, write the timestamp when a screenshot was taken.  This
includes the base time, fractional seconds, and timezone offset.

Bug: 140247628, 138155848
Test: manual
Change-Id: Ibdc7464e75ee5ea1483d529e6943f4e997323e03
parent 8a505cde
Loading
Loading
Loading
Loading
+39 −0
Original line number Original line Diff line number Diff line
@@ -59,13 +59,16 @@ import android.graphics.Picture;
import android.graphics.PixelFormat;
import android.graphics.PixelFormat;
import android.graphics.PointF;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.Rect;
import android.media.ExifInterface;
import android.media.MediaActionSound;
import android.media.MediaActionSound;
import android.net.Uri;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Environment;
import android.os.Environment;
import android.os.Handler;
import android.os.Handler;
import android.os.Looper;
import android.os.Looper;
import android.os.Message;
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.os.PowerManager;
import android.os.PowerManager;
import android.os.Process;
import android.os.Process;
import android.os.RemoteException;
import android.os.RemoteException;
@@ -107,9 +110,15 @@ import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStream;
import java.text.DateFormat;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Collections;
import java.util.Collections;
import java.util.Date;
import java.util.Date;
import java.util.List;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutionException;
@@ -323,11 +332,41 @@ public class GlobalScreenshot {
                final Uri uri = MediaStore.createPending(context, params);
                final Uri uri = MediaStore.createPending(context, params);
                final MediaStore.PendingSession session = MediaStore.openPending(context, uri);
                final MediaStore.PendingSession session = MediaStore.openPending(context, uri);
                try {
                try {
                    // First, write the actual data for our screenshot
                    try (OutputStream out = session.openOutputStream()) {
                    try (OutputStream out = session.openOutputStream()) {
                        if (!image.compress(Bitmap.CompressFormat.PNG, 100, out)) {
                        if (!image.compress(Bitmap.CompressFormat.PNG, 100, out)) {
                            throw new IOException("Failed to compress");
                            throw new IOException("Failed to compress");
                        }
                        }
                    }
                    }

                    // Next, write metadata to help index the screenshot
                    try (ParcelFileDescriptor pfd = session.open()) {
                        final ExifInterface exif = new ExifInterface(pfd.getFileDescriptor());

                        exif.setAttribute(ExifInterface.TAG_SOFTWARE,
                                "Android " + Build.DISPLAY);

                        exif.setAttribute(ExifInterface.TAG_IMAGE_WIDTH,
                                Integer.toString(image.getWidth()));
                        exif.setAttribute(ExifInterface.TAG_IMAGE_LENGTH,
                                Integer.toString(image.getHeight()));

                        final ZonedDateTime time = ZonedDateTime.ofInstant(
                                Instant.ofEpochMilli(mImageTime), ZoneId.systemDefault());
                        exif.setAttribute(ExifInterface.TAG_DATETIME_ORIGINAL,
                                DateTimeFormatter.ofPattern("yyyy:MM:dd HH:mm:ss").format(time));
                        exif.setAttribute(ExifInterface.TAG_SUBSEC_TIME_ORIGINAL,
                                DateTimeFormatter.ofPattern("SSS").format(time));

                        if (Objects.equals(time.getOffset(), ZoneOffset.UTC)) {
                            exif.setAttribute(ExifInterface.TAG_OFFSET_TIME_ORIGINAL, "+00:00");
                        } else {
                            exif.setAttribute(ExifInterface.TAG_OFFSET_TIME_ORIGINAL,
                                    DateTimeFormatter.ofPattern("XXX").format(time));
                        }

                        exif.saveAttributes();
                    }
                    session.publish();
                    session.publish();
                } catch (Exception e) {
                } catch (Exception e) {
                    session.abandon();
                    session.abandon();