diff --git a/.gitignore b/.gitignore index db6dc17d..bae30917 100644 --- a/.gitignore +++ b/.gitignore @@ -29,3 +29,5 @@ src/main/assets/armeabi src/main/assets/armeabi-v7a src/main/assets/x86 src/main/jni +obj +libs diff --git a/.travis.yml b/.travis.yml index 41fc9e9e..0a3a68ce 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,10 +2,6 @@ language: scala scala: - 2.10.3 before_install: -- git clone https://github.com/madeye/android-plugin.git -- pushd android-plugin -- sbt publish-local -- popd - sudo apt-get update - sudo apt-get install libc6-dev-i386 - sudo apt-get install lib32ncurses5-dev @@ -15,8 +11,8 @@ before_install: - sudo apt-get install ccache - export NDK_CCACHE=ccache - export ARCH=`uname -m` -- wget http://dl.google.com/android/android-sdk_r22.6.4-linux.tgz -- tar xf android-sdk_r22.6.4-linux.tgz +- wget http://dl.google.com/android/android-sdk_r22.6.2-linux.tgz +- tar xf android-sdk_r22.6.2-linux.tgz - wget http://dl.google.com/android/ndk/android-ndk-r9d-linux-${ARCH}.tar.bz2 - tar xf android-ndk-r9d-linux-${ARCH}.tar.bz2 - export ANDROID_NDK_HOME=`pwd`/android-ndk-r9d @@ -28,11 +24,10 @@ install: - gem install travis-artifacts script: - ./build-ndk.sh -- cp local.sbt.example local.sbt -- sbt clean -- sbt apk +- cp local.properties.example local.properties +- sbt clean android:package-release after_success: -- sbt deploy +- ./deploy target/android-bin shadowsocks-release.apk env: global: - "ARTIFACTS_AWS_REGION=us-east-1" diff --git a/build-ndk.sh b/build-ndk.sh index 6421a79a..626c89c6 100755 --- a/build-ndk.sh +++ b/build-ndk.sh @@ -4,7 +4,7 @@ ndk-build mkdir -p assets/armeabi mkdir -p assets/armeabi-v7a mkdir -p assets/x86 -for app in iptables pdnsd redsocks ss-local ss-tunnel tun2socks +for app in ip6tables iptables pdnsd redsocks ss-local ss-tunnel tun2socks do mv libs/armeabi/$app src/main/assets/armeabi/ mv libs/armeabi-v7a/$app src/main/assets/armeabi-v7a/ diff --git a/local.properties.example b/local.properties.example new file mode 100644 index 00000000..771b6607 --- /dev/null +++ b/local.properties.example @@ -0,0 +1,3 @@ +key.alias: travis +key.store: travis.keystore +key.store.password=travis diff --git a/src/main/scala/com/github/shadowsocks/Shadowsocks.scala b/src/main/scala/com/github/shadowsocks/Shadowsocks.scala index 2f0c5cfc..d087bf4e 100644 --- a/src/main/scala/com/github/shadowsocks/Shadowsocks.scala +++ b/src/main/scala/com/github/shadowsocks/Shadowsocks.scala @@ -50,7 +50,6 @@ import android.widget._ import com.google.analytics.tracking.android.{MapBuilder, EasyTracker} import de.keyboardsurfer.android.widget.crouton.{Crouton, Style, Configuration} import java.util.Hashtable -import android.preference.PreferenceFragment import com.actionbarsherlock.app.SherlockPreferenceActivity import org.jraf.android.backport.switchwidget.Switch import android.content.pm.{PackageInfo, PackageManager} @@ -172,77 +171,6 @@ object Shadowsocks { case _ => } } - - class SettingsFragment extends PreferenceFragment { - - var receiver: BroadcastReceiver = null - - private def setPreferenceEnabled() { - val state = getActivity.asInstanceOf[Shadowsocks].state - val enabled = state != State.CONNECTED && state != State.CONNECTING - for (name <- PROXY_PREFS) { - val pref: Preference = findPreference(name) - if (pref != null) { - pref.setEnabled(enabled) - } - } - for (name <- Shadowsocks.FEATRUE_PREFS) { - val pref: Preference = findPreference(name) - if (pref != null) { - val status = getActivity.getSharedPreferences(Key.status, Context.MODE_PRIVATE) - val isRoot = status.getBoolean(Key.isRoot, false) - if (Seq(Key.isGlobalProxy, Key.isTrafficStat, Key.proxyedApps) - .contains(name)) { - pref.setEnabled(enabled && isRoot) - } else { - pref.setEnabled(enabled) - } - } - } - } - - private def updatePreferenceScreen() { - for (name <- Shadowsocks.PROXY_PREFS) { - val pref = findPreference(name) - Shadowsocks - .updatePreference(pref, name, getActivity.asInstanceOf[Shadowsocks].currentProfile) - } - for (name <- Shadowsocks.FEATRUE_PREFS) { - val pref = findPreference(name) - Shadowsocks - .updatePreference(pref, name, getActivity.asInstanceOf[Shadowsocks].currentProfile) - } - } - - override def onCreate(bundle: Bundle) { - super.onCreate(bundle) - addPreferencesFromResource(R.xml.pref_all) - val filter = new IntentFilter() - filter.addAction(Action.UPDATE_FRAGMENT) - receiver = new BroadcastReceiver { - def onReceive(p1: Context, p2: Intent) { - setPreferenceEnabled() - updatePreferenceScreen() - } - } - getActivity.getApplicationContext.registerReceiver(receiver, filter) - } - - override def onDestroy() { - super.onDestroy() - getActivity.getApplicationContext.unregisterReceiver(receiver) - } - - override def onResume() { - super.onResume() - setPreferenceEnabled() - } - - override def onPause() { - super.onPause() - } - } - } class Shadowsocks @@ -315,10 +243,6 @@ class Shadowsocks val handler = new Handler() - def isFallbackPref: Boolean = { - Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB - } - def isSinglePane: Boolean = { if (singlePane == -1) { val metrics = new DisplayMetrics() @@ -327,8 +251,7 @@ class Shadowsocks val scaleFactor = metrics.density val widthDp = widthPixels / scaleFactor - singlePane = if (widthDp <= 720) 1 - else 0 + singlePane = if (widthDp <= 720) 1 else 0 } singlePane == 1 } @@ -503,7 +426,11 @@ class Shadowsocks def initAdView() { if (settings.getString(Key.proxy, "") == "198.199.101.152") { val layoutView = { + if (Build.VERSION.SDK_INT > 10) { + drawer.getContentContainer.asInstanceOf[ViewGroup].getChildAt(0) + } else { getLayoutView(drawer.getContentContainer.getParent) + } } if (layoutView != null) { val adView = new AdView(this) @@ -525,15 +452,7 @@ class Shadowsocks super.onCreate(savedInstanceState) - if (isFallbackPref) { - // Load the legacy preferences headers - addPreferencesFromResource(R.xml.pref_all) - } else { - // Display the fragment as the main content. - getFragmentManager.beginTransaction() - .replace(android.R.id.content, new Shadowsocks.SettingsFragment()) - .commit() - } + addPreferencesFromResource(R.xml.pref_all) // Initialize the profile currentProfile = { @@ -678,11 +597,7 @@ class Shadowsocks profileManager.reload(currentProfile.id) menuAdapter.updateList(getMenuList, currentProfile.id) - if (!isFallbackPref) { - sendBroadcast(new Intent(Action.UPDATE_FRAGMENT)) - } else { - updatePreferenceScreen() - } + updatePreferenceScreen() h.sendEmptyMessage(0) } @@ -700,11 +615,7 @@ class Shadowsocks profileManager.save() menuAdapter.updateList(getMenuList, currentProfile.id) - if (!isFallbackPref) { - sendBroadcast(new Intent(Action.UPDATE_FRAGMENT)) - } else { - updatePreferenceScreen() - } + updatePreferenceScreen() h.sendEmptyMessage(0) } @@ -722,11 +633,7 @@ class Shadowsocks menuAdapter.setActiveId(id) menuAdapter.notifyDataSetChanged() - if (!isFallbackPref) { - sendBroadcast(new Intent(Action.UPDATE_FRAGMENT)) - } else { - updatePreferenceScreen() - } + updatePreferenceScreen() h.sendEmptyMessage(0) } @@ -756,11 +663,7 @@ class Shadowsocks currentProfile = profileManager.load(profileId) menuAdapter.updateList(getMenuList, currentProfile.id) - if (!isFallbackPref) { - sendBroadcast(new Intent(Action.UPDATE_FRAGMENT)) - } else { - updatePreferenceScreen() - } + sendBroadcast(new Intent(Action.UPDATE_FRAGMENT)) dialog.dismiss() } @@ -1080,7 +983,6 @@ class Shadowsocks } setPreferenceEnabled(enabled = true) } - if (!isFallbackPref) sendBroadcast(new Intent(Action.UPDATE_FRAGMENT)) } } }) diff --git a/src/main/scala/com/github/shadowsocks/preferences/PasswordEditTextPreference.scala b/src/main/scala/com/github/shadowsocks/preferences/PasswordEditTextPreference.scala index 4a8cd7da..c0e3a15b 100644 --- a/src/main/scala/com/github/shadowsocks/preferences/PasswordEditTextPreference.scala +++ b/src/main/scala/com/github/shadowsocks/preferences/PasswordEditTextPreference.scala @@ -51,6 +51,11 @@ class PasswordEditTextPreference(context: Context, attrs: AttributeSet, defStyle mDefaultSummary = getSummary } + override def setText(text: String) { + super.setText(text) + setSummary(text) + } + override def setSummary(summary: CharSequence) { if (summary.toString.isEmpty) { super.setSummary(mDefaultSummary) diff --git a/src/main/scala/com/github/shadowsocks/preferences/ProfileEditTextPreference.scala b/src/main/scala/com/github/shadowsocks/preferences/ProfileEditTextPreference.scala index 01d295e7..1ca8ecc3 100644 --- a/src/main/scala/com/github/shadowsocks/preferences/ProfileEditTextPreference.scala +++ b/src/main/scala/com/github/shadowsocks/preferences/ProfileEditTextPreference.scala @@ -52,6 +52,11 @@ class ProfileEditTextPreference(context: Context, attrs: AttributeSet, defStyle: mDefaultSummary = getSummary } + override def setText(text: String) { + super.setText(text) + setSummary(text) + } + override def setSummary(summary: CharSequence) { if (summary.toString.isEmpty) { super.setSummary(mDefaultSummary) diff --git a/src/main/scala/com/github/shadowsocks/preferences/SummaryEditTextPreference.scala b/src/main/scala/com/github/shadowsocks/preferences/SummaryEditTextPreference.scala index d6531714..fe6f8765 100644 --- a/src/main/scala/com/github/shadowsocks/preferences/SummaryEditTextPreference.scala +++ b/src/main/scala/com/github/shadowsocks/preferences/SummaryEditTextPreference.scala @@ -51,6 +51,11 @@ class SummaryEditTextPreference(context: Context, attrs: AttributeSet, defStyle: mDefaultSummary = getSummary } + override def setText(text: String) { + super.setText(text) + setSummary(text) + } + override def setSummary(summary: CharSequence) { if (summary.toString.isEmpty) { super.setSummary(mDefaultSummary) diff --git a/travis.keystore b/travis.keystore new file mode 100755 index 00000000..fb6d8520 Binary files /dev/null and b/travis.keystore differ