diff --git a/androidshared/build.gradle b/androidshared/build.gradle index 6671d6c56ac..e420bcb0a0c 100644 --- a/androidshared/build.gradle +++ b/androidshared/build.gradle @@ -62,6 +62,7 @@ dependencies { implementation Dependencies.androidx_fragment_ktx implementation Dependencies.androidx_preference_ktx implementation Dependencies.timber + implementation Dependencies.androidx_exinterface testImplementation project(':testshared') testImplementation Dependencies.junit @@ -70,5 +71,8 @@ dependencies { testImplementation Dependencies.robolectric testImplementation Dependencies.mockito_kotlin + androidTestImplementation Dependencies.androidx_test_ext_junit + androidTestImplementation Dependencies.junit + debugImplementation project(':fragmentstest') } diff --git a/collect_app/src/androidTest/java/org/odk/collect/android/instrumented/utilities/ImageCompressorTest.kt b/androidshared/src/androidTest/java/org/odk/collect/androidshared/bitmap/ImageCompressorTest.kt similarity index 97% rename from collect_app/src/androidTest/java/org/odk/collect/android/instrumented/utilities/ImageCompressorTest.kt rename to androidshared/src/androidTest/java/org/odk/collect/androidshared/bitmap/ImageCompressorTest.kt index d215bd57461..866a171d49f 100644 --- a/collect_app/src/androidTest/java/org/odk/collect/android/instrumented/utilities/ImageCompressorTest.kt +++ b/androidshared/src/androidTest/java/org/odk/collect/androidshared/bitmap/ImageCompressorTest.kt @@ -13,18 +13,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.odk.collect.android.instrumented.utilities +package org.odk.collect.androidshared.bitmap import android.graphics.Bitmap import android.graphics.BitmapFactory import androidx.exifinterface.media.ExifInterface import androidx.test.ext.junit.runners.AndroidJUnit4 +import org.hamcrest.CoreMatchers.equalTo import org.hamcrest.MatcherAssert.assertThat -import org.hamcrest.Matchers.equalTo import org.junit.Test import org.junit.runner.RunWith -import org.odk.collect.android.utilities.ImageCompressor -import org.odk.collect.android.utilities.ImageFileUtils import java.io.File @RunWith(AndroidJUnit4::class) diff --git a/collect_app/src/androidTest/java/org/odk/collect/android/instrumented/utilities/ImageFileUtilsTest.kt b/androidshared/src/androidTest/java/org/odk/collect/androidshared/bitmap/ImageFileUtilsTest.kt similarity index 92% rename from collect_app/src/androidTest/java/org/odk/collect/android/instrumented/utilities/ImageFileUtilsTest.kt rename to androidshared/src/androidTest/java/org/odk/collect/androidshared/bitmap/ImageFileUtilsTest.kt index 31b64f74778..749f5bea83a 100644 --- a/collect_app/src/androidTest/java/org/odk/collect/android/instrumented/utilities/ImageFileUtilsTest.kt +++ b/androidshared/src/androidTest/java/org/odk/collect/androidshared/bitmap/ImageFileUtilsTest.kt @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.odk.collect.android.instrumented.utilities +package org.odk.collect.androidshared.bitmap import android.content.Context import android.graphics.Bitmap @@ -26,7 +26,6 @@ import org.junit.Assert.assertEquals import org.junit.Before import org.junit.Test import org.junit.runner.RunWith -import org.odk.collect.android.utilities.ImageFileUtils import timber.log.Timber import java.io.File import java.io.IOException @@ -50,7 +49,10 @@ class ImageFileUtilsTest { attributes[ExifInterface.TAG_ORIENTATION] = ExifInterface.ORIENTATION_ROTATE_90.toString() saveTestBitmapToFile(sourceFile.absolutePath, attributes) ImageFileUtils.copyImageAndApplyExifRotation(sourceFile, destinationFile) - val image = ImageFileUtils.getBitmap(destinationFile.absolutePath, BitmapFactory.Options())!! + val image = ImageFileUtils.getBitmap( + destinationFile.absolutePath, + BitmapFactory.Options() + )!! assertEquals(2, image.width) assertEquals(1, image.height) @@ -64,7 +66,10 @@ class ImageFileUtilsTest { attributes[ExifInterface.TAG_ORIENTATION] = ExifInterface.ORIENTATION_ROTATE_270.toString() saveTestBitmapToFile(sourceFile.absolutePath, attributes) ImageFileUtils.copyImageAndApplyExifRotation(sourceFile, destinationFile) - val image = ImageFileUtils.getBitmap(destinationFile.absolutePath, BitmapFactory.Options())!! + val image = ImageFileUtils.getBitmap( + destinationFile.absolutePath, + BitmapFactory.Options() + )!! assertEquals(2, image.width) assertEquals(1, image.height) @@ -78,7 +83,10 @@ class ImageFileUtilsTest { attributes[ExifInterface.TAG_ORIENTATION] = ExifInterface.ORIENTATION_ROTATE_180.toString() saveTestBitmapToFile(sourceFile.absolutePath, attributes) ImageFileUtils.copyImageAndApplyExifRotation(sourceFile, destinationFile) - val image = ImageFileUtils.getBitmap(destinationFile.absolutePath, BitmapFactory.Options())!! + val image = ImageFileUtils.getBitmap( + destinationFile.absolutePath, + BitmapFactory.Options() + )!! assertEquals(1, image.width) assertEquals(2, image.height) @@ -92,7 +100,10 @@ class ImageFileUtilsTest { attributes[ExifInterface.TAG_ORIENTATION] = ExifInterface.ORIENTATION_UNDEFINED.toString() saveTestBitmapToFile(sourceFile.absolutePath, attributes) ImageFileUtils.copyImageAndApplyExifRotation(sourceFile, destinationFile) - val image = ImageFileUtils.getBitmap(destinationFile.absolutePath, BitmapFactory.Options())!! + val image = ImageFileUtils.getBitmap( + destinationFile.absolutePath, + BitmapFactory.Options() + )!! assertEquals(1, image.width) assertEquals(2, image.height) @@ -105,7 +116,10 @@ class ImageFileUtilsTest { fun copyAndRotateImageNoExif() { saveTestBitmapToFile(sourceFile.absolutePath, null) ImageFileUtils.copyImageAndApplyExifRotation(sourceFile, destinationFile) - val image = ImageFileUtils.getBitmap(destinationFile.absolutePath, BitmapFactory.Options())!! + val image = ImageFileUtils.getBitmap( + destinationFile.absolutePath, + BitmapFactory.Options() + )!! assertEquals(1, image.width) assertEquals(2, image.height) diff --git a/collect_app/src/main/java/org/odk/collect/android/utilities/ImageCompressor.kt b/androidshared/src/main/java/org/odk/collect/androidshared/bitmap/ImageCompressor.kt similarity index 99% rename from collect_app/src/main/java/org/odk/collect/android/utilities/ImageCompressor.kt rename to androidshared/src/main/java/org/odk/collect/androidshared/bitmap/ImageCompressor.kt index 4d9a52fbede..e5e94b283b9 100644 --- a/collect_app/src/main/java/org/odk/collect/android/utilities/ImageCompressor.kt +++ b/androidshared/src/main/java/org/odk/collect/androidshared/bitmap/ImageCompressor.kt @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.odk.collect.android.utilities +package org.odk.collect.androidshared.bitmap import android.graphics.Bitmap import android.graphics.BitmapFactory diff --git a/collect_app/src/main/java/org/odk/collect/android/utilities/ImageFileUtils.kt b/androidshared/src/main/java/org/odk/collect/androidshared/bitmap/ImageFileUtils.kt similarity index 98% rename from collect_app/src/main/java/org/odk/collect/android/utilities/ImageFileUtils.kt rename to androidshared/src/main/java/org/odk/collect/androidshared/bitmap/ImageFileUtils.kt index 753e94cef6e..fec44ca3478 100644 --- a/collect_app/src/main/java/org/odk/collect/android/utilities/ImageFileUtils.kt +++ b/androidshared/src/main/java/org/odk/collect/androidshared/bitmap/ImageFileUtils.kt @@ -1,4 +1,4 @@ -package org.odk.collect.android.utilities +package org.odk.collect.androidshared.bitmap import android.graphics.Bitmap import android.graphics.Bitmap.CompressFormat @@ -150,7 +150,7 @@ object ImageFileUtils { ) ) { // Source Image doesn't have any EXIF Rotations, so a normal file copy will suffice - FileUtils.copyFile(sourceFile, destFile) + sourceFile.copyTo(destFile, true) } else { val sourceImage = getBitmap(sourceFile.absolutePath, BitmapFactory.Options()) val orientation = sourceFileExif.getAttributeInt( diff --git a/collect_app/build.gradle b/collect_app/build.gradle index 5153f200e84..2b1ae85bef0 100644 --- a/collect_app/build.gradle +++ b/collect_app/build.gradle @@ -280,7 +280,6 @@ dependencies { implementation Dependencies.androidx_work_runtime implementation Dependencies.androidx_cardview - implementation Dependencies.androidx_exinterface implementation Dependencies.androidx_multidex implementation Dependencies.androidx_preference_ktx implementation Dependencies.androidx_fragment_ktx diff --git a/collect_app/src/main/java/org/odk/collect/android/configure/qr/CachingQRCodeGenerator.kt b/collect_app/src/main/java/org/odk/collect/android/configure/qr/CachingQRCodeGenerator.kt index 135b6b33be5..090a549fc3e 100644 --- a/collect_app/src/main/java/org/odk/collect/android/configure/qr/CachingQRCodeGenerator.kt +++ b/collect_app/src/main/java/org/odk/collect/android/configure/qr/CachingQRCodeGenerator.kt @@ -5,7 +5,7 @@ import org.json.JSONException import org.odk.collect.android.storage.StoragePathProvider import org.odk.collect.android.storage.StorageSubdirectory import org.odk.collect.android.utilities.FileUtils -import org.odk.collect.android.utilities.ImageFileUtils.saveBitmapToFile +import org.odk.collect.androidshared.bitmap.ImageFileUtils import org.odk.collect.qrcode.QRCodeDecoder import org.odk.collect.qrcode.QRCodeEncoder import timber.log.Timber @@ -62,7 +62,7 @@ class CachingQRCodeGenerator(private val qrCodeEncoder: QRCodeEncoder) : QRCodeG val bmp = qrCodeEncoder.encode(preferencesString) Timber.i("QR Code generation took : %d ms", System.currentTimeMillis() - time) Timber.i("Saving QR Code to disk... : %s", qRCodeFilepath) - saveBitmapToFile(bmp, qRCodeFilepath) + ImageFileUtils.saveBitmapToFile(bmp, qRCodeFilepath) FileUtils.write(mdCacheFile, messageDigest) Timber.i("Updated %s file contents", SETTINGS_MD5_FILE) } diff --git a/collect_app/src/main/java/org/odk/collect/android/configure/qr/QRCodeViewModel.kt b/collect_app/src/main/java/org/odk/collect/android/configure/qr/QRCodeViewModel.kt index f94fbfd61c8..3d903cc430f 100644 --- a/collect_app/src/main/java/org/odk/collect/android/configure/qr/QRCodeViewModel.kt +++ b/collect_app/src/main/java/org/odk/collect/android/configure/qr/QRCodeViewModel.kt @@ -8,7 +8,7 @@ import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider import org.odk.collect.android.R -import org.odk.collect.android.utilities.ImageFileUtils.getBitmap +import org.odk.collect.androidshared.bitmap.ImageFileUtils import org.odk.collect.async.Scheduler import org.odk.collect.settings.SettingsProvider import org.odk.collect.settings.keys.ProjectKeys @@ -50,7 +50,7 @@ class QRCodeViewModel( qrCodeGenerator.generateQRCode(includedKeys, appConfigurationGenerator) val options = BitmapFactory.Options() options.inPreferredConfig = Bitmap.Config.ARGB_8888 - val bitmap = getBitmap(filePath, options) + val bitmap = ImageFileUtils.getBitmap(filePath, options) return@immediate Pair(filePath, bitmap) } catch (ignored: Exception) { // Ignored diff --git a/collect_app/src/main/java/org/odk/collect/android/draw/DrawActivity.java b/collect_app/src/main/java/org/odk/collect/android/draw/DrawActivity.java index ad090462991..f6457163eaf 100644 --- a/collect_app/src/main/java/org/odk/collect/android/draw/DrawActivity.java +++ b/collect_app/src/main/java/org/odk/collect/android/draw/DrawActivity.java @@ -46,7 +46,7 @@ import org.odk.collect.android.utilities.AnimationUtils; import org.odk.collect.android.storage.StoragePathProvider; import org.odk.collect.android.utilities.DialogUtils; -import org.odk.collect.android.utilities.ImageFileUtils; +import org.odk.collect.androidshared.bitmap.ImageFileUtils; import org.odk.collect.androidshared.ui.DialogFragmentUtils; import org.odk.collect.strings.localization.LocalizedActivity; diff --git a/collect_app/src/main/java/org/odk/collect/android/draw/DrawView.kt b/collect_app/src/main/java/org/odk/collect/android/draw/DrawView.kt index 607ed48d376..5d28f7e9c02 100644 --- a/collect_app/src/main/java/org/odk/collect/android/draw/DrawView.kt +++ b/collect_app/src/main/java/org/odk/collect/android/draw/DrawView.kt @@ -25,7 +25,7 @@ import android.util.AttributeSet import android.view.MotionEvent import android.view.View import org.odk.collect.android.storage.StoragePathProvider -import org.odk.collect.android.utilities.ImageFileUtils +import org.odk.collect.androidshared.bitmap.ImageFileUtils import java.io.File class DrawView(context: Context?, attrs: AttributeSet?) : View(context, attrs) { diff --git a/collect_app/src/main/java/org/odk/collect/android/injection/config/AppDependencyModule.java b/collect_app/src/main/java/org/odk/collect/android/injection/config/AppDependencyModule.java index f33e5586e45..9ecdddec4ed 100644 --- a/collect_app/src/main/java/org/odk/collect/android/injection/config/AppDependencyModule.java +++ b/collect_app/src/main/java/org/odk/collect/android/injection/config/AppDependencyModule.java @@ -111,7 +111,7 @@ import org.odk.collect.android.utilities.FileProvider; import org.odk.collect.android.utilities.FormsDirDiskFormsSynchronizer; import org.odk.collect.android.utilities.FormsRepositoryProvider; -import org.odk.collect.android.utilities.ImageCompressor; +import org.odk.collect.androidshared.bitmap.ImageCompressor; import org.odk.collect.android.utilities.ImageCompressionController; import org.odk.collect.android.utilities.InstancesRepositoryProvider; import org.odk.collect.android.utilities.MediaUtils; diff --git a/collect_app/src/main/java/org/odk/collect/android/utilities/ImageCompressionController.kt b/collect_app/src/main/java/org/odk/collect/android/utilities/ImageCompressionController.kt index 611e5317424..a4953c82e68 100644 --- a/collect_app/src/main/java/org/odk/collect/android/utilities/ImageCompressionController.kt +++ b/collect_app/src/main/java/org/odk/collect/android/utilities/ImageCompressionController.kt @@ -3,6 +3,7 @@ package org.odk.collect.android.utilities import android.content.Context import org.odk.collect.android.R import org.odk.collect.android.widgets.QuestionWidget +import org.odk.collect.androidshared.bitmap.ImageCompressor import timber.log.Timber class ImageCompressionController(private val imageCompressor: ImageCompressor) { diff --git a/collect_app/src/main/java/org/odk/collect/android/widgets/items/LabelWidget.java b/collect_app/src/main/java/org/odk/collect/android/widgets/items/LabelWidget.java index c1d2aa2bf1d..b230ba4f777 100644 --- a/collect_app/src/main/java/org/odk/collect/android/widgets/items/LabelWidget.java +++ b/collect_app/src/main/java/org/odk/collect/android/widgets/items/LabelWidget.java @@ -35,7 +35,7 @@ import org.odk.collect.android.externaldata.ExternalSelectChoice; import org.odk.collect.android.formentry.questions.QuestionDetails; import org.odk.collect.android.utilities.HtmlUtils; -import org.odk.collect.android.utilities.ImageFileUtils; +import org.odk.collect.androidshared.bitmap.ImageFileUtils; import org.odk.collect.android.widgets.QuestionWidget; import org.odk.collect.android.widgets.interfaces.SelectChoiceLoader; import org.odk.collect.android.widgets.warnings.SpacesInUnderlyingValuesWarning; diff --git a/collect_app/src/main/java/org/odk/collect/android/widgets/items/LikertWidget.java b/collect_app/src/main/java/org/odk/collect/android/widgets/items/LikertWidget.java index 7b16ffcc4ba..a3e999ad926 100644 --- a/collect_app/src/main/java/org/odk/collect/android/widgets/items/LikertWidget.java +++ b/collect_app/src/main/java/org/odk/collect/android/widgets/items/LikertWidget.java @@ -32,7 +32,7 @@ import org.odk.collect.android.externaldata.ExternalSelectChoice; import org.odk.collect.android.formentry.questions.QuestionDetails; import org.odk.collect.android.utilities.HtmlUtils; -import org.odk.collect.android.utilities.ImageFileUtils; +import org.odk.collect.androidshared.bitmap.ImageFileUtils; import org.odk.collect.android.widgets.QuestionWidget; import org.odk.collect.android.widgets.interfaces.SelectChoiceLoader; diff --git a/collect_app/src/main/java/org/odk/collect/android/widgets/items/ListMultiWidget.java b/collect_app/src/main/java/org/odk/collect/android/widgets/items/ListMultiWidget.java index 900a12aefcd..feacec0d651 100644 --- a/collect_app/src/main/java/org/odk/collect/android/widgets/items/ListMultiWidget.java +++ b/collect_app/src/main/java/org/odk/collect/android/widgets/items/ListMultiWidget.java @@ -42,7 +42,7 @@ import org.odk.collect.android.externaldata.ExternalSelectChoice; import org.odk.collect.android.formentry.questions.QuestionDetails; import org.odk.collect.android.utilities.HtmlUtils; -import org.odk.collect.android.utilities.ImageFileUtils; +import org.odk.collect.androidshared.bitmap.ImageFileUtils; import org.odk.collect.android.widgets.QuestionWidget; import org.odk.collect.android.widgets.interfaces.MultiChoiceWidget; import org.odk.collect.android.widgets.interfaces.SelectChoiceLoader; diff --git a/collect_app/src/main/java/org/odk/collect/android/widgets/items/ListWidget.java b/collect_app/src/main/java/org/odk/collect/android/widgets/items/ListWidget.java index b51f453dfe7..f266baef14f 100644 --- a/collect_app/src/main/java/org/odk/collect/android/widgets/items/ListWidget.java +++ b/collect_app/src/main/java/org/odk/collect/android/widgets/items/ListWidget.java @@ -44,7 +44,7 @@ import org.odk.collect.android.formentry.questions.QuestionDetails; import org.odk.collect.android.listeners.AdvanceToNextListener; import org.odk.collect.android.utilities.HtmlUtils; -import org.odk.collect.android.utilities.ImageFileUtils; +import org.odk.collect.androidshared.bitmap.ImageFileUtils; import org.odk.collect.android.utilities.SelectOneWidgetUtils; import org.odk.collect.android.widgets.QuestionWidget; import org.odk.collect.android.widgets.interfaces.MultiChoiceWidget; diff --git a/collect_app/src/test/java/org/odk/collect/android/utilities/ImageCompressionControllerTest.kt b/collect_app/src/test/java/org/odk/collect/android/utilities/ImageCompressionControllerTest.kt index 9264583565b..a285767fa30 100644 --- a/collect_app/src/test/java/org/odk/collect/android/utilities/ImageCompressionControllerTest.kt +++ b/collect_app/src/test/java/org/odk/collect/android/utilities/ImageCompressionControllerTest.kt @@ -12,6 +12,7 @@ import org.mockito.kotlin.verify import org.mockito.kotlin.verifyNoInteractions import org.mockito.kotlin.whenever import org.odk.collect.android.widgets.QuestionWidget +import org.odk.collect.androidshared.bitmap.ImageCompressor @RunWith(AndroidJUnit4::class) class ImageCompressionControllerTest {