diff options
author | 2019-12-24 19:48:51 +0800 | |
---|---|---|
committer | 2020-04-22 03:20:02 +0000 | |
commit | 19ded228a3d84e07be054484ddfb0c94a6b9ebe4 (patch) | |
tree | 3873a714145e137b42d1b7d924261d6a3b44bc10 /media/tests/MtpTests | |
parent | 4bdbd1269a019b019705abb31e1e29bd4044a15f (diff) |
MTP: Add MtpDatabase unit test
Add Thumbnail feature test cases
Bug: 117863715
Test: atest MtpTests
Change-Id: I5a09efef10df20e382a4c623481e048e7b35ff14
Diffstat (limited to 'media/tests/MtpTests')
-rw-r--r-- | media/tests/MtpTests/res/raw/test_bad_thumb.jpg | 0 | ||||
-rw-r--r-- | media/tests/MtpTests/src/android/mtp/MtpDatabaseTest.java | 284 |
2 files changed, 284 insertions, 0 deletions
diff --git a/media/tests/MtpTests/res/raw/test_bad_thumb.jpg b/media/tests/MtpTests/res/raw/test_bad_thumb.jpg new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/media/tests/MtpTests/res/raw/test_bad_thumb.jpg diff --git a/media/tests/MtpTests/src/android/mtp/MtpDatabaseTest.java b/media/tests/MtpTests/src/android/mtp/MtpDatabaseTest.java new file mode 100644 index 000000000000..e0cd1917cff6 --- /dev/null +++ b/media/tests/MtpTests/src/android/mtp/MtpDatabaseTest.java @@ -0,0 +1,284 @@ +/* + * Copyright (C) 2020 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 android.mtp; + +import android.annotation.NonNull; +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.os.Build; +import android.os.FileUtils; +import android.os.UserHandle; +import android.os.storage.StorageVolume; +import android.util.Log; + +import androidx.test.InstrumentationRegistry; +import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; + +import com.android.internal.util.Preconditions; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * Tests for MtpDatabase functionality. + */ +@RunWith(AndroidJUnit4.class) +public class MtpDatabaseTest { + private static final String TAG = MtpDatabaseTest.class.getSimpleName(); + + private final Context mContext = InstrumentationRegistry.getContext(); + + private static final File mBaseDir = InstrumentationRegistry.getContext().getExternalCacheDir(); + private static final String MAIN_STORAGE_DIR = mBaseDir.getPath() + "/" + TAG + "/"; + private static final String TEST_DIRNAME = "/TestIs"; + + private static final int MAIN_STORAGE_ID = 0x10001; + private static final String MAIN_STORAGE_ID_STR = Integer.toHexString(MAIN_STORAGE_ID); + + private static final File mMainStorageDir = new File(MAIN_STORAGE_DIR); + + private static ServerHolder mServerHolder; + private MtpDatabase mMtpDatabase; + + private static void logMethodName() { + Log.d(TAG, Thread.currentThread().getStackTrace()[3].getMethodName()); + } + + private static File createNewDir(File parent, String name) { + File ret = new File(parent, name); + if (!ret.mkdir()) + throw new AssertionError( + "Failed to create file: name=" + name + ", " + parent.getPath()); + return ret; + } + + private static void writeNewFile(File newFile) { + try { + new FileOutputStream(newFile).write(new byte[] {0, 0, 0}); + } catch (IOException e) { + Assert.fail(); + } + } + + private static void writeNewFileFromByte(File newFile, byte[] byteData) { + try { + new FileOutputStream(newFile).write(byteData); + } catch (IOException e) { + Assert.fail(); + } + } + + private static class ServerHolder { + @NonNull final MtpServer server; + @NonNull final MtpDatabase database; + + ServerHolder(@NonNull MtpServer server, @NonNull MtpDatabase database) { + Preconditions.checkNotNull(server); + Preconditions.checkNotNull(database); + this.server = server; + this.database = database; + } + + void close() { + this.database.setServer(null); + } + } + + private class OnServerTerminated implements Runnable { + @Override + public void run() { + if (mServerHolder == null) { + Log.e(TAG, "mServerHolder is unexpectedly null."); + return; + } + mServerHolder.close(); + mServerHolder = null; + } + } + + @Before + public void setUp() { + FileUtils.deleteContentsAndDir(mMainStorageDir); + Assert.assertTrue(mMainStorageDir.mkdir()); + + StorageVolume mainStorage = new StorageVolume(MAIN_STORAGE_ID_STR, + mMainStorageDir, mMainStorageDir, "Primary Storage", + true, false, true, false, -1, UserHandle.CURRENT, "", ""); + + final StorageVolume primary = mainStorage; + + mMtpDatabase = new MtpDatabase(mContext, null); + + final MtpServer server = + new MtpServer(mMtpDatabase, null, false, + new OnServerTerminated(), Build.MANUFACTURER, + Build.MODEL, "1.0"); + mMtpDatabase.setServer(server); + mServerHolder = new ServerHolder(server, mMtpDatabase); + + mMtpDatabase.addStorage(mainStorage); + } + + @After + public void tearDown() { + FileUtils.deleteContentsAndDir(mMainStorageDir); + } + + private File stageFile(int resId, File file) throws IOException { + try (InputStream source = mContext.getResources().openRawResource(resId); + OutputStream target = new FileOutputStream(file)) { + android.os.FileUtils.copy(source, target); + } + return file; + } + + /** + * Refer to BitmapUtilTests, but keep here, + * so as to be aware of the behavior or interface change there + */ + private void assertBitmapSize(int expectedWidth, int expectedHeight, Bitmap bitmap) { + Assert.assertTrue( + "Abnormal bitmap.width: " + bitmap.getWidth(), bitmap.getWidth() >= expectedWidth); + Assert.assertTrue( + "Abnormal bitmap.height: " + bitmap.getHeight(), + bitmap.getHeight() >= expectedHeight); + } + + private byte[] createJpegRawData(int sourceWidth, int sourceHeight) throws IOException { + return createRawData(Bitmap.CompressFormat.JPEG, sourceWidth, sourceHeight); + } + + private byte[] createPngRawData(int sourceWidth, int sourceHeight) throws IOException { + return createRawData(Bitmap.CompressFormat.PNG, sourceWidth, sourceHeight); + } + + private byte[] createRawData(Bitmap.CompressFormat format, int sourceWidth, int sourceHeight) + throws IOException { + // Create a temp bitmap as our source + Bitmap b = Bitmap.createBitmap(sourceWidth, sourceHeight, Bitmap.Config.ARGB_8888); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + b.compress(format, 50, outputStream); + final byte[] data = outputStream.toByteArray(); + outputStream.close(); + return data; + } + + /** + * Decodes the bitmap with the given sample size + */ + public static Bitmap decodeBitmapFromBytes(byte[] bytes, int sampleSize) { + final BitmapFactory.Options options; + if (sampleSize <= 1) { + options = null; + } else { + options = new BitmapFactory.Options(); + options.inSampleSize = sampleSize; + } + return BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options); + } + + private void testThumbnail(int fileHandle, File imgFile, boolean isGoodThumb) + throws IOException { + boolean isValidThumb; + byte[] byteArray; + long[] outLongs = new long[3]; + + isValidThumb = mMtpDatabase.getThumbnailInfo(fileHandle, outLongs); + Assert.assertTrue(isValidThumb); + + byteArray = mMtpDatabase.getThumbnailData(fileHandle); + + if (isGoodThumb) { + Assert.assertNotNull("Fail to generate thumbnail:" + imgFile.getPath(), byteArray); + + Bitmap testBitmap = decodeBitmapFromBytes(byteArray, 4); + assertBitmapSize(32, 16, testBitmap); + } else Assert.assertNull("Bad image should return null:" + imgFile.getPath(), byteArray); + } + + @Test + @SmallTest + public void testMtpDatabaseThumbnail() throws IOException { + int baseHandle; + int handleJpgBadThumb, handleJpgNoThumb, handleJpgBad; + int handlePng1, handlePngBad; + final String baseTestDirStr = mMainStorageDir.getPath() + TEST_DIRNAME; + + logMethodName(); + + Log.d(TAG, "testMtpDatabaseThumbnail: Generate and insert tested files."); + + baseHandle = mMtpDatabase.beginSendObject(baseTestDirStr, + MtpConstants.FORMAT_ASSOCIATION, 0, MAIN_STORAGE_ID); + + File baseDir = new File(baseTestDirStr); + baseDir.mkdirs(); + + final File jpgfileBadThumb = new File(baseDir, "jpgfileBadThumb.jpg"); + final File jpgFileNoThumb = new File(baseDir, "jpgFileNoThumb.jpg"); + final File jpgfileBad = new File(baseDir, "jpgfileBad.jpg"); + final File pngFile1 = new File(baseDir, "pngFile1.png"); + final File pngFileBad = new File(baseDir, "pngFileBad.png"); + + handleJpgBadThumb = mMtpDatabase.beginSendObject(jpgfileBadThumb.getPath(), + MtpConstants.FORMAT_EXIF_JPEG, baseHandle, MAIN_STORAGE_ID); + stageFile(R.raw.test_bad_thumb, jpgfileBadThumb); + + handleJpgNoThumb = mMtpDatabase.beginSendObject(jpgFileNoThumb.getPath(), + MtpConstants.FORMAT_EXIF_JPEG, baseHandle, MAIN_STORAGE_ID); + writeNewFileFromByte(jpgFileNoThumb, createJpegRawData(128, 64)); + + handleJpgBad = mMtpDatabase.beginSendObject(jpgfileBad.getPath(), + MtpConstants.FORMAT_EXIF_JPEG, baseHandle, MAIN_STORAGE_ID); + writeNewFile(jpgfileBad); + + handlePng1 = mMtpDatabase.beginSendObject(pngFile1.getPath(), + MtpConstants.FORMAT_PNG, baseHandle, MAIN_STORAGE_ID); + writeNewFileFromByte(pngFile1, createPngRawData(128, 64)); + + handlePngBad = mMtpDatabase.beginSendObject(pngFileBad.getPath(), + MtpConstants.FORMAT_PNG, baseHandle, MAIN_STORAGE_ID); + writeNewFile(pngFileBad); + + Log.d(TAG, "testMtpDatabaseThumbnail: Test bad JPG"); + + testThumbnail(handleJpgBadThumb, jpgfileBadThumb, false); + + testThumbnail(handleJpgNoThumb, jpgFileNoThumb, false); + + testThumbnail(handleJpgBad, jpgfileBad, false); + + Log.d(TAG, "testMtpDatabaseThumbnail: Test PNG"); + + testThumbnail(handlePng1, pngFile1, true); + + Log.d(TAG, "testMtpDatabaseThumbnail: Test bad PNG"); + + testThumbnail(handlePngBad, pngFileBad, false); + } +} |