Implement EXIF stripping using "scrambled" library

This commit is contained in:
Matthieu 2022-10-24 14:53:01 +02:00
parent 96c14ef289
commit 56668688b5
6 changed files with 748 additions and 6 deletions

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "scrambler"]
path = scrambler
url = https://gitlab.com/artectrex/scrambler.git

View File

@ -200,6 +200,7 @@ dependencies {
implementation 'info.androidhive:imagefilters:1.0.7' implementation 'info.androidhive:imagefilters:1.0.7'
implementation 'com.github.yalantis:ucrop:2.2.8-native' implementation 'com.github.yalantis:ucrop:2.2.8-native'
implementation project(path: ':scrambler')
implementation('com.github.bumptech.glide:glide:4.14.2') { implementation('com.github.bumptech.glide:glide:4.14.2') {
exclude group: "com.android.support" exclude group: "com.android.support"

View File

@ -13,6 +13,7 @@ import androidx.core.net.toUri
import androidx.lifecycle.* import androidx.lifecycle.*
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import com.arthenica.ffmpegkit.FFmpegKit import com.arthenica.ffmpegkit.FFmpegKit
import com.jarsilio.android.scrambler.exceptions.UnsupportedFileFormatException
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.disposables.Disposable import io.reactivex.rxjava3.disposables.Disposable
import io.reactivex.rxjava3.schedulers.Schedulers import io.reactivex.rxjava3.schedulers.Schedulers
@ -30,6 +31,7 @@ import org.pixeldroid.app.utils.PixelDroidApplication
import org.pixeldroid.app.utils.api.objects.Attachment import org.pixeldroid.app.utils.api.objects.Attachment
import org.pixeldroid.app.utils.db.entities.InstanceDatabaseEntity import org.pixeldroid.app.utils.db.entities.InstanceDatabaseEntity
import org.pixeldroid.app.utils.di.PixelfedAPIHolder import org.pixeldroid.app.utils.di.PixelfedAPIHolder
import org.pixeldroid.app.utils.fileExtension
import org.pixeldroid.app.utils.getMimeType import org.pixeldroid.app.utils.getMimeType
import retrofit2.HttpException import retrofit2.HttpException
import java.io.File import java.io.File
@ -37,6 +39,7 @@ import java.io.FileNotFoundException
import java.io.IOException import java.io.IOException
import javax.inject.Inject import javax.inject.Inject
import kotlin.math.ceil import kotlin.math.ceil
import com.jarsilio.android.scrambler.stripMetadata
// Models the UI state for the PostCreationActivity // Models the UI state for the PostCreationActivity
data class PostCreationActivityUiState( data class PostCreationActivityUiState(
@ -233,6 +236,7 @@ class PostCreationViewModel(application: Application, clipdata: ClipData? = null
* Keeps track of them in the [PhotoData.progress] (for the upload progress), and the * Keeps track of them in the [PhotoData.progress] (for the upload progress), and the
* [PhotoData.uploadId] (for the list of ids of the uploads). * [PhotoData.uploadId] (for the list of ids of the uploads).
*/ */
@OptIn(ExperimentalUnsignedTypes::class)
fun upload() { fun upload() {
_uiState.update { currentUiState -> _uiState.update { currentUiState ->
currentUiState.copy( currentUiState.copy(
@ -247,21 +251,40 @@ class PostCreationViewModel(application: Application, clipdata: ClipData? = null
} }
for (data: PhotoData in getPhotoData().value ?: emptyList()) { for (data: PhotoData in getPhotoData().value ?: emptyList()) {
val imageUri = data.imageUri val extension = data.imageUri.fileExtension(getApplication<PixelDroidApplication>().contentResolver)
val imageInputStream = try {
getApplication<PixelDroidApplication>().contentResolver.openInputStream(imageUri)!! val strippedImage = File.createTempFile("temp_img", ".$extension", getApplication<PixelDroidApplication>().cacheDir)
val (strippedOrNot, size) = try {
stripMetadata(data.imageUri, strippedImage, getApplication<PixelDroidApplication>().contentResolver)
Pair(strippedImage.inputStream(), strippedImage.length())
} catch (e: FileNotFoundException){ } catch (e: FileNotFoundException){
strippedImage.delete()
_uiState.update { currentUiState -> _uiState.update { currentUiState ->
currentUiState.copy( currentUiState.copy(
userMessage = getApplication<PixelDroidApplication>().getString(R.string.file_not_found, userMessage = getApplication<PixelDroidApplication>().getString(R.string.file_not_found,
imageUri) data.imageUri)
) )
} }
return return
} catch (e: UnsupportedFileFormatException){
strippedImage.delete()
val imageInputStream = try {
getApplication<PixelDroidApplication>().contentResolver.openInputStream(data.imageUri)!!
} catch (e: FileNotFoundException){
_uiState.update { currentUiState ->
currentUiState.copy(
userMessage = getApplication<PixelDroidApplication>().getString(R.string.file_not_found,
data.imageUri)
)
}
return
}
Pair(imageInputStream, data.size)
} }
val type = imageUri.getMimeType(getApplication<PixelDroidApplication>().contentResolver) val type = data.imageUri.getMimeType(getApplication<PixelDroidApplication>().contentResolver)
val imagePart = ProgressRequestBody(imageInputStream, data.size, type) val imagePart = ProgressRequestBody(strippedOrNot, size, type)
val requestBody = MultipartBody.Builder() val requestBody = MultipartBody.Builder()
.setType(MultipartBody.FORM) .setType(MultipartBody.FORM)
.addFormDataPart("file", System.currentTimeMillis().toString(), imagePart) .addFormDataPart("file", System.currentTimeMillis().toString(), imagePart)
@ -303,11 +326,13 @@ class PostCreationViewModel(application: Application, clipdata: ClipData? = null
uploadErrorExplanationVisible = e is HttpException, uploadErrorExplanationVisible = e is HttpException,
) )
} }
strippedImage.delete()
e.printStackTrace() e.printStackTrace()
postSub?.dispose() postSub?.dispose()
sub.dispose() sub.dispose()
}, },
{ {
strippedImage.delete()
data.progress = 100 data.progress = 100
if (getPhotoData().value!!.all { it.progress == 100 && it.uploadId != null }) { if (getPhotoData().value!!.all { it.progress == 100 && it.uploadId != null }) {
_uiState.update { currentUiState -> _uiState.update { currentUiState ->

File diff suppressed because it is too large Load Diff

1
scrambler Submodule

@ -0,0 +1 @@
Subproject commit 961934d4c4ff8127e89a16ec1169b5bff7136820

View File

@ -1,2 +1,4 @@
rootProject.name='PixelDroid' rootProject.name='PixelDroid'
include ':app' include ':app'
include ':scrambler'
project(':scrambler').projectDir = new File(rootDir, 'scrambler/scrambler/')