diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml index 14d82d9c..21d49d7c 100644 --- a/src/main/AndroidManifest.xml +++ b/src/main/AndroidManifest.xml @@ -1,85 +1,97 @@ + package="com.github.shadowsocks"> - - - - - - + + + + + + - + - + - + - + - + - - - - - - + + + + + + - - + + + + + + + + - - - - - - + + - + + + + + + - - - - - + - - - - - - + + + + + - + + + + + + + + diff --git a/src/main/res/values-v14/styles_shadow.xml b/src/main/res/values-v14/styles_shadow.xml index f74d65f8..8259ed25 100755 --- a/src/main/res/values-v14/styles_shadow.xml +++ b/src/main/res/values-v14/styles_shadow.xml @@ -19,6 +19,15 @@ + + + + + diff --git a/src/main/scala/com/github/shadowsocks/ParserActivity.scala b/src/main/scala/com/github/shadowsocks/ParserActivity.scala new file mode 100644 index 00000000..24e553e9 --- /dev/null +++ b/src/main/scala/com/github/shadowsocks/ParserActivity.scala @@ -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() + } + } + } + +} diff --git a/src/main/scala/com/github/shadowsocks/ShadowVpnActivity.scala b/src/main/scala/com/github/shadowsocks/ShadowVpnActivity.scala index 32c6ad44..25fc9944 100644 --- a/src/main/scala/com/github/shadowsocks/ShadowVpnActivity.scala +++ b/src/main/scala/com/github/shadowsocks/ShadowVpnActivity.scala @@ -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 { diff --git a/src/main/scala/com/github/shadowsocks/Shadowsocks.scala b/src/main/scala/com/github/shadowsocks/Shadowsocks.scala index b98678d2..f60cad78 100644 --- a/src/main/scala/com/github/shadowsocks/Shadowsocks.scala +++ b/src/main/scala/com/github/shadowsocks/Shadowsocks.scala @@ -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 } diff --git a/src/main/scala/com/github/shadowsocks/utils/Constants.scala b/src/main/scala/com/github/shadowsocks/utils/Constants.scala index 2e8bdc9d..66a7a201 100644 --- a/src/main/scala/com/github/shadowsocks/utils/Constants.scala +++ b/src/main/scala/com/github/shadowsocks/utils/Constants.scala @@ -30,7 +30,7 @@ object Key { object Scheme { val APP = "app://" val PROFILE = "profile://" - val SHADOW = "shadow:" + val SS = "ss" } object State { diff --git a/src/main/scala/com/github/shadowsocks/utils/ShadowParser.scala b/src/main/scala/com/github/shadowsocks/utils/Parser.scala similarity index 87% rename from src/main/scala/com/github/shadowsocks/utils/ShadowParser.scala rename to src/main/scala/com/github/shadowsocks/utils/Parser.scala index 338a9705..f4a9ed34 100644 --- a/src/main/scala/com/github/shadowsocks/utils/ShadowParser.scala +++ b/src/main/scala/com/github/shadowsocks/utils/Parser.scala @@ -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(':')