Allow importing certificate from file

This commit is contained in:
Mygod 2019-01-14 13:54:35 +08:00
parent 27165740d5
commit f940595e6e
2 changed files with 87 additions and 1 deletions

View file

@ -0,0 +1,52 @@
/*******************************************************************************
* *
* Copyright (C) 2019 by Max Lv <max.c.lv@gmail.com> *
* Copyright (C) 2019 by Mygod Studio <contact-shadowsocks-android@mygod.be> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
package com.github.shadowsocks.plugin.v2ray
import android.content.ActivityNotFoundException
import android.content.Intent
import android.view.View
import androidx.appcompat.app.AlertDialog
import androidx.core.os.bundleOf
import androidx.preference.EditTextPreferenceDialogFragmentCompat
import com.google.android.material.snackbar.Snackbar
class CertificatePreferenceDialogFragment : EditTextPreferenceDialogFragmentCompat() {
fun setKey(key: String) {
arguments = bundleOf(Pair(ARG_KEY, key))
}
override fun onPrepareDialogBuilder(builder: AlertDialog.Builder) {
super.onPrepareDialogBuilder(builder)
builder.setNeutralButton("Browse…") { _, _ ->
val activity = requireActivity()
try {
targetFragment!!.startActivityForResult(Intent(Intent.ACTION_GET_CONTENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
type = "application/pkix-cert"
}, ConfigFragment.REQUEST_BROWSE_CERTIFICATE)
return@setNeutralButton
} catch (_: ActivityNotFoundException) { } catch (_: SecurityException) { }
Snackbar.make(activity.findViewById<View>(R.id.content),
"Please install a file manager like MiXplorer",
Snackbar.LENGTH_SHORT).show()
}
}
}

View file

@ -20,14 +20,23 @@
package com.github.shadowsocks.plugin.v2ray package com.github.shadowsocks.plugin.v2ray
import android.app.Activity
import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.View
import androidx.preference.EditTextPreference import androidx.preference.EditTextPreference
import androidx.preference.ListPreference import androidx.preference.ListPreference
import androidx.preference.Preference import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceFragmentCompat
import com.github.shadowsocks.plugin.PluginOptions import com.github.shadowsocks.plugin.PluginOptions
import com.google.android.material.snackbar.Snackbar
import java.lang.RuntimeException
class ConfigFragment : PreferenceFragmentCompat(), Preference.OnPreferenceChangeListener { class ConfigFragment : PreferenceFragmentCompat(), Preference.OnPreferenceChangeListener {
companion object {
const val REQUEST_BROWSE_CERTIFICATE = 1
}
private val mode by lazy { findPreference<ListPreference>("mode") } private val mode by lazy { findPreference<ListPreference>("mode") }
private val host by lazy { findPreference<EditTextPreference>("host") } private val host by lazy { findPreference<EditTextPreference>("host") }
private val path by lazy { findPreference<EditTextPreference>("path") } private val path by lazy { findPreference<EditTextPreference>("path") }
@ -53,7 +62,7 @@ class ConfigFragment : PreferenceFragmentCompat(), Preference.OnPreferenceChange
putWithDefault("tls", tls) putWithDefault("tls", tls)
putWithDefault("host", host.text, "cloudfront.com") putWithDefault("host", host.text, "cloudfront.com")
putWithDefault("path", path.text, "/") putWithDefault("path", path.text, "/")
putWithDefault("certRaw", certRaw.text, "") putWithDefault("certRaw", certRaw.text.replace("\n", ""), "")
} }
fun onInitializePluginOptions(options: PluginOptions) { fun onInitializePluginOptions(options: PluginOptions) {
@ -78,4 +87,29 @@ class ConfigFragment : PreferenceFragmentCompat(), Preference.OnPreferenceChange
certRaw.isEnabled = mode != null || tls != null certRaw.isEnabled = mode != null || tls != null
return true return true
} }
override fun onDisplayPreferenceDialog(preference: Preference?) {
if (preference == certRaw) CertificatePreferenceDialogFragment().apply {
setKey(certRaw.key)
setTargetFragment(this@ConfigFragment, 0)
}.show(fragmentManager ?: return, certRaw.key) else super.onDisplayPreferenceDialog(preference)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
when (requestCode) {
REQUEST_BROWSE_CERTIFICATE -> {
if (resultCode != Activity.RESULT_OK) return
val activity = requireActivity()
try {
// we read all its content here to avoid content URL permission issues
certRaw.text = activity.contentResolver.openInputStream(data!!.data!!)!!
.bufferedReader().readText()
} catch (e: RuntimeException) {
Snackbar.make(activity.findViewById<View>(R.id.content), e.localizedMessage, Snackbar.LENGTH_LONG)
.show()
}
}
else -> super.onActivityResult(requestCode, resultCode, data)
}
}
} }