Add unit test TranscodeHelperTest

BUG: 169546642
Test: atest TranscodeHelperTest
Change-Id: I5e9bddc22d0d7f7cce06128eb19188a82206e9b7
diff --git a/src/com/android/providers/media/TranscodeHelper.java b/src/com/android/providers/media/TranscodeHelper.java
index 1432662..15e2ff3 100644
--- a/src/com/android/providers/media/TranscodeHelper.java
+++ b/src/com/android/providers/media/TranscodeHelper.java
@@ -78,6 +78,7 @@
 import androidx.core.app.NotificationCompat;
 import androidx.core.app.NotificationManagerCompat;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.modules.utils.build.SdkLevel;
 import com.android.providers.media.util.BackgroundThread;
 import com.android.providers.media.util.FileUtils;
@@ -158,8 +159,10 @@
     @Disabled
     private static final long FORCE_DISABLE_HEVC_SUPPORT = 174227820L;
 
-    private static final int FLAG_HEVC = 1 << 0;
-    private static final int FLAG_SLOW_MOTION = 1 << 1;
+    @VisibleForTesting
+    static final int FLAG_HEVC = 1 << 0;
+    @VisibleForTesting
+    static final int FLAG_SLOW_MOTION = 1 << 1;
     private static final int FLAG_HDR_10 = 1 << 2;
     private static final int FLAG_HDR_10_PLUS = 1 << 3;
     private static final int FLAG_HDR_HLG = 1 << 4;
@@ -527,7 +530,8 @@
         return doesAppNeedTranscoding(uid, bundle, fileFlags);
     }
 
-    private int doesAppNeedTranscoding(int uid, Bundle bundle, int fileFlags) {
+    @VisibleForTesting
+    int doesAppNeedTranscoding(int uid, Bundle bundle, int fileFlags) {
         // Check explicit Bundle provided
         if (bundle != null) {
             if (bundle.getBoolean(MediaStore.EXTRA_ACCEPT_ORIGINAL_MEDIA_FORMAT, false)) {
@@ -1361,6 +1365,11 @@
         };
     }
 
+    @VisibleForTesting
+    static int getMyUid() {
+        return MY_UID;
+    }
+
     private static class StorageTranscodingSession {
         public final TranscodingSession session;
         public final CountDownLatch latch;
diff --git a/tests/src/com/android/providers/media/TranscodeHelperTest.java b/tests/src/com/android/providers/media/TranscodeHelperTest.java
new file mode 100644
index 0000000..f33d67d
--- /dev/null
+++ b/tests/src/com/android/providers/media/TranscodeHelperTest.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.providers.media;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.media.ApplicationMediaCapabilities;
+import android.media.MediaFormat;
+import android.os.Bundle;
+import android.os.Environment;
+import android.os.Process;
+import android.provider.MediaStore;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Random;
+
+@RunWith(AndroidJUnit4.class)
+public class TranscodeHelperTest {
+    private static final String SOME_VALID_FILE_PATH =
+            "/storage/emulated/0/" + Environment.DIRECTORY_DCIM + "/Camera/some_filename.mp4";
+
+    private final MediaProvider mDefaultMediaProvider = new MediaProvider() {
+        @Override
+        public String getStringDeviceConfig(String key, String defaultValue) {
+            return defaultValue;
+        }
+
+        @Override
+        public boolean getBooleanDeviceConfig(String key, boolean defaultValue) {
+            return defaultValue;
+        }
+
+        @Override
+        public int getIntDeviceConfig(String key, int defaultValue) {
+            return defaultValue;
+        }
+    };
+
+    private final TranscodeHelper mUnderTest = new TranscodeHelper(
+            InstrumentationRegistry.getTargetContext(), mDefaultMediaProvider);
+
+    @Test
+    public void testSupportsValidTranscodePath() {
+        List<String> filePaths = Arrays.asList(
+                "/storage/emulated/0/" + Environment.DIRECTORY_DCIM + "/Camera/filename.mp4",
+                "/storage/emulated/1/" + Environment.DIRECTORY_DCIM + "/Camera/filename.mp4",
+                "/storage/emulated/0/dcim/camera/filename.mp4");
+
+        for (String path : filePaths) {
+            assertThat(mUnderTest.supportsTranscode(path)).isTrue();
+        }
+    }
+
+    @Test
+    public void testDoesNotSupportsInvalidTranscodePath() {
+        List<String> filePaths = Arrays.asList(
+                "/storage/emulated/ab/" + Environment.DIRECTORY_DCIM + "/Camera/filename.mp4",
+                "/storage/emulated/0/" + Environment.DIRECTORY_DCIM + "/Camera/dir/filename.mp4",
+                "/storage/emulate/" + Environment.DIRECTORY_DCIM + "/Camera/filename.mp4",
+                "/storage/emulated/" + Environment.DIRECTORY_DCIM + "/Camera/filename.jpeg",
+                "/storage/emulated/0/dcmi/Camera/dir/filename.mp4");
+
+        for (String path : filePaths) {
+            assertThat(mUnderTest.supportsTranscode(path)).isFalse();
+        }
+    }
+
+    @Test
+    public void testDoesNotTranscodeForMediaProvider() {
+        int transcodeReason = mUnderTest.shouldTranscode(SOME_VALID_FILE_PATH,
+                TranscodeHelper.getMyUid(),
+                null);
+        assertThat(transcodeReason).isEqualTo(0);
+
+        Random random = new Random(System.currentTimeMillis());
+        Bundle bundle = new Bundle();
+        bundle.putInt(MediaStore.EXTRA_MEDIA_CAPABILITIES_UID, TranscodeHelper.getMyUid());
+        int randomAppUid = random.nextInt(
+                Process.LAST_APPLICATION_UID - Process.FIRST_APPLICATION_UID + 1)
+                + Process.FIRST_APPLICATION_UID;
+        transcodeReason = mUnderTest.shouldTranscode(SOME_VALID_FILE_PATH, randomAppUid, bundle);
+        assertThat(transcodeReason).isEqualTo(0);
+    }
+
+    @Test
+    public void testDoesNotTranscodeForSystemProcesses() {
+        Random random = new Random(System.currentTimeMillis());
+        int randomSystemProcessUid = random.nextInt(Process.FIRST_APPLICATION_UID);
+        int transcodeReason = mUnderTest.shouldTranscode(SOME_VALID_FILE_PATH,
+                randomSystemProcessUid, null);
+        assertThat(transcodeReason).isEqualTo(0);
+    }
+
+    @Test
+    public void testDoesNotTranscodeIfAppAcceptsOriginalFormat() {
+        Random random = new Random(System.currentTimeMillis());
+        Bundle bundle = new Bundle();
+        bundle.putBoolean(MediaStore.EXTRA_ACCEPT_ORIGINAL_MEDIA_FORMAT, true);
+        int randomAppUid = random.nextInt(
+                Process.LAST_APPLICATION_UID - Process.FIRST_APPLICATION_UID + 1)
+                + Process.FIRST_APPLICATION_UID;
+        int transcodeReason = mUnderTest.doesAppNeedTranscoding(randomAppUid, bundle,
+                TranscodeHelper.FLAG_HEVC);
+        assertThat(transcodeReason).isEqualTo(0);
+    }
+
+    @Test
+    public void testDoesNotTranscodeIfAppExtraMediaCapabilitiesHevc_supported() {
+        Random random = new Random(System.currentTimeMillis());
+        ApplicationMediaCapabilities capabilities =
+                new ApplicationMediaCapabilities.Builder().addSupportedVideoMimeType(
+                        MediaFormat.MIMETYPE_VIDEO_HEVC).build();
+        Bundle bundle = new Bundle();
+        bundle.putParcelable(MediaStore.EXTRA_MEDIA_CAPABILITIES, capabilities);
+        int randomAppUid = random.nextInt(
+                Process.LAST_APPLICATION_UID - Process.FIRST_APPLICATION_UID + 1)
+                + Process.FIRST_APPLICATION_UID;
+        int transcodeReason = mUnderTest.doesAppNeedTranscoding(randomAppUid, bundle,
+                TranscodeHelper.FLAG_HEVC);
+        assertThat(transcodeReason).isEqualTo(0);
+    }
+
+    @Test
+    public void testTranscodesIfAppExtraMediaCapabilitiesHevc_unsupported() {
+        Random random = new Random(System.currentTimeMillis());
+        ApplicationMediaCapabilities capabilities =
+                new ApplicationMediaCapabilities.Builder().addUnsupportedVideoMimeType(
+                        MediaFormat.MIMETYPE_VIDEO_HEVC).build();
+        Bundle bundle = new Bundle();
+        bundle.putParcelable(MediaStore.EXTRA_MEDIA_CAPABILITIES, capabilities);
+        int randomAppUid = random.nextInt(
+                Process.LAST_APPLICATION_UID - Process.FIRST_APPLICATION_UID + 1)
+                + Process.FIRST_APPLICATION_UID;
+        int transcodeReason = mUnderTest.doesAppNeedTranscoding(randomAppUid, bundle,
+                TranscodeHelper.FLAG_HEVC);
+        assertThat(transcodeReason).isEqualTo(
+                MediaProviderStatsLog.TRANSCODING_DATA__ACCESS_REASON__APP_EXTRA);
+    }
+}