Image swipe
This commit is contained in:
parent
5a444f2829
commit
400aa831b2
@ -15,7 +15,7 @@ android {
|
|||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 29
|
targetSdkVersion 29
|
||||||
versionCode 1
|
versionCode 1
|
||||||
versionName "1.1.1"
|
versionName "1.1.2"
|
||||||
|
|
||||||
ndk {
|
ndk {
|
||||||
abiFilters 'x86_64', 'armeabi-v7a', 'arm64-v8a'
|
abiFilters 'x86_64', 'armeabi-v7a', 'arm64-v8a'
|
||||||
|
@ -121,7 +121,7 @@ class ChangePasswordActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (changePasswordImmediately){
|
if (changePasswordImmediately){
|
||||||
if (GocryptfsVolume.change_password(rootCipherDir, oldPassword, givenHash, newPassword, returnedHash)) {
|
if (GocryptfsVolume.changePassword(rootCipherDir, oldPassword, givenHash, newPassword, returnedHash)) {
|
||||||
val editor = sharedPrefs.edit()
|
val editor = sharedPrefs.edit()
|
||||||
if (sharedPrefs.getString(rootCipherDir, null) != null){
|
if (sharedPrefs.getString(rootCipherDir, null) != null){
|
||||||
editor.remove(rootCipherDir)
|
editor.remove(rootCipherDir)
|
||||||
|
@ -91,7 +91,7 @@ class CreateActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (goodDirectory) {
|
if (goodDirectory) {
|
||||||
if (GocryptfsVolume.create_volume(rootCipherDir, password, GocryptfsVolume.ScryptDefaultLogN, ConstValues.creator)) {
|
if (GocryptfsVolume.createVolume(rootCipherDir, password, GocryptfsVolume.ScryptDefaultLogN, ConstValues.creator)) {
|
||||||
var returnedHash: ByteArray? = null
|
var returnedHash: ByteArray? = null
|
||||||
if (usf_fingerprint && checkbox_save_password.isChecked){
|
if (usf_fingerprint && checkbox_save_password.isChecked){
|
||||||
returnedHash = ByteArray(GocryptfsVolume.KeyLen)
|
returnedHash = ByteArray(GocryptfsVolume.KeyLen)
|
||||||
|
@ -167,7 +167,7 @@ open class BaseExplorerActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected fun setCurrentPath(path: String) {
|
protected fun setCurrentPath(path: String) {
|
||||||
explorerElements = gocryptfsVolume.list_dir(path)
|
explorerElements = gocryptfsVolume.listDir(path)
|
||||||
text_dir_empty.visibility = if (explorerElements.size == 0) View.VISIBLE else View.INVISIBLE
|
text_dir_empty.visibility = if (explorerElements.size == 0) View.VISIBLE else View.INVISIBLE
|
||||||
sortExplorerElements()
|
sortExplorerElements()
|
||||||
if (path.isNotEmpty()) { //not root
|
if (path.isNotEmpty()) { //not root
|
||||||
|
@ -44,7 +44,7 @@ class ExplorerActivity : BaseExplorerActivity() {
|
|||||||
if (fileName.isEmpty()) {
|
if (fileName.isEmpty()) {
|
||||||
Toast.makeText(this, R.string.error_filename_empty, Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, R.string.error_filename_empty, Toast.LENGTH_SHORT).show()
|
||||||
} else {
|
} else {
|
||||||
val handleID = gocryptfsVolume.open_write_mode(PathUtils.path_join(currentDirectoryPath, fileName))
|
val handleID = gocryptfsVolume.openWriteMode(PathUtils.path_join(currentDirectoryPath, fileName))
|
||||||
if (handleID == -1) {
|
if (handleID == -1) {
|
||||||
ColoredAlertDialogBuilder(this)
|
ColoredAlertDialogBuilder(this)
|
||||||
.setTitle(R.string.error)
|
.setTitle(R.string.error)
|
||||||
@ -52,7 +52,7 @@ class ExplorerActivity : BaseExplorerActivity() {
|
|||||||
.setPositiveButton(R.string.ok, null)
|
.setPositiveButton(R.string.ok, null)
|
||||||
.show()
|
.show()
|
||||||
} else {
|
} else {
|
||||||
gocryptfsVolume.close_file(handleID)
|
gocryptfsVolume.closeFile(handleID)
|
||||||
setCurrentPath(currentDirectoryPath)
|
setCurrentPath(currentDirectoryPath)
|
||||||
invalidateOptionsMenu()
|
invalidateOptionsMenu()
|
||||||
}
|
}
|
||||||
@ -120,7 +120,7 @@ class ExplorerActivity : BaseExplorerActivity() {
|
|||||||
for (uri in uris) {
|
for (uri in uris) {
|
||||||
val dstPath = PathUtils.path_join(currentDirectoryPath, PathUtils.getFilenameFromURI(activity, uri))
|
val dstPath = PathUtils.path_join(currentDirectoryPath, PathUtils.getFilenameFromURI(activity, uri))
|
||||||
contentResolver.openInputStream(uri)?.let {
|
contentResolver.openInputStream(uri)?.let {
|
||||||
success = gocryptfsVolume.import_file(it, dstPath)
|
success = gocryptfsVolume.importFile(it, dstPath)
|
||||||
}
|
}
|
||||||
if (!success) {
|
if (!success) {
|
||||||
stopTask {
|
stopTask {
|
||||||
@ -194,7 +194,7 @@ class ExplorerActivity : BaseExplorerActivity() {
|
|||||||
failedItem = if (element.isDirectory) {
|
failedItem = if (element.isDirectory) {
|
||||||
recursiveExportDirectory(fullPath, outputDir)
|
recursiveExportDirectory(fullPath, outputDir)
|
||||||
} else {
|
} else {
|
||||||
if (gocryptfsVolume.export_file(fullPath, PathUtils.path_join(outputDir, element.name))) null else fullPath
|
if (gocryptfsVolume.exportFile(fullPath, PathUtils.path_join(outputDir, element.name))) null else fullPath
|
||||||
}
|
}
|
||||||
if (failedItem != null) {
|
if (failedItem != null) {
|
||||||
stopTask {
|
stopTask {
|
||||||
@ -400,18 +400,6 @@ class ExplorerActivity : BaseExplorerActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun recursiveMapFiles(rootPath: String): MutableList<ExplorerElement> {
|
|
||||||
val result = mutableListOf<ExplorerElement>()
|
|
||||||
val explorerElements = gocryptfsVolume.list_dir(rootPath)
|
|
||||||
result.addAll(explorerElements)
|
|
||||||
for (e in explorerElements){
|
|
||||||
if (e.isDirectory){
|
|
||||||
result.addAll(recursiveMapFiles(e.getFullPath()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun cancelCopy() {
|
private fun cancelCopy() {
|
||||||
if (modeSelectLocation){
|
if (modeSelectLocation){
|
||||||
modeSelectLocation = false
|
modeSelectLocation = false
|
||||||
@ -424,15 +412,15 @@ class ExplorerActivity : BaseExplorerActivity() {
|
|||||||
|
|
||||||
private fun copyFile(srcPath: String, dstPath: String): Boolean {
|
private fun copyFile(srcPath: String, dstPath: String): Boolean {
|
||||||
var success = true
|
var success = true
|
||||||
val originalHandleId = gocryptfsVolume.open_read_mode(srcPath)
|
val originalHandleId = gocryptfsVolume.openReadMode(srcPath)
|
||||||
if (originalHandleId != -1){
|
if (originalHandleId != -1){
|
||||||
val newHandleId = gocryptfsVolume.open_write_mode(dstPath)
|
val newHandleId = gocryptfsVolume.openWriteMode(dstPath)
|
||||||
if (newHandleId != -1){
|
if (newHandleId != -1){
|
||||||
var offset: Long = 0
|
var offset: Long = 0
|
||||||
val ioBuffer = ByteArray(GocryptfsVolume.DefaultBS)
|
val ioBuffer = ByteArray(GocryptfsVolume.DefaultBS)
|
||||||
var length: Int
|
var length: Int
|
||||||
while (gocryptfsVolume.read_file(originalHandleId, offset, ioBuffer).also { length = it } > 0) {
|
while (gocryptfsVolume.readFile(originalHandleId, offset, ioBuffer).also { length = it } > 0) {
|
||||||
val written = gocryptfsVolume.write_file(newHandleId, offset, ioBuffer, length).toLong()
|
val written = gocryptfsVolume.writeFile(newHandleId, offset, ioBuffer, length).toLong()
|
||||||
if (written == length.toLong()) {
|
if (written == length.toLong()) {
|
||||||
offset += written
|
offset += written
|
||||||
} else {
|
} else {
|
||||||
@ -440,11 +428,11 @@ class ExplorerActivity : BaseExplorerActivity() {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gocryptfsVolume.close_file(newHandleId)
|
gocryptfsVolume.closeFile(newHandleId)
|
||||||
} else {
|
} else {
|
||||||
success = false
|
success = false
|
||||||
}
|
}
|
||||||
gocryptfsVolume.close_file(originalHandleId)
|
gocryptfsVolume.closeFile(originalHandleId)
|
||||||
} else {
|
} else {
|
||||||
success = false
|
success = false
|
||||||
}
|
}
|
||||||
@ -452,9 +440,9 @@ class ExplorerActivity : BaseExplorerActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun recursiveCopyDirectory(srcDirectoryPath: String, outputPath: String): String? {
|
private fun recursiveCopyDirectory(srcDirectoryPath: String, outputPath: String): String? {
|
||||||
val mappedElements = recursiveMapFiles(srcDirectoryPath)
|
val mappedElements = gocryptfsVolume.recursiveMapFiles(srcDirectoryPath)
|
||||||
val dstDirectoryPath = PathUtils.path_join(outputPath, File(srcDirectoryPath).name)
|
val dstDirectoryPath = PathUtils.path_join(outputPath, File(srcDirectoryPath).name)
|
||||||
if (!gocryptfsVolume.path_exists(dstDirectoryPath)) {
|
if (!gocryptfsVolume.pathExists(dstDirectoryPath)) {
|
||||||
if (!gocryptfsVolume.mkdir(dstDirectoryPath)) {
|
if (!gocryptfsVolume.mkdir(dstDirectoryPath)) {
|
||||||
return dstDirectoryPath
|
return dstDirectoryPath
|
||||||
}
|
}
|
||||||
@ -477,15 +465,15 @@ class ExplorerActivity : BaseExplorerActivity() {
|
|||||||
|
|
||||||
private fun importFileFromOtherVolume(remote_gocryptfsVolume: GocryptfsVolume, srcPath: String, dstPath: String): Boolean {
|
private fun importFileFromOtherVolume(remote_gocryptfsVolume: GocryptfsVolume, srcPath: String, dstPath: String): Boolean {
|
||||||
var success = true
|
var success = true
|
||||||
val srcHandleID = remote_gocryptfsVolume.open_read_mode(srcPath)
|
val srcHandleID = remote_gocryptfsVolume.openReadMode(srcPath)
|
||||||
if (srcHandleID != -1) {
|
if (srcHandleID != -1) {
|
||||||
val dstHandleID = gocryptfsVolume.open_write_mode(dstPath)
|
val dstHandleID = gocryptfsVolume.openWriteMode(dstPath)
|
||||||
if (dstHandleID != -1) {
|
if (dstHandleID != -1) {
|
||||||
var length: Int
|
var length: Int
|
||||||
val ioBuffer = ByteArray(GocryptfsVolume.DefaultBS)
|
val ioBuffer = ByteArray(GocryptfsVolume.DefaultBS)
|
||||||
var offset: Long = 0
|
var offset: Long = 0
|
||||||
while (remote_gocryptfsVolume.read_file(srcHandleID, offset, ioBuffer).also { length = it } > 0){
|
while (remote_gocryptfsVolume.readFile(srcHandleID, offset, ioBuffer).also { length = it } > 0){
|
||||||
val written = gocryptfsVolume.write_file(dstHandleID, offset, ioBuffer, length).toLong()
|
val written = gocryptfsVolume.writeFile(dstHandleID, offset, ioBuffer, length).toLong()
|
||||||
if (written == length.toLong()) {
|
if (written == length.toLong()) {
|
||||||
offset += length.toLong()
|
offset += length.toLong()
|
||||||
} else {
|
} else {
|
||||||
@ -493,17 +481,17 @@ class ExplorerActivity : BaseExplorerActivity() {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gocryptfsVolume.close_file(dstHandleID)
|
gocryptfsVolume.closeFile(dstHandleID)
|
||||||
}
|
}
|
||||||
remote_gocryptfsVolume.close_file(srcHandleID)
|
remote_gocryptfsVolume.closeFile(srcHandleID)
|
||||||
}
|
}
|
||||||
return success
|
return success
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun recursiveImportDirectoryFromOtherVolume(remote_gocryptfsVolume: GocryptfsVolume, remote_directory_path: String, outputPath: String): String? {
|
private fun recursiveImportDirectoryFromOtherVolume(remote_gocryptfsVolume: GocryptfsVolume, remote_directory_path: String, outputPath: String): String? {
|
||||||
val mappedElements = recursiveMapFiles(remote_directory_path)
|
val mappedElements = gocryptfsVolume.recursiveMapFiles(remote_directory_path)
|
||||||
val dstDirectoryPath = PathUtils.path_join(outputPath, File(remote_directory_path).name)
|
val dstDirectoryPath = PathUtils.path_join(outputPath, File(remote_directory_path).name)
|
||||||
if (!gocryptfsVolume.path_exists(dstDirectoryPath)) {
|
if (!gocryptfsVolume.pathExists(dstDirectoryPath)) {
|
||||||
if (!gocryptfsVolume.mkdir(dstDirectoryPath)) {
|
if (!gocryptfsVolume.mkdir(dstDirectoryPath)) {
|
||||||
return dstDirectoryPath
|
return dstDirectoryPath
|
||||||
}
|
}
|
||||||
@ -526,14 +514,14 @@ class ExplorerActivity : BaseExplorerActivity() {
|
|||||||
|
|
||||||
private fun recursiveExportDirectory(plain_directory_path: String, output_dir: String?): String? {
|
private fun recursiveExportDirectory(plain_directory_path: String, output_dir: String?): String? {
|
||||||
if (File(PathUtils.path_join(output_dir, plain_directory_path)).mkdir()) {
|
if (File(PathUtils.path_join(output_dir, plain_directory_path)).mkdir()) {
|
||||||
val explorerElements = gocryptfsVolume.list_dir(plain_directory_path)
|
val explorerElements = gocryptfsVolume.listDir(plain_directory_path)
|
||||||
for (e in explorerElements) {
|
for (e in explorerElements) {
|
||||||
val fullPath = PathUtils.path_join(plain_directory_path, e.name)
|
val fullPath = PathUtils.path_join(plain_directory_path, e.name)
|
||||||
if (e.isDirectory) {
|
if (e.isDirectory) {
|
||||||
val failedItem = recursiveExportDirectory(fullPath, output_dir)
|
val failedItem = recursiveExportDirectory(fullPath, output_dir)
|
||||||
failedItem?.let { return it }
|
failedItem?.let { return it }
|
||||||
} else {
|
} else {
|
||||||
if (!gocryptfsVolume.export_file(fullPath, PathUtils.path_join(output_dir, fullPath))) {
|
if (!gocryptfsVolume.exportFile(fullPath, PathUtils.path_join(output_dir, fullPath))) {
|
||||||
return fullPath
|
return fullPath
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -544,14 +532,14 @@ class ExplorerActivity : BaseExplorerActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun recursiveRemoveDirectory(plain_directory_path: String): String? {
|
private fun recursiveRemoveDirectory(plain_directory_path: String): String? {
|
||||||
val explorerElements = gocryptfsVolume.list_dir(plain_directory_path)
|
val explorerElements = gocryptfsVolume.listDir(plain_directory_path)
|
||||||
for (e in explorerElements) {
|
for (e in explorerElements) {
|
||||||
val fullPath = PathUtils.path_join(plain_directory_path, e.name)
|
val fullPath = PathUtils.path_join(plain_directory_path, e.name)
|
||||||
if (e.isDirectory) {
|
if (e.isDirectory) {
|
||||||
val result = recursiveRemoveDirectory(fullPath)
|
val result = recursiveRemoveDirectory(fullPath)
|
||||||
result?.let { return it }
|
result?.let { return it }
|
||||||
} else {
|
} else {
|
||||||
if (!gocryptfsVolume.remove_file(fullPath)) {
|
if (!gocryptfsVolume.removeFile(fullPath)) {
|
||||||
return fullPath
|
return fullPath
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -572,7 +560,7 @@ class ExplorerActivity : BaseExplorerActivity() {
|
|||||||
val result = recursiveRemoveDirectory(fullPath)
|
val result = recursiveRemoveDirectory(fullPath)
|
||||||
result?.let{ failedItem = it }
|
result?.let{ failedItem = it }
|
||||||
} else {
|
} else {
|
||||||
if (!gocryptfsVolume.remove_file(fullPath)) {
|
if (!gocryptfsVolume.removeFile(fullPath)) {
|
||||||
failedItem = fullPath
|
failedItem = fullPath
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ package sushi.hardcore.droidfs.explorers
|
|||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.util.Log
|
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import sushi.hardcore.droidfs.R
|
import sushi.hardcore.droidfs.R
|
||||||
@ -33,13 +32,13 @@ class ExplorerActivityDrop : BaseExplorerActivity() {
|
|||||||
if (intent.action == Intent.ACTION_SEND) {
|
if (intent.action == Intent.ACTION_SEND) {
|
||||||
val uri = intent.getParcelableExtra<Uri>(Intent.EXTRA_STREAM)
|
val uri = intent.getParcelableExtra<Uri>(Intent.EXTRA_STREAM)
|
||||||
val outputPath = PathUtils.path_join(currentDirectoryPath, PathUtils.getFilenameFromURI(this, uri))
|
val outputPath = PathUtils.path_join(currentDirectoryPath, PathUtils.getFilenameFromURI(this, uri))
|
||||||
errorMsg = if (gocryptfsVolume.import_file(this, uri, outputPath)) null else getString(R.string.import_failed, outputPath)
|
errorMsg = if (gocryptfsVolume.importFile(this, uri, outputPath)) null else getString(R.string.import_failed, outputPath)
|
||||||
} else if (intent.action == Intent.ACTION_SEND_MULTIPLE) {
|
} else if (intent.action == Intent.ACTION_SEND_MULTIPLE) {
|
||||||
val uris = intent.getParcelableArrayListExtra<Uri>(Intent.EXTRA_STREAM)
|
val uris = intent.getParcelableArrayListExtra<Uri>(Intent.EXTRA_STREAM)
|
||||||
if (uris != null){
|
if (uris != null){
|
||||||
for (uri in uris) {
|
for (uri in uris) {
|
||||||
val outputPath = PathUtils.path_join(currentDirectoryPath, PathUtils.getFilenameFromURI(this, uri))
|
val outputPath = PathUtils.path_join(currentDirectoryPath, PathUtils.getFilenameFromURI(this, uri))
|
||||||
if (!gocryptfsVolume.import_file(this, uri, outputPath)) {
|
if (!gocryptfsVolume.importFile(this, uri, outputPath)) {
|
||||||
errorMsg = getString(R.string.import_failed, outputPath)
|
errorMsg = getString(R.string.import_failed, outputPath)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -29,21 +29,21 @@ abstract class FileViewerActivity: BaseActivity() {
|
|||||||
}
|
}
|
||||||
abstract fun viewFile()
|
abstract fun viewFile()
|
||||||
fun loadWholeFile(path: String): ByteArray? {
|
fun loadWholeFile(path: String): ByteArray? {
|
||||||
val fileSize = gocryptfsVolume.get_size(path)
|
val fileSize = gocryptfsVolume.getSize(path)
|
||||||
if (fileSize >= 0){
|
if (fileSize >= 0){
|
||||||
try {
|
try {
|
||||||
val fileBuff = ByteArray(fileSize.toInt())
|
val fileBuff = ByteArray(fileSize.toInt())
|
||||||
var success = false
|
var success = false
|
||||||
val handleID = gocryptfsVolume.open_read_mode(path)
|
val handleID = gocryptfsVolume.openReadMode(path)
|
||||||
if (handleID != -1) {
|
if (handleID != -1) {
|
||||||
var offset: Long = 0
|
var offset: Long = 0
|
||||||
val ioBuffer = ByteArray(GocryptfsVolume.DefaultBS)
|
val ioBuffer = ByteArray(GocryptfsVolume.DefaultBS)
|
||||||
var length: Int
|
var length: Int
|
||||||
while (gocryptfsVolume.read_file(handleID, offset, ioBuffer).also { length = it } > 0){
|
while (gocryptfsVolume.readFile(handleID, offset, ioBuffer).also { length = it } > 0){
|
||||||
System.arraycopy(ioBuffer, 0, fileBuff, offset.toInt(), length)
|
System.arraycopy(ioBuffer, 0, fileBuff, offset.toInt(), length)
|
||||||
offset += length.toLong()
|
offset += length.toLong()
|
||||||
}
|
}
|
||||||
gocryptfsVolume.close_file(handleID)
|
gocryptfsVolume.closeFile(handleID)
|
||||||
success = offset == fileBuff.size.toLong()
|
success = offset == fileBuff.size.toLong()
|
||||||
}
|
}
|
||||||
if (success){
|
if (success){
|
||||||
|
@ -15,8 +15,8 @@ class GocryptfsDataSource(private val gocryptfsVolume: GocryptfsVolume, private
|
|||||||
dataSpec?.let {
|
dataSpec?.let {
|
||||||
fileOffset = dataSpec.position
|
fileOffset = dataSpec.position
|
||||||
}
|
}
|
||||||
handleID = gocryptfsVolume.open_read_mode(filePath)
|
handleID = gocryptfsVolume.openReadMode(filePath)
|
||||||
fileSize = gocryptfsVolume.get_size(filePath)
|
fileSize = gocryptfsVolume.getSize(filePath)
|
||||||
return fileSize
|
return fileSize
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ class GocryptfsDataSource(private val gocryptfsVolume: GocryptfsVolume, private
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun close() {
|
override fun close() {
|
||||||
gocryptfsVolume.close_file(handleID)
|
gocryptfsVolume.closeFile(handleID)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun addTransferListener(transferListener: TransferListener?) {
|
override fun addTransferListener(transferListener: TransferListener?) {
|
||||||
@ -44,7 +44,7 @@ class GocryptfsDataSource(private val gocryptfsVolume: GocryptfsVolume, private
|
|||||||
} else {
|
} else {
|
||||||
ByteArray(tmpReadLength)
|
ByteArray(tmpReadLength)
|
||||||
}
|
}
|
||||||
val read = gocryptfsVolume.read_file(handleID, fileOffset, tmpBuff)
|
val read = gocryptfsVolume.readFile(handleID, fileOffset, tmpBuff)
|
||||||
System.arraycopy(tmpBuff, 0, buffer, offset+totalRead, read)
|
System.arraycopy(tmpBuff, 0, buffer, offset+totalRead, read)
|
||||||
fileOffset += read
|
fileOffset += read
|
||||||
totalRead += read
|
totalRead += read
|
||||||
|
@ -4,20 +4,30 @@ import android.graphics.Bitmap
|
|||||||
import android.graphics.Matrix
|
import android.graphics.Matrix
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
|
import android.view.MotionEvent
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import com.bumptech.glide.RequestBuilder
|
import com.bumptech.glide.RequestBuilder
|
||||||
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool
|
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool
|
||||||
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation
|
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation
|
||||||
import kotlinx.android.synthetic.main.activity_image_viewer.*
|
import kotlinx.android.synthetic.main.activity_image_viewer.*
|
||||||
|
import sushi.hardcore.droidfs.ConstValues
|
||||||
import sushi.hardcore.droidfs.R
|
import sushi.hardcore.droidfs.R
|
||||||
|
import sushi.hardcore.droidfs.util.PathUtils
|
||||||
import java.security.MessageDigest
|
import java.security.MessageDigest
|
||||||
|
import kotlin.math.abs
|
||||||
|
|
||||||
class ImageViewer: FileViewerActivity() {
|
class ImageViewer: FileViewerActivity() {
|
||||||
companion object {
|
companion object {
|
||||||
private const val hideDelay: Long = 3000
|
private const val hideDelay: Long = 3000
|
||||||
|
private const val MIN_SWIPE_DISTANCE = 150
|
||||||
}
|
}
|
||||||
private lateinit var glideImage: RequestBuilder<Drawable>
|
private lateinit var glideImage: RequestBuilder<Drawable>
|
||||||
|
private var x1 = 0F
|
||||||
|
private var x2 = 0F
|
||||||
|
private val mappedImages = mutableListOf<String>()
|
||||||
|
private var wasMapped = false
|
||||||
|
private var currentMappedImageIndex = -1
|
||||||
private var rotationAngle: Float = 0F
|
private var rotationAngle: Float = 0F
|
||||||
private val handler = Handler()
|
private val handler = Handler()
|
||||||
private val hideActionButtons = Runnable { action_buttons.visibility = View.GONE }
|
private val hideActionButtons = Runnable { action_buttons.visibility = View.GONE }
|
||||||
@ -31,6 +41,50 @@ class ImageViewer: FileViewerActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun dispatchTouchEvent(event: MotionEvent?): Boolean {
|
||||||
|
if (!image_viewer.isZoomed){
|
||||||
|
when(event?.action){
|
||||||
|
MotionEvent.ACTION_DOWN -> {
|
||||||
|
x1 = event.x
|
||||||
|
}
|
||||||
|
MotionEvent.ACTION_UP -> {
|
||||||
|
x2 = event.x
|
||||||
|
val deltaX = x2 - x1
|
||||||
|
if (abs(deltaX) > MIN_SWIPE_DISTANCE){
|
||||||
|
if (!wasMapped){
|
||||||
|
for (e in gocryptfsVolume.recursiveMapFiles(PathUtils.getParentPath(filePath))){
|
||||||
|
if (e.isRegularFile && ConstValues.isImage(e.name)){
|
||||||
|
mappedImages.add(e.getFullPath())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mappedImages.sortWith(Comparator { p1, p2 -> p1.compareTo(p2) })
|
||||||
|
currentMappedImageIndex = mappedImages.indexOf(filePath)
|
||||||
|
wasMapped = true
|
||||||
|
}
|
||||||
|
if (deltaX < 0){
|
||||||
|
if (currentMappedImageIndex == mappedImages.size-1){
|
||||||
|
currentMappedImageIndex = 0
|
||||||
|
} else {
|
||||||
|
currentMappedImageIndex += 1
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (currentMappedImageIndex == 0){
|
||||||
|
currentMappedImageIndex = mappedImages.size-1
|
||||||
|
} else {
|
||||||
|
currentMappedImageIndex -= 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
loadWholeFile(mappedImages[currentMappedImageIndex])?.let {
|
||||||
|
glideImage = Glide.with(this).load(it)
|
||||||
|
glideImage.into(image_viewer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return super.dispatchTouchEvent(event)
|
||||||
|
}
|
||||||
|
|
||||||
class RotateTransformation(private val rotationAngle: Float): BitmapTransformation() {
|
class RotateTransformation(private val rotationAngle: Float): BitmapTransformation() {
|
||||||
|
|
||||||
override fun transform(pool: BitmapPool, toTransform: Bitmap, outWidth: Int, outHeight: Int): Bitmap {
|
override fun transform(pool: BitmapPool, toTransform: Bitmap, outWidth: Int, outHeight: Int): Bitmap {
|
||||||
@ -45,6 +99,7 @@ class ImageViewer: FileViewerActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun rotateImage(){
|
private fun rotateImage(){
|
||||||
|
image_viewer.restoreZoomNormal()
|
||||||
glideImage.transform(RotateTransformation(rotationAngle)).into(image_viewer)
|
glideImage.transform(RotateTransformation(rotationAngle)).into(image_viewer)
|
||||||
}
|
}
|
||||||
fun onCLickRotateRight(view: View){
|
fun onCLickRotateRight(view: View){
|
||||||
|
@ -68,14 +68,14 @@ class TextEditor: FileViewerActivity() {
|
|||||||
private fun save(): Boolean{
|
private fun save(): Boolean{
|
||||||
var success = false
|
var success = false
|
||||||
val content = editor.text.toString().toByteArray()
|
val content = editor.text.toString().toByteArray()
|
||||||
val handleID = gocryptfsVolume.open_write_mode(filePath)
|
val handleID = gocryptfsVolume.openWriteMode(filePath)
|
||||||
if (handleID != -1){
|
if (handleID != -1){
|
||||||
val buff = ByteArrayInputStream(content)
|
val buff = ByteArrayInputStream(content)
|
||||||
var offset: Long = 0
|
var offset: Long = 0
|
||||||
val io_buffer = ByteArray(GocryptfsVolume.DefaultBS)
|
val io_buffer = ByteArray(GocryptfsVolume.DefaultBS)
|
||||||
var length: Int
|
var length: Int
|
||||||
while (buff.read(io_buffer).also { length = it } > 0) {
|
while (buff.read(io_buffer).also { length = it } > 0) {
|
||||||
val written = gocryptfsVolume.write_file(handleID, offset, io_buffer, length).toLong()
|
val written = gocryptfsVolume.writeFile(handleID, offset, io_buffer, length).toLong()
|
||||||
if (written == length.toLong()) {
|
if (written == length.toLong()) {
|
||||||
offset += written
|
offset += written
|
||||||
} else {
|
} else {
|
||||||
@ -85,7 +85,7 @@ class TextEditor: FileViewerActivity() {
|
|||||||
if (offset == content.size.toLong()){
|
if (offset == content.size.toLong()){
|
||||||
success = gocryptfsVolume.truncate(filePath, offset)
|
success = gocryptfsVolume.truncate(filePath, offset)
|
||||||
}
|
}
|
||||||
gocryptfsVolume.close_file(handleID)
|
gocryptfsVolume.closeFile(handleID)
|
||||||
buff.close()
|
buff.close()
|
||||||
}
|
}
|
||||||
if (success){
|
if (success){
|
||||||
|
@ -34,7 +34,7 @@ object ExternalProvider {
|
|||||||
val tmpFileUri = RestrictedFileProvider.newFile(fileName)
|
val tmpFileUri = RestrictedFileProvider.newFile(fileName)
|
||||||
if (tmpFileUri != null){
|
if (tmpFileUri != null){
|
||||||
storedFiles.add(tmpFileUri)
|
storedFiles.add(tmpFileUri)
|
||||||
if (gocryptfsVolume.export_file(context, file_path, tmpFileUri)) {
|
if (gocryptfsVolume.exportFile(context, file_path, tmpFileUri)) {
|
||||||
return Pair(tmpFileUri, getContentType(fileName, previous_content_type))
|
return Pair(tmpFileUri, getContentType(fileName, previous_content_type))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,9 +25,9 @@ class GocryptfsVolume(var sessionID: Int) {
|
|||||||
const val KeyLen = 32
|
const val KeyLen = 32
|
||||||
const val ScryptDefaultLogN = 16
|
const val ScryptDefaultLogN = 16
|
||||||
const val DefaultBS = 4096
|
const val DefaultBS = 4096
|
||||||
external fun create_volume(root_cipher_dir: String, password: CharArray, logN: Int, creator: String): Boolean
|
external fun createVolume(root_cipher_dir: String, password: CharArray, logN: Int, creator: String): Boolean
|
||||||
external fun init(root_cipher_dir: String, password: CharArray?, givenHash: ByteArray?, returnedHash: ByteArray?): Int
|
external fun init(root_cipher_dir: String, password: CharArray?, givenHash: ByteArray?, returnedHash: ByteArray?): Int
|
||||||
external fun change_password(root_cipher_dir: String, old_password: CharArray?, givenHash: ByteArray?, new_password: CharArray, returnedHash: ByteArray?): Boolean
|
external fun changePassword(root_cipher_dir: String, old_password: CharArray?, givenHash: ByteArray?, new_password: CharArray, returnedHash: ByteArray?): Boolean
|
||||||
|
|
||||||
init {
|
init {
|
||||||
System.loadLibrary("gocryptfs_jni")
|
System.loadLibrary("gocryptfs_jni")
|
||||||
@ -38,7 +38,7 @@ class GocryptfsVolume(var sessionID: Int) {
|
|||||||
native_close(sessionID)
|
native_close(sessionID)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun list_dir(dir_path: String): MutableList<ExplorerElement> {
|
fun listDir(dir_path: String): MutableList<ExplorerElement> {
|
||||||
return native_list_dir(sessionID, dir_path)
|
return native_list_dir(sessionID, dir_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,35 +50,35 @@ class GocryptfsVolume(var sessionID: Int) {
|
|||||||
return native_rmdir(sessionID, dir_path)
|
return native_rmdir(sessionID, dir_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun remove_file(file_path: String): Boolean {
|
fun removeFile(file_path: String): Boolean {
|
||||||
return native_remove_file(sessionID, file_path)
|
return native_remove_file(sessionID, file_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun path_exists(file_path: String): Boolean {
|
fun pathExists(file_path: String): Boolean {
|
||||||
return native_path_exists(sessionID, file_path)
|
return native_path_exists(sessionID, file_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun get_size(file_path: String): Long {
|
fun getSize(file_path: String): Long {
|
||||||
return native_get_size(sessionID, file_path)
|
return native_get_size(sessionID, file_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun close_file(handleID: Int) {
|
fun closeFile(handleID: Int) {
|
||||||
native_close_file(sessionID, handleID)
|
native_close_file(sessionID, handleID)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun open_read_mode(file_path: String): Int {
|
fun openReadMode(file_path: String): Int {
|
||||||
return native_open_read_mode(sessionID, file_path)
|
return native_open_read_mode(sessionID, file_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun open_write_mode(file_path: String): Int {
|
fun openWriteMode(file_path: String): Int {
|
||||||
return native_open_write_mode(sessionID, file_path)
|
return native_open_write_mode(sessionID, file_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun read_file(handleID: Int, offset: Long, buff: ByteArray): Int {
|
fun readFile(handleID: Int, offset: Long, buff: ByteArray): Int {
|
||||||
return native_read_file(sessionID, handleID, offset, buff)
|
return native_read_file(sessionID, handleID, offset, buff)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun write_file(handleID: Int, offset: Long, buff: ByteArray, buff_size: Int): Int {
|
fun writeFile(handleID: Int, offset: Long, buff: ByteArray, buff_size: Int): Int {
|
||||||
return native_write_file(sessionID, handleID, offset, buff, buff_size)
|
return native_write_file(sessionID, handleID, offset, buff, buff_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,7 +90,7 @@ class GocryptfsVolume(var sessionID: Int) {
|
|||||||
return native_rename(sessionID, old_path, new_path)
|
return native_rename(sessionID, old_path, new_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun export_file(handleID: Int, os: OutputStream): Boolean {
|
fun exportFile(handleID: Int, os: OutputStream): Boolean {
|
||||||
var offset: Long = 0
|
var offset: Long = 0
|
||||||
val ioBuffer = ByteArray(DefaultBS)
|
val ioBuffer = ByteArray(DefaultBS)
|
||||||
var length: Int
|
var length: Int
|
||||||
@ -102,29 +102,29 @@ class GocryptfsVolume(var sessionID: Int) {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun export_file(src_path: String, os: OutputStream): Boolean {
|
fun exportFile(src_path: String, os: OutputStream): Boolean {
|
||||||
var success = false
|
var success = false
|
||||||
val srcHandleId = open_read_mode(src_path)
|
val srcHandleId = openReadMode(src_path)
|
||||||
if (srcHandleId != -1) {
|
if (srcHandleId != -1) {
|
||||||
success = export_file(srcHandleId, os)
|
success = exportFile(srcHandleId, os)
|
||||||
close_file(srcHandleId)
|
closeFile(srcHandleId)
|
||||||
}
|
}
|
||||||
return success
|
return success
|
||||||
}
|
}
|
||||||
|
|
||||||
fun export_file(src_path: String, dst_path: String): Boolean {
|
fun exportFile(src_path: String, dst_path: String): Boolean {
|
||||||
return export_file(src_path, FileOutputStream(dst_path))
|
return exportFile(src_path, FileOutputStream(dst_path))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun export_file(context: Context, src_path: String, output_path: Uri): Boolean {
|
fun exportFile(context: Context, src_path: String, output_path: Uri): Boolean {
|
||||||
val os = context.contentResolver.openOutputStream(output_path)
|
val os = context.contentResolver.openOutputStream(output_path)
|
||||||
if (os != null){
|
if (os != null){
|
||||||
return export_file(src_path, os)
|
return exportFile(src_path, os)
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
fun import_file(inputStream: InputStream, handleID: Int): Boolean {
|
fun importFile(inputStream: InputStream, handleID: Int): Boolean {
|
||||||
var offset: Long = 0
|
var offset: Long = 0
|
||||||
val ioBuffer = ByteArray(DefaultBS)
|
val ioBuffer = ByteArray(DefaultBS)
|
||||||
var length: Int
|
var length: Int
|
||||||
@ -142,22 +142,33 @@ class GocryptfsVolume(var sessionID: Int) {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun import_file(inputStream: InputStream, dst_path: String): Boolean {
|
fun importFile(inputStream: InputStream, dst_path: String): Boolean {
|
||||||
var success = false
|
var success = false
|
||||||
val dstHandleId = open_write_mode(dst_path)
|
val dstHandleId = openWriteMode(dst_path)
|
||||||
if (dstHandleId != -1) {
|
if (dstHandleId != -1) {
|
||||||
success = import_file(inputStream, dstHandleId)
|
success = importFile(inputStream, dstHandleId)
|
||||||
close_file(dstHandleId)
|
closeFile(dstHandleId)
|
||||||
}
|
}
|
||||||
return success
|
return success
|
||||||
}
|
}
|
||||||
|
|
||||||
fun import_file(context: Context, src_uri: Uri, dst_path: String): Boolean {
|
fun importFile(context: Context, src_uri: Uri, dst_path: String): Boolean {
|
||||||
val inputStream = context.contentResolver.openInputStream(src_uri)
|
val inputStream = context.contentResolver.openInputStream(src_uri)
|
||||||
if (inputStream != null){
|
if (inputStream != null){
|
||||||
return import_file(inputStream, dst_path)
|
return importFile(inputStream, dst_path)
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun recursiveMapFiles(rootPath: String): MutableList<ExplorerElement> {
|
||||||
|
val result = mutableListOf<ExplorerElement>()
|
||||||
|
val explorerElements = listDir(rootPath)
|
||||||
|
result.addAll(explorerElements)
|
||||||
|
for (e in explorerElements){
|
||||||
|
if (e.isDirectory){
|
||||||
|
result.addAll(recursiveMapFiles(e.getFullPath()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
}
|
}
|
@ -112,8 +112,16 @@ public class ZoomableImageView extends androidx.appcompat.widget.AppCompatImageV
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMaxZoom(float x) {
|
public boolean isZoomed(){
|
||||||
maxScale = x;
|
return saveScale > minScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void restoreZoomNormal(){
|
||||||
|
float origScale = saveScale;
|
||||||
|
saveScale = minScale;
|
||||||
|
float mScaleFactor = minScale / origScale;
|
||||||
|
matrix.postScale(mScaleFactor, mScaleFactor, viewWidth/2, viewHeight/2);
|
||||||
|
fixTrans();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -124,20 +132,17 @@ public class ZoomableImageView extends androidx.appcompat.widget.AppCompatImageV
|
|||||||
@Override
|
@Override
|
||||||
public boolean onDoubleTap(MotionEvent e) {
|
public boolean onDoubleTap(MotionEvent e) {
|
||||||
// Double tap is detected
|
// Double tap is detected
|
||||||
float origScale = saveScale;
|
|
||||||
float mScaleFactor;
|
|
||||||
|
|
||||||
if (saveScale >= maxScale) {
|
if (saveScale >= maxScale) {
|
||||||
saveScale = minScale;
|
restoreZoomNormal();
|
||||||
mScaleFactor = minScale / origScale;
|
|
||||||
matrix.postScale(mScaleFactor, mScaleFactor, viewWidth/2, viewHeight/2);
|
|
||||||
} else {
|
} else {
|
||||||
|
float origScale = saveScale;
|
||||||
saveScale *= 1.5;
|
saveScale *= 1.5;
|
||||||
mScaleFactor = saveScale / origScale;
|
float mScaleFactor = saveScale / origScale;
|
||||||
matrix.postScale(mScaleFactor, mScaleFactor, e.getX(), e.getY());
|
matrix.postScale(mScaleFactor, mScaleFactor, e.getX(), e.getY());
|
||||||
|
fixTrans();
|
||||||
}
|
}
|
||||||
|
|
||||||
fixTrans();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ void jbyteArray_to_unsignedCharArray(const jbyte* src, unsigned char* dst, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jboolean JNICALL
|
JNIEXPORT jboolean JNICALL
|
||||||
Java_sushi_hardcore_droidfs_util_GocryptfsVolume_00024Companion_create_1volume(JNIEnv *env, jclass clazz,
|
Java_sushi_hardcore_droidfs_util_GocryptfsVolume_00024Companion_createVolume(JNIEnv *env, jclass clazz,
|
||||||
jstring jroot_cipher_dir, jcharArray jpassword,
|
jstring jroot_cipher_dir, jcharArray jpassword,
|
||||||
jint logN,
|
jint logN,
|
||||||
jstring jcreator) {
|
jstring jcreator) {
|
||||||
@ -127,7 +127,7 @@ Java_sushi_hardcore_droidfs_util_GocryptfsVolume_00024Companion_init(JNIEnv *env
|
|||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jboolean JNICALL
|
JNIEXPORT jboolean JNICALL
|
||||||
Java_sushi_hardcore_droidfs_util_GocryptfsVolume_00024Companion_change_1password(JNIEnv *env, jclass clazz,
|
Java_sushi_hardcore_droidfs_util_GocryptfsVolume_00024Companion_changePassword(JNIEnv *env, jclass clazz,
|
||||||
jstring jroot_cipher_dir,
|
jstring jroot_cipher_dir,
|
||||||
jcharArray jold_password,
|
jcharArray jold_password,
|
||||||
jbyteArray jgiven_hash,
|
jbyteArray jgiven_hash,
|
||||||
|
Loading…
Reference in New Issue
Block a user