add intent filter for shadowsocks URI #51

This commit is contained in:
Max Lv
2013-12-01 14:56:15 +08:00
parent 1907ac2fef
commit 9511a616e9
10 changed files with 203 additions and 79 deletions
@@ -0,0 +1,77 @@
package com.github.shadowsocks
import android.os.{Message, Handler, Bundle}
import android.app.{ProgressDialog, AlertDialog, Activity}
import android.content.{Intent, DialogInterface}
import com.github.shadowsocks.database.{ProfileManager, Profile}
import com.github.shadowsocks.utils.{Parser, Action}
import android.preference.PreferenceManager
import android.view.WindowManager
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
class ParserActivity extends Activity {
override def onCreate(savedInstanceState: Bundle) {
super.onCreate(savedInstanceState)
showAsPopup(this)
val data = getIntent.getData.toString
new AlertDialog.Builder(this)
.setTitle(R.string.add_profile_dialog)
.setCancelable(false)
.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
override def onClick(dialog: DialogInterface, id: Int) {
Parser.parse(data) match {
case Some(profile) => addProfile(profile)
case _ => // ignore
}
dialog.dismiss()
}
})
.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
override def onClick(dialog: DialogInterface, id: Int) {
dialog.dismiss()
finish()
}
})
.setMessage(data)
.create()
.show()
}
def showAsPopup(activity: Activity) {
activity.getWindow.setFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND,
WindowManager.LayoutParams.FLAG_DIM_BEHIND)
val params = activity.getWindow.getAttributes
params.alpha = 1.0f
params.dimAmount = 0.5f
activity.getWindow.setAttributes(params.asInstanceOf[android.view.WindowManager.LayoutParams])
activity.getWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT))
}
def addProfile(profile: Profile) {
val h = showProgress(getString(R.string.loading))
h.postDelayed(new Runnable {
def run() {
val profileManager =
new ProfileManager(PreferenceManager.getDefaultSharedPreferences(getBaseContext),
getApplication.asInstanceOf[ShadowsocksApplication].dbHelper)
profileManager.createOrUpdateProfile(profile)
profileManager.reload(profile.id)
h.sendEmptyMessage(0)
}
}, 600)
}
private def showProgress(msg: String): Handler = {
val progressDialog = ProgressDialog.show(this, "", msg, true, false)
new Handler {
override def handleMessage(msg: Message) {
progressDialog.dismiss()
finish()
}
}
}
}
@@ -46,6 +46,7 @@ import android.content.Intent
import android.util.Log
import android.preference.PreferenceManager
import com.github.shadowsocks.utils.Extra
import com.actionbarsherlock.app.SherlockActivity
class ShadowVpnActivity extends Activity {
@@ -579,10 +579,20 @@ class Shadowsocks
def onClick(dialog: DialogInterface, which: Int) {
which match {
case 0 => {
val integrator = new IntentIntegrator(Shadowsocks.this)
integrator.initiateScan()
dialog.dismiss()
val h = showProgress(getString(R.string.loading))
h.postDelayed(new Runnable() {
def run() {
val integrator = new IntentIntegrator(Shadowsocks.this)
integrator.initiateScan()
h.sendEmptyMessage(0)
}
}, 600)
}
case 1 => {
dialog.dismiss()
addProfile(id)
}
case 1 => addProfile(id)
case _ =>
}
}
@@ -874,7 +884,7 @@ class Shadowsocks
override def onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
val scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, data)
if (scanResult != null) {
ShadowParser.parse(scanResult.getContents) match {
Parser.parse(scanResult.getContents) match {
case Some(profile) => addProfile(profile)
case _ => // ignore
}
@@ -30,7 +30,7 @@ object Key {
object Scheme {
val APP = "app://"
val PROFILE = "profile://"
val SHADOW = "shadow:"
val SS = "ss"
}
object State {
@@ -4,14 +4,14 @@ import com.github.shadowsocks.database.Profile
import android.net.Uri
import android.util.{Log, Base64}
object ShadowParser {
object Parser {
val TAG = "ShadowParser"
def parse (data: String): Option[Profile] = {
try {
Log.d(TAG, data)
val uri = Uri.parse(data.trim)
if (uri.isOpaque && uri.getScheme == "shadow") {
val encoded = data.replace("shadow:", "")
if (uri.isOpaque && uri.getScheme == Scheme.SS) {
val encoded = data.replace(Scheme.SS + ":", "")
val content = new String(Base64.decode(encoded, Base64.NO_PADDING), "UTF-8")
val info = content.split('@')
val encinfo = info(0).split(':')