2020-07-17 16:35:39 +02:00
package sushi.hardcore.droidfs
import android.app.Activity
import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.view.View
2020-07-18 18:44:53 +02:00
import android.view.WindowManager
2020-07-17 16:35:39 +02:00
import android.widget.AdapterView.OnItemClickListener
import android.widget.Toast
import kotlinx.android.synthetic.main.activity_change_password.*
import kotlinx.android.synthetic.main.activity_open.*
import kotlinx.android.synthetic.main.activity_open.checkbox_remember_path
import kotlinx.android.synthetic.main.activity_open.checkbox_save_password
import kotlinx.android.synthetic.main.activity_open.edit_password
import kotlinx.android.synthetic.main.activity_open.edit_volume_path
import kotlinx.android.synthetic.main.activity_open.saved_path_listview
import kotlinx.android.synthetic.main.toolbar.*
import sushi.hardcore.droidfs.adapters.SavedVolumesAdapter
import sushi.hardcore.droidfs.explorers.ExplorerActivity
import sushi.hardcore.droidfs.explorers.ExplorerActivityDrop
import sushi.hardcore.droidfs.explorers.ExplorerActivityPick
import sushi.hardcore.droidfs.fingerprint_stuff.FingerprintPasswordHashSaver
import sushi.hardcore.droidfs.util.FilesUtils
import sushi.hardcore.droidfs.util.GocryptfsVolume
import sushi.hardcore.droidfs.util.WidgetUtil
import sushi.hardcore.droidfs.util.Wiper
import sushi.hardcore.droidfs.widgets.ColoredAlertDialog
import java.io.File
import java.util.*
class OpenActivity : ColoredActivity ( ) {
companion object {
private const val PICK _DIRECTORY _REQUEST _CODE = 1
}
private lateinit var savedVolumesAdapter : SavedVolumesAdapter
private lateinit var fingerprintPasswordHashSaver : FingerprintPasswordHashSaver
private lateinit var root _cipher _dir : String
private var sessionID = - 1
private var usf _fingerprint = false
override fun onCreate ( savedInstanceState : Bundle ? ) {
super . onCreate ( savedInstanceState )
2020-07-18 18:44:53 +02:00
if ( ! sharedPrefs . getBoolean ( " usf_screenshot " , false ) ) {
window . setFlags ( WindowManager . LayoutParams . FLAG _SECURE , WindowManager . LayoutParams . FLAG _SECURE )
}
2020-07-17 16:35:39 +02:00
setContentView ( R . layout . activity _open )
setSupportActionBar ( toolbar )
//val sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this)
usf _fingerprint = sharedPrefs . getBoolean ( " usf_fingerprint " , false )
if ( Build . VERSION . SDK _INT >= Build . VERSION_CODES . M && usf _fingerprint ) {
fingerprintPasswordHashSaver = FingerprintPasswordHashSaver ( this , sharedPrefs )
} else {
WidgetUtil . hide ( checkbox _save _password )
}
savedVolumesAdapter = SavedVolumesAdapter ( this , sharedPrefs )
if ( savedVolumesAdapter . count > 0 ) {
saved _path _listview . adapter = savedVolumesAdapter
saved _path _listview . onItemClickListener = OnItemClickListener { _ , _ , position , _ ->
root _cipher _dir = savedVolumesAdapter . getItem ( position )
edit _volume _path . setText ( root _cipher _dir )
val cipherText = sharedPrefs . getString ( root _cipher _dir , null )
if ( cipherText != null ) { //password hash saved
fingerprintPasswordHashSaver . decrypt ( cipherText , root _cipher _dir , :: openUsingPasswordHash )
}
}
} else {
WidgetUtil . hide ( saved _path _listview )
}
edit _password . setOnEditorActionListener { v , _ , _ ->
onClickOpen ( v )
true
}
}
fun pick _directory ( view : View ? ) {
val i = Intent ( Intent . ACTION _OPEN _DOCUMENT _TREE )
startActivityForResult ( i , PICK _DIRECTORY _REQUEST _CODE )
}
override fun onActivityResult ( requestCode : Int , resultCode : Int , data : Intent ? ) {
super . onActivityResult ( requestCode , resultCode , data )
if ( resultCode == Activity . RESULT _OK ) {
if ( requestCode == PICK _DIRECTORY _REQUEST _CODE ) {
if ( data != null ) {
val path = FilesUtils . getFullPathFromTreeUri ( data . data , this )
edit _volume _path . setText ( path )
}
}
}
}
fun onClickOpen ( view : View ? ) {
root _cipher _dir = edit _volume _path . text . toString ( ) //fresh get in case of manual rewrite
if ( root _cipher _dir . isEmpty ( ) ) {
Toast . makeText ( this , R . string . enter _volume _path , Toast . LENGTH _SHORT ) . show ( )
} else {
val password = edit _password . text . toString ( ) . toCharArray ( )
var returnedHash : ByteArray ? = null
if ( usf _fingerprint && checkbox _save _password . isChecked ) {
returnedHash = ByteArray ( GocryptfsVolume . KeyLen )
}
sessionID = GocryptfsVolume . init ( root _cipher _dir , password , null , returnedHash )
if ( sessionID != - 1 ) {
var startExplorerImmediately = true
if ( checkbox _remember _path . isChecked ) {
savedVolumesAdapter . addVolumePath ( root _cipher _dir )
if ( checkbox _save _password . isChecked && returnedHash != null ) {
fingerprintPasswordHashSaver . encryptAndSave ( returnedHash , root _cipher _dir ) { success ->
if ( success ) {
startExplorer ( )
}
}
startExplorerImmediately = false
}
}
if ( startExplorerImmediately ) {
startExplorer ( )
}
} else {
ColoredAlertDialog ( this )
. setTitle ( R . string . open _volume _failed )
. setMessage ( R . string . open _volume _failed _msg )
. setPositiveButton ( R . string . ok , null )
. show ( )
}
Arrays . fill ( password , 0. toChar ( ) )
}
}
private fun openUsingPasswordHash ( passwordHash : ByteArray ) {
sessionID = GocryptfsVolume . init ( root _cipher _dir , null , passwordHash , null )
if ( sessionID != - 1 ) {
startExplorer ( )
} else {
ColoredAlertDialog ( this )
. setTitle ( R . string . open _volume _failed )
. setMessage ( getString ( R . string . open _failed _hash _msg ) )
. setPositiveButton ( R . string . ok , null )
. show ( )
}
Arrays . fill ( passwordHash , 0 )
}
private fun startExplorer ( ) {
var explorer _intent : Intent ? = null
val current _intent _action = intent . action
if ( current _intent _action != null ) {
if ( ( current _intent _action == Intent . ACTION _SEND || current _intent _action == Intent . ACTION _SEND _MULTIPLE ) && intent . extras != null ) { //import via android share menu
explorer _intent = Intent ( this , ExplorerActivityDrop :: class . java )
explorer _intent . action = current _intent _action //forward action
explorer _intent . putExtras ( intent . extras !! ) //forward extras
} else if ( current _intent _action == " pick " ) { //pick items to import
explorer _intent = Intent ( this , ExplorerActivityPick :: class . java )
explorer _intent . flags = Intent . FLAG _ACTIVITY _FORWARD _RESULT
}
}
if ( explorer _intent == null ) {
explorer _intent = Intent ( this , ExplorerActivity :: class . java ) //default opening
}
explorer _intent . putExtra ( " sessionID " , sessionID )
explorer _intent . putExtra ( " volume_name " , File ( root _cipher _dir ) . name )
startActivity ( explorer _intent )
finish ( )
}
fun onClickSavePasswordHash ( view : View ) {
if ( checkbox _save _password . isChecked ) {
if ( ! fingerprintPasswordHashSaver . canAuthenticate ( ) ) {
checkbox _save _password . isChecked = false
} else {
checkbox _remember _path . isChecked = true
}
}
}
fun onClickRememberPath ( view : View ) {
if ( ! checkbox _remember _path . isChecked ) {
checkbox _save _password . isChecked = false
}
}
override fun onPause ( ) {
super . onPause ( )
if ( :: fingerprintPasswordHashSaver . isInitialized && fingerprintPasswordHashSaver . isListening ) {
fingerprintPasswordHashSaver . stopListening ( )
if ( fingerprintPasswordHashSaver . fingerprintFragment . isAdded ) {
fingerprintPasswordHashSaver . fingerprintFragment . dismiss ( )
}
}
}
override fun onDestroy ( ) {
super . onDestroy ( )
Wiper . wipeEditText ( edit _password )
}
}