CtsVerifier: Modify camera intents test to test for exif

Bug: 143191192, 143260675
Test: Run CTS Verifier camera intent tests
Merged-In: I25a500a1ef356ac436b86349a36f61ffa2349e4e
Change-Id: I25a500a1ef356ac436b86349a36f61ffa2349e4e
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index f0f0b7e..7b3f626 100755
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -1142,6 +1142,7 @@
     <string name="ci_intents_label">Intents Test</string>
     <string name="ci_intents_direction_label">clockwise</string>
     <string name="ci_instruction_heading_label">Instructions:</string>
+    <string name="ci_directory_creation_error">CTS Verifier debug directory could not be created, please try again</string>
     <string name="ci_instruction_text_photo_label">READ BEFORE STARTING TEST</string>
     <string name="ci_instruction_text_passfail_label">Choose \"Pass\" if the right intent is fired after taking a photo from the camera app. Otherwise, choose \"Fail\".</string>
     <string name="ci_instruction_text_app_picture_label">\n
diff --git a/apps/CtsVerifier/res/xml/filepaths.xml b/apps/CtsVerifier/res/xml/filepaths.xml
index 2d555a2..9993951 100644
--- a/apps/CtsVerifier/res/xml/filepaths.xml
+++ b/apps/CtsVerifier/res/xml/filepaths.xml
@@ -1,3 +1,4 @@
 <paths xmlns:android="http://schemas.android.com/apk/res/android">
     <files-path path="images/" name="images" />
+    <files-path path="debug" name="debug/" />
 </paths>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/intents/CameraIntentsActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/intents/CameraIntentsActivity.java
index 161cceb..7c0e475 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/intents/CameraIntentsActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/intents/CameraIntentsActivity.java
@@ -23,6 +23,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.hardware.Camera;
+import android.media.ExifInterface;
 import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.Bundle;
@@ -34,13 +35,21 @@
 import android.widget.Button;
 import android.widget.ImageButton;
 import android.widget.TextView;
+import android.widget.Toast;
+
+import androidx.core.content.FileProvider;
 
 import com.android.cts.verifier.camera.intents.CameraContentJobService;
 import com.android.cts.verifier.PassFailButtons;
 import com.android.cts.verifier.R;
 import com.android.cts.verifier.TestResult;
 
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
 import java.util.TreeSet;
+import java.util.Date;
+import java.text.SimpleDateFormat;
 
 /**
  * Tests for manual verification of uri trigger being fired.
@@ -80,6 +89,8 @@
     private ImageButton mPassButton;
     private ImageButton mFailButton;
     private Button mStartTestButton;
+    private File mDebugFolder = null;
+    private File mImageTarget = null;
 
     private int mState = STATE_OFF;
 
@@ -271,27 +282,66 @@
     @Override
     protected void onActivityResult(
         int requestCode, int resultCode, Intent data) {
-        if (requestCode == 1337 + getStageIndex()) {
+        int stageIndex = getStageIndex();
+        if (requestCode == 1337 + stageIndex) {
             Log.v(TAG, "Activity we launched was finished");
             mActivityResult = true;
 
             if (mState != STATE_FAILED
                 && getStageIndex() == STAGE_INTENT_PICTURE) {
-                mPassButton.setEnabled(true);
-                mFailButton.setEnabled(false);
-
-                mState = STATE_SUCCESSFUL;
-                /* successful, unless we get the URI trigger back
-                 at some point later on */
+                handleIntentPictureResult();
             }
         }
     }
 
+    private void handleIntentPictureResult() {
+        if (mImageTarget == null) {
+            Log.d(TAG, "Image target was not set");
+            return;
+        }
+        try {
+            if (!mImageTarget.exists() || mImageTarget.length() == 0) {
+                Log.d(TAG, "Image target does not exist or it is empty");
+                mState = STATE_FAILED;
+                return;
+            }
+
+            try {
+                final ExifInterface exif = new ExifInterface(new FileInputStream(mImageTarget));
+                if (!checkExifAttribute(exif, ExifInterface.TAG_MAKE)
+                    || !checkExifAttribute(exif, ExifInterface.TAG_MODEL)
+                    || !checkExifAttribute(exif, ExifInterface.TAG_DATETIME)) {
+                    Log.d(TAG, "The required tag does not appear in the exif");
+                    mState = STATE_FAILED;
+                    return;
+                }
+                mState = STATE_SUCCESSFUL;
+                setPassButton(true);
+            } catch (IOException ex) {
+                Log.e(TAG, "Failed to verify Exif", ex);
+                mState = STATE_FAILED;
+                return;
+            }
+        } finally {
+            mImageTarget.delete();
+        }
+    }
+
+    private boolean checkExifAttribute(ExifInterface exif, String tag) {
+        final String res = exif.getAttribute(tag);
+        return res != null && res.length() > 0;
+    }
+
     @Override
     public String getTestDetails() {
         return mReportBuilder.toString();
     }
 
+    private void setPassButton(Boolean pass) {
+        mPassButton.setEnabled(pass);
+        mFailButton.setEnabled(!pass);
+    }
+
     private class WaitForTriggerTask extends AsyncTask<Void, Void, Boolean> {
         protected Boolean doInBackground(Void... param) {
             try {
@@ -387,7 +437,33 @@
 
             if (intentStr != null) {
                 cameraIntent = new Intent(intentStr);
-                startActivityForResult(cameraIntent, 1337 + getStageIndex());
+                switch (stageIndex) {
+                    case STAGE_INTENT_PICTURE:
+                        mDebugFolder = new File(this.getFilesDir(), "debug");
+                        mDebugFolder.mkdirs();
+                        if (!mDebugFolder.exists()) {
+                            Toast.makeText(this, R.string.ci_directory_creation_error,
+                                    Toast.LENGTH_SHORT).show();
+                            Log.v(TAG, "Could not create directory");
+                            return;
+                        }
+
+                        File targetFile;
+                        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
+                        mImageTarget = new File(mDebugFolder, timeStamp + "capture.jpg");
+                        targetFile = mImageTarget;
+                        cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, FileProvider.getUriForFile(this,
+                              "com.android.cts.verifier.managedprovisioning.fileprovider",
+                              targetFile));
+                        startActivityForResult(cameraIntent, 1337 + getStageIndex());
+                        break;
+                    case STAGE_INTENT_VIDEO:
+                        startActivityForResult(cameraIntent, 1337 + getStageIndex());
+                        break;
+                    default:
+                        Log.wtf(TAG, "Unexpected stage index to send intent");
+                        return;
+                }
             }
 
             mStartTestButton.setEnabled(false);