move the protection related things in the Commons library

This commit is contained in:
tibbi 2017-08-03 23:43:04 +02:00
parent 35944eef4d
commit 3fe5aaa451
17 changed files with 4 additions and 610 deletions

View file

@ -37,14 +37,13 @@ android {
}
dependencies {
compile 'com.simplemobiletools:commons:2.23.7'
compile 'com.simplemobiletools:commons:2.23.8'
compile 'com.davemorrissey.labs:subsampling-scale-image-view:3.6.0'
compile 'com.theartofdev.edmodo:android-image-cropper:2.4.0'
compile 'com.bignerdranch.android:recyclerview-multiselect:0.2'
compile 'com.google.code.gson:gson:2.8.0'
compile 'com.github.chrisbanes:PhotoView:2.1.2'
compile 'it.sephiroth.android.exif:library:1.0.1'
compile 'com.andrognito.patternlockview:patternlockview:1.0.0'
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5.1'

View file

@ -4,12 +4,13 @@ import android.content.Intent
import android.content.res.Resources
import android.os.Bundle
import com.simplemobiletools.commons.dialogs.RadioGroupDialog
import com.simplemobiletools.commons.dialogs.SecurityDialog
import com.simplemobiletools.commons.extensions.handleHiddenFolderPasswordProtection
import com.simplemobiletools.commons.extensions.updateTextColors
import com.simplemobiletools.commons.helpers.SHOW_ALL_TABS
import com.simplemobiletools.commons.models.RadioItem
import com.simplemobiletools.gallery.R
import com.simplemobiletools.gallery.dialogs.SecurityDialog
import com.simplemobiletools.gallery.extensions.config
import com.simplemobiletools.gallery.extensions.handleHiddenFolderPasswordProtection
import com.simplemobiletools.gallery.helpers.*
import kotlinx.android.synthetic.main.activity_settings.*

View file

@ -1,33 +0,0 @@
package com.simplemobiletools.gallery.adapters
import android.content.Context
import android.support.v4.view.PagerAdapter
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.simplemobiletools.gallery.R
import com.simplemobiletools.gallery.interfaces.HashListener
import com.simplemobiletools.gallery.interfaces.SecurityTab
class PasswordTypesAdapter(val context: Context, val requiredHash: String, val hashListener: HashListener) : PagerAdapter() {
override fun instantiateItem(container: ViewGroup, position: Int): Any {
val view = LayoutInflater.from(context).inflate(layoutSelection(position), container, false)
container.addView(view)
(view as SecurityTab).initTab(requiredHash, hashListener)
return view
}
override fun destroyItem(container: ViewGroup, position: Int, item: Any) {
container.removeView(item as View)
}
override fun getCount() = 2
override fun isViewFromObject(view: View, item: Any) = view == item
private fun layoutSelection(position: Int): Int = when (position) {
0 -> R.layout.tab_pattern
1 -> R.layout.tab_pin
else -> throw RuntimeException("Only 2 tabs allowed")
}
}

View file

@ -1,75 +0,0 @@
package com.simplemobiletools.gallery.dialogs
import android.support.design.widget.TabLayout
import android.support.v4.view.ViewPager
import android.support.v7.app.AlertDialog
import android.view.LayoutInflater
import com.simplemobiletools.commons.extensions.beGone
import com.simplemobiletools.commons.extensions.setupDialogStuff
import com.simplemobiletools.gallery.R
import com.simplemobiletools.gallery.activities.SimpleActivity
import com.simplemobiletools.gallery.adapters.PasswordTypesAdapter
import com.simplemobiletools.gallery.extensions.config
import com.simplemobiletools.gallery.helpers.SHOW_ALL_TABS
import com.simplemobiletools.gallery.interfaces.HashListener
import com.simplemobiletools.gallery.views.MyDialogViewPager
import kotlinx.android.synthetic.main.dialog_security.view.*
class SecurityDialog(val activity: SimpleActivity, val requiredHash: String, val showTabIndex: Int, val callback: (hash: String, type: Int) -> Unit) : HashListener {
var dialog: AlertDialog? = null
val view = LayoutInflater.from(activity).inflate(R.layout.dialog_security, null)
init {
view.apply {
val viewPager = findViewById(R.id.dialog_tab_view_pager) as MyDialogViewPager
viewPager.adapter = PasswordTypesAdapter(context, requiredHash, this@SecurityDialog)
viewPager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
override fun onPageScrollStateChanged(state: Int) {
}
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
}
override fun onPageSelected(position: Int) {
dialog_tab_layout.getTabAt(position)!!.select()
}
})
if (showTabIndex == SHOW_ALL_TABS) {
val textColor = context.config.textColor
dialog_tab_layout.setTabTextColors(textColor, textColor)
dialog_tab_layout.setSelectedTabIndicatorColor(context.config.primaryColor)
dialog_tab_layout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
override fun onTabReselected(tab: TabLayout.Tab?) {
}
override fun onTabUnselected(tab: TabLayout.Tab) {
}
override fun onTabSelected(tab: TabLayout.Tab) {
if (tab.text.toString().equals(resources.getString(R.string.pattern), true)) {
viewPager.currentItem = 0
} else {
viewPager.currentItem = 1
}
}
})
} else {
dialog_tab_layout.beGone()
viewPager.currentItem = showTabIndex
viewPager.allowSwiping = false
}
}
dialog = AlertDialog.Builder(activity)
.setNegativeButton(R.string.cancel, null)
.create().apply {
activity.setupDialogStuff(view, this)
}
}
override fun receivedHash(hash: String, type: Int) {
callback(hash, type)
dialog!!.dismiss()
}
}

View file

@ -24,7 +24,6 @@ import com.simplemobiletools.commons.helpers.*
import com.simplemobiletools.gallery.BuildConfig
import com.simplemobiletools.gallery.R
import com.simplemobiletools.gallery.activities.SimpleActivity
import com.simplemobiletools.gallery.dialogs.SecurityDialog
import com.simplemobiletools.gallery.helpers.NOMEDIA
import com.simplemobiletools.gallery.helpers.REQUEST_EDIT_IMAGE
import com.simplemobiletools.gallery.helpers.REQUEST_SET_AS
@ -333,16 +332,6 @@ fun Activity.loadStaticGif(path: String, target: MySquareImageView) {
builder.apply(options).into(target)
}
fun SimpleActivity.handleHiddenFolderPasswordProtection(callback: () -> Unit) {
if (config.isPasswordProtectionOn) {
SecurityDialog(this, config.passwordHash, config.protectionType) { hash, type ->
callback()
}
} else {
callback()
}
}
fun Activity.getCachedDirectories(): ArrayList<Directory> {
val token = object : TypeToken<List<Directory>>() {}.type
return Gson().fromJson<ArrayList<Directory>>(config.directories, token) ?: ArrayList<Directory>(1)

View file

@ -232,16 +232,4 @@ class Config(context: Context) : BaseConfig(context) {
var replaceShare: Boolean
get() = prefs.getBoolean(REPLACE_SHARE_WITH_ROTATE, false)
set(replaceShare) = prefs.edit().putBoolean(REPLACE_SHARE_WITH_ROTATE, replaceShare).apply()
var isPasswordProtectionOn: Boolean
get() = prefs.getBoolean(IS_PASSWORD_PROTECTION, false)
set(passwordProtection) = prefs.edit().putBoolean(IS_PASSWORD_PROTECTION, passwordProtection).apply()
var passwordHash: String
get() = prefs.getString(PASSWORD_HASH, "")
set(passwordHash) = prefs.edit().putString(PASSWORD_HASH, passwordHash).apply()
var protectionType: Int
get() = prefs.getInt(PROTECTION_TYPE, PROTECTION_PATTERN)
set(protectionType) = prefs.edit().putInt(PROTECTION_TYPE, protectionType).apply()
}

View file

@ -33,9 +33,6 @@ val ALBUM_COVERS = "album_covers"
val SCROLL_HORIZONTALLY = "scroll_horizontally"
val HIDE_SYSTEM_UI = "hide_system_ui"
val REPLACE_SHARE_WITH_ROTATE = "replace_share_with_rotate"
val IS_PASSWORD_PROTECTION = "password_protection"
val PASSWORD_HASH = "password_hash"
val PROTECTION_TYPE = "protection_type"
val NOMEDIA = ".nomedia"
@ -65,12 +62,3 @@ val ORIENT_PORTRAIT = 0
val ORIENT_LANDSCAPE_LEFT = 1
val ORIENT_LANDSCAPE_RIGHT = 2
val ORIENT_UPSIDE_DOWN = 3
// security
val PROTECTION_PATTERN = 0
val PROTECTION_PIN = 1
val PROTECTION_FINGERPRINT = 2
val SHOW_ALL_TABS = -1
val SHOW_PATTERN = 0
val SHOW_PIN = 1

View file

@ -1,5 +0,0 @@
package com.simplemobiletools.gallery.interfaces
interface HashListener {
fun receivedHash(hash: String, type: Int)
}

View file

@ -1,5 +0,0 @@
package com.simplemobiletools.gallery.interfaces
interface SecurityTab {
fun initTab(requiredHash: String, listener: HashListener)
}

View file

@ -1,46 +0,0 @@
package com.simplemobiletools.gallery.views
import android.content.Context
import android.support.v4.view.ViewPager
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
class MyDialogViewPager : ViewPager {
var allowSwiping = true
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
// disable manual swiping of viewpager at the dialog by swiping over the pattern
override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
return false
}
override fun onTouchEvent(ev: MotionEvent): Boolean {
if (!allowSwiping)
return false
try {
return super.onTouchEvent(ev)
} catch (ignored: Exception) {
}
return false
}
// https://stackoverflow.com/a/20784791/1967672
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
var height = 0
for (i in 0..childCount - 1) {
val child = getChildAt(i)
child.measure(widthMeasureSpec, View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED))
val h = child.measuredHeight
if (h > height) height = h
}
val newHeightMeasureSpec = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY)
super.onMeasure(widthMeasureSpec, newHeightMeasureSpec)
}
}

View file

@ -1,74 +0,0 @@
package com.simplemobiletools.gallery.views
import android.content.Context
import android.os.Handler
import android.util.AttributeSet
import android.widget.RelativeLayout
import com.andrognito.patternlockview.PatternLockView
import com.andrognito.patternlockview.listener.PatternLockViewListener
import com.andrognito.patternlockview.utils.PatternLockUtils
import com.simplemobiletools.commons.extensions.toast
import com.simplemobiletools.commons.extensions.updateTextColors
import com.simplemobiletools.gallery.R
import com.simplemobiletools.gallery.extensions.config
import com.simplemobiletools.gallery.helpers.PROTECTION_PATTERN
import com.simplemobiletools.gallery.interfaces.HashListener
import com.simplemobiletools.gallery.interfaces.SecurityTab
import kotlinx.android.synthetic.main.tab_pattern.view.*
class PatternTab(context: Context, attrs: AttributeSet) : RelativeLayout(context, attrs), SecurityTab {
private var hash = ""
private var requiredHash = ""
lateinit var hashListener: HashListener
override fun onFinishInflate() {
super.onFinishInflate()
val textColor = context.config.textColor
context.updateTextColors(pattern_lock_holder)
pattern_lock_view.correctStateColor = context.config.primaryColor
pattern_lock_view.normalStateColor = textColor
pattern_lock_view.addPatternLockListener(object : PatternLockViewListener {
override fun onComplete(pattern: MutableList<PatternLockView.Dot>?) {
receivedHash(PatternLockUtils.patternToSha1(pattern_lock_view, pattern))
}
override fun onCleared() {
}
override fun onStarted() {
}
override fun onProgress(progressPattern: MutableList<PatternLockView.Dot>?) {
}
})
}
override fun initTab(requiredHash: String, listener: HashListener) {
this.requiredHash = requiredHash
hash = requiredHash
hashListener = listener
}
private fun receivedHash(newHash: String) {
if (hash.isEmpty()) {
hash = newHash
pattern_lock_view.clearPattern()
pattern_lock_title.setText(R.string.repeat_pattern)
} else if (hash == newHash) {
pattern_lock_view.setViewMode(PatternLockView.PatternViewMode.CORRECT)
Handler().postDelayed({
hashListener.receivedHash(hash, PROTECTION_PATTERN)
}, 300)
} else {
pattern_lock_view.setViewMode(PatternLockView.PatternViewMode.WRONG)
context.toast(R.string.wrong_pattern)
Handler().postDelayed({
pattern_lock_view.clearPattern()
if (requiredHash.isEmpty()) {
hash = ""
pattern_lock_title.setText(R.string.insert_pattern)
}
}, 1000)
}
}
}

View file

@ -1,100 +0,0 @@
package com.simplemobiletools.gallery.views
import android.content.Context
import android.graphics.PorterDuff
import android.util.AttributeSet
import android.widget.RelativeLayout
import com.simplemobiletools.commons.extensions.toast
import com.simplemobiletools.commons.extensions.updateTextColors
import com.simplemobiletools.gallery.R
import com.simplemobiletools.gallery.extensions.config
import com.simplemobiletools.gallery.helpers.PROTECTION_PIN
import com.simplemobiletools.gallery.interfaces.HashListener
import com.simplemobiletools.gallery.interfaces.SecurityTab
import kotlinx.android.synthetic.main.tab_pin.view.*
import java.math.BigInteger
import java.security.MessageDigest
import java.util.*
class PinTab(context: Context, attrs: AttributeSet) : RelativeLayout(context, attrs), SecurityTab {
private var hash = ""
private var requiredHash = ""
private var pin = ""
lateinit var hashListener: HashListener
override fun onFinishInflate() {
super.onFinishInflate()
context.updateTextColors(pin_lock_holder)
pin_0.setOnClickListener { addNumber("0") }
pin_1.setOnClickListener { addNumber("1") }
pin_2.setOnClickListener { addNumber("2") }
pin_3.setOnClickListener { addNumber("3") }
pin_4.setOnClickListener { addNumber("4") }
pin_5.setOnClickListener { addNumber("5") }
pin_6.setOnClickListener { addNumber("6") }
pin_7.setOnClickListener { addNumber("7") }
pin_8.setOnClickListener { addNumber("8") }
pin_9.setOnClickListener { addNumber("9") }
pin_c.setOnClickListener { clear() }
pin_ok.setOnClickListener { confirmPIN() }
pin_ok.setColorFilter(context.config.textColor, PorterDuff.Mode.SRC_IN)
}
override fun initTab(requiredHash: String, listener: HashListener) {
this.requiredHash = requiredHash
hash = requiredHash
hashListener = listener
}
private fun addNumber(number: String) {
if (pin.length < 10) {
pin += number
updatePinCode()
}
}
private fun clear() {
if (pin.isNotEmpty()) {
pin = pin.substring(0, pin.length - 1)
updatePinCode()
}
}
private fun confirmPIN() {
val newHash = getHashedPin()
if (pin.isEmpty()) {
context.toast(R.string.please_enter_pin)
} else if (hash.isEmpty()) {
hash = newHash
resetPin()
pin_lock_title.setText(R.string.repeat_pin)
} else if (hash == newHash) {
hashListener.receivedHash(hash, PROTECTION_PIN)
} else {
resetPin()
context.toast(R.string.wrong_pin)
if (requiredHash.isEmpty()) {
hash = ""
pin_lock_title.setText(R.string.enter_pin)
}
}
}
private fun resetPin() {
pin = ""
pin_lock_current_pin.text = ""
}
private fun updatePinCode() {
pin_lock_current_pin.text = "*".repeat(pin.length)
}
private fun getHashedPin(): String {
val messageDigest = MessageDigest.getInstance("SHA-1")
messageDigest.update(pin.toByteArray(charset("UTF-8")))
val digest = messageDigest.digest()
val bigInteger = BigInteger(1, digest)
return String.format(Locale.getDefault(), "%0${digest.size * 2}x", bigInteger).toLowerCase()
}
}

View file

@ -1,33 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/dialog_holder"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<android.support.design.widget.TabLayout
android:id="@+id/dialog_tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.design.widget.TabItem
android:id="@+id/dialog_tab_pattern"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/pattern"/>
<android.support.design.widget.TabItem
android:id="@+id/dialog_tab_pin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/pin"/>
</android.support.design.widget.TabLayout>
<com.simplemobiletools.gallery.views.MyDialogViewPager
android:id="@+id/dialog_tab_view_pager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/dialog_tab_layout"/>
</RelativeLayout>

View file

@ -1,22 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<com.simplemobiletools.gallery.views.PatternTab
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pattern_lock_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/pattern_lock_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="@dimen/activity_margin"
android:text="@string/insert_pattern"/>
<com.andrognito.patternlockview.PatternLockView
android:id="@+id/pattern_lock_view"
android:layout_width="280dp"
android:layout_height="280dp"
android:layout_below="@+id/pattern_lock_title"
android:layout_centerInParent="true"/>
</com.simplemobiletools.gallery.views.PatternTab>

View file

@ -1,164 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<com.simplemobiletools.gallery.views.PinTab
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pin_lock_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/pin_lock_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/small_margin"
android:paddingLeft="@dimen/activity_margin"
android:paddingRight="@dimen/activity_margin"
android:paddingTop="@dimen/activity_margin"
android:text="@string/enter_pin"/>
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/pin_lock_current_pin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/pin_lock_title"
android:gravity="center"
android:letterSpacing="1.05"
android:lines="1"
android:maxLength="10"
android:paddingBottom="@dimen/small_margin"
android:paddingTop="@dimen/small_margin"
android:textSize="@dimen/big_text_size"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/pin_lock_current_pin"
android:layout_marginTop="@dimen/activity_margin"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal">
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/pin_1"
style="@style/PinNumberStyle"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="1"/>
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/pin_2"
style="@style/PinNumberStyle"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="2"/>
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/pin_3"
style="@style/PinNumberStyle"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="3"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal">
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/pin_4"
style="@style/PinNumberStyle"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="4"/>
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/pin_5"
style="@style/PinNumberStyle"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="5"/>
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/pin_6"
style="@style/PinNumberStyle"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="6"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal">
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/pin_7"
style="@style/PinNumberStyle"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="7"/>
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/pin_8"
style="@style/PinNumberStyle"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="8"/>
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/pin_9"
style="@style/PinNumberStyle"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="9"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal">
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/pin_c"
style="@style/PinNumberStyle"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="C"/>
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/pin_0"
style="@style/PinNumberStyle"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="0"/>
<ImageView
android:id="@+id/pin_ok"
style="@style/PinNumberStyle"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:padding="@dimen/activity_margin"
android:src="@drawable/ic_check"/>
</LinearLayout>
</LinearLayout>
</com.simplemobiletools.gallery.views.PinTab>

View file

@ -4,8 +4,4 @@
<item name="android:windowTranslucentNavigation">true</item>
</style>
<style name="PinNumberStyle" parent="PinNumberStyle.Base">
<item name="android:background">?attr/selectableItemBackgroundBorderless</item>
</style>
</resources>

View file

@ -16,14 +16,4 @@
<item name="titleTextStyle">@style/AppTheme.ActionBar.TitleTextStyle</item>
</style>
<style name="PinNumberStyle.Base">
<item name="android:gravity">center</item>
<item name="android:padding">@dimen/small_margin</item>
<item name="android:textSize">@dimen/big_text_size</item>
</style>
<style name="PinNumberStyle" parent="PinNumberStyle.Base">
<item name="android:background">?attr/selectableItemBackground</item>
</style>
</resources>