Commit a5df60ae authored by Mygod's avatar Mygod

Refine code style

parent c9b404fa
......@@ -37,7 +37,7 @@ class EditTextPreference(context: Context, attrs: AttributeSet = null) extends P
override def createDialog() = new EditTextPreferenceDialogFragment()
override protected def getSummaryValue = {
override protected def getSummaryValue: String = {
var text = getText
if (text == null) text = ""
val inputType = editText.getInputType
......@@ -47,8 +47,8 @@ class EditTextPreference(context: Context, attrs: AttributeSet = null) extends P
"\u2022" * text.length else text
}
override def setText(text: String) = {
override def setText(text: String): Unit = {
super.setText(text)
notifyChanged
notifyChanged()
}
}
......@@ -22,13 +22,14 @@ package be.mygod.preference
import android.content.Context
import android.support.v14.preference.PreferenceDialogFragment
import android.support.v7.widget.AppCompatEditText
import android.view.{View, ViewGroup}
class EditTextPreferenceDialogFragment extends PreferenceDialogFragment {
private lazy val preference = getPreference.asInstanceOf[EditTextPreference]
private lazy val editText = preference.editText
override protected def onCreateDialogView(context: Context) = {
override protected def onCreateDialogView(context: Context): AppCompatEditText = {
val parent = editText.getParent.asInstanceOf[ViewGroup]
if (parent != null) parent.removeView(editText)
editText
......@@ -43,7 +44,7 @@ class EditTextPreferenceDialogFragment extends PreferenceDialogFragment {
override protected def needInputMethod = true
def onDialogClosed(positiveResult: Boolean) = if (positiveResult) {
def onDialogClosed(positiveResult: Boolean): Unit = if (positiveResult) {
val value = editText.getText.toString
if (preference.callChangeListener(value)) preference.setText(value)
}
......
......@@ -37,23 +37,23 @@ class NumberPickerPreference(private val context: Context, attrs: AttributeSet =
val a: TypedArray = context.obtainStyledAttributes(attrs, R.styleable.NumberPickerPreference)
setMin(a.getInt(R.styleable.NumberPickerPreference_min, 0))
setMax(a.getInt(R.styleable.NumberPickerPreference_max, Int.MaxValue - 1))
a.recycle
a.recycle()
}
override def createDialog() = new NumberPickerPreferenceDialogFragment()
def getValue = value
def getMin = if (picker == null) 0 else picker.getMinValue
def getMax = picker.getMaxValue
def getValue: Int = value
def getMin: Int = if (picker == null) 0 else picker.getMinValue
def getMax: Int = picker.getMaxValue
def setValue(i: Int) {
if (i == value) return
picker.setValue(i)
value = picker.getValue
persistInt(value)
notifyChanged
notifyChanged()
}
def setMin(value: Int) = picker.setMinValue(value)
def setMax(value: Int) = picker.setMaxValue(value)
def setMin(value: Int): Unit = picker.setMinValue(value)
def setMax(value: Int): Unit = picker.setMaxValue(value)
override protected def onGetDefaultValue(a: TypedArray, index: Int): AnyRef =
a.getInt(index, getMin).asInstanceOf[AnyRef]
......
......@@ -23,12 +23,13 @@ package be.mygod.preference
import android.content.Context
import android.support.v14.preference.PreferenceDialogFragment
import android.view.{View, ViewGroup}
import android.widget.NumberPicker
class NumberPickerPreferenceDialogFragment extends PreferenceDialogFragment {
private lazy val preference = getPreference.asInstanceOf[NumberPickerPreference]
private lazy val picker = preference.picker
override protected def onCreateDialogView(context: Context) = {
override protected def onCreateDialogView(context: Context): NumberPicker = {
val parent = picker.getParent.asInstanceOf[ViewGroup]
if (parent != null) parent.removeView(picker)
picker
......@@ -42,7 +43,7 @@ class NumberPickerPreferenceDialogFragment extends PreferenceDialogFragment {
override protected def needInputMethod = true
def onDialogClosed(positiveResult: Boolean) {
picker.clearFocus // commit changes
picker.clearFocus() // commit changes
if (positiveResult) {
val value = picker.getValue
if (preference.callChangeListener(value)) preference.setValue(value)
......
......@@ -24,10 +24,10 @@ import android.app.DialogFragment
import android.os.Bundle
import android.support.v14.preference.{PreferenceFragment => Base}
import android.support.v7.preference.{Preference, PreferenceScreen}
import android.view.{LayoutInflater, ViewGroup}
import android.view.{LayoutInflater, View, ViewGroup}
abstract class PreferenceFragment extends Base {
override def onCreateView(inflater: LayoutInflater, container: ViewGroup, savedInstanceState: Bundle) =
override def onCreateView(inflater: LayoutInflater, container: ViewGroup, savedInstanceState: Bundle): View =
super.onCreateView(inflater, container, savedInstanceState)
protected final def displayPreferenceDialog(key: String, fragment: DialogFragment) {
......@@ -40,15 +40,15 @@ abstract class PreferenceFragment extends Base {
.commitAllowingStateLoss()
}
override def onDisplayPreferenceDialog(preference: Preference) = preference match {
override def onDisplayPreferenceDialog(preference: Preference): Unit = preference match {
case dpp: DialogPreferencePlus => displayPreferenceDialog(preference.getKey, dpp.createDialog())
case _ => super.onDisplayPreferenceDialog(preference)
}
override protected def onCreateAdapter(screen: PreferenceScreen) = new PreferenceGroupAdapter(screen)
override def onResume {
super.onResume
override def onResume() {
super.onResume()
getListView.scrollBy(0, 0)
}
}
......@@ -21,7 +21,7 @@
package be.mygod.preference
import java.lang.reflect.Field
import java.util.List
import java.util
import android.os.Build
import android.support.v4.content.ContextCompat
......@@ -57,29 +57,31 @@ object PreferenceGroupAdapter {
class PreferenceGroupAdapter(group: PreferenceGroup) extends Old(group) {
import PreferenceGroupAdapter._
protected lazy val preferenceLayouts = preferenceLayoutsField.get(this).asInstanceOf[List[AnyRef]]
protected lazy val preferenceLayouts: util.List[AnyRef] =
preferenceLayoutsField.get(this).asInstanceOf[util.List[AnyRef]]
override def onCreateViewHolder(parent: ViewGroup, viewType: Int) = if (Build.VERSION.SDK_INT < 21) {
val context = parent.getContext
val inflater = LayoutInflater.from(context)
val pl = preferenceLayouts.get(viewType)
val view = inflater.inflate(fieldResId.get(pl).asInstanceOf[Int], parent, false)
if (view.getBackground == null) {
val array = context.obtainStyledAttributes(null, R.styleable.BackgroundStyle)
var background = array.getDrawable(R.styleable.BackgroundStyle_android_selectableItemBackground)
if (background == null)
background = ContextCompat.getDrawable(context, android.R.drawable.list_selector_background)
array.recycle
val (s, t, e, b) = (ViewCompat.getPaddingStart(view), view.getPaddingTop,
ViewCompat.getPaddingEnd(view), view.getPaddingBottom)
view.setBackground(background)
ViewCompat.setPaddingRelative(view, s, t, e, b)
}
val widgetFrame = view.findViewById(android.R.id.widget_frame).asInstanceOf[ViewGroup]
if (widgetFrame != null) {
val widgetResId = fieldWidgetResId.get(pl).asInstanceOf[Int]
if (widgetResId != 0) inflater.inflate(widgetResId, widgetFrame) else widgetFrame.setVisibility(View.GONE)
}
preferenceViewHolderConstructor.newInstance(view)
} else super.onCreateViewHolder(parent, viewType)
override def onCreateViewHolder(parent: ViewGroup, viewType: Int): PreferenceViewHolder =
if (Build.VERSION.SDK_INT < 21) {
val context = parent.getContext
val inflater = LayoutInflater.from(context)
val pl = preferenceLayouts.get(viewType)
val view = inflater.inflate(fieldResId.get(pl).asInstanceOf[Int], parent, false)
if (view.getBackground == null) {
val array = context.obtainStyledAttributes(null, R.styleable.BackgroundStyle)
var background = array.getDrawable(R.styleable.BackgroundStyle_android_selectableItemBackground)
if (background == null)
background = ContextCompat.getDrawable(context, android.R.drawable.list_selector_background)
array.recycle()
val (s, t, e, b) = (ViewCompat.getPaddingStart(view), view.getPaddingTop,
ViewCompat.getPaddingEnd(view), view.getPaddingBottom)
view.setBackground(background)
ViewCompat.setPaddingRelative(view, s, t, e, b)
}
val widgetFrame = view.findViewById(android.R.id.widget_frame).asInstanceOf[ViewGroup]
if (widgetFrame != null) {
val widgetResId = fieldWidgetResId.get(pl).asInstanceOf[Int]
if (widgetResId != 0) inflater.inflate(widgetResId, widgetFrame) else widgetFrame.setVisibility(View.GONE)
}
preferenceViewHolderConstructor.newInstance(view)
} else super.onCreateViewHolder(parent, viewType)
}
......@@ -38,7 +38,7 @@ trait SummaryPreference extends Preference {
*
* @return the summary with appropriate string substitution
*/
override def getSummary = {
override def getSummary: String = {
val summary = super.getSummary
if (summary == null) null else String.format(summary.toString, getSummaryValue)
}
......
......@@ -53,7 +53,7 @@ object AppManager {
val filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED)
filter.addAction(Intent.ACTION_PACKAGE_REMOVED)
filter.addDataScheme("package")
app.registerReceiver((context: Context, intent: Intent) =>
app.registerReceiver((_: Context, intent: Intent) =>
if (intent.getAction != Intent.ACTION_PACKAGE_REMOVED ||
!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
synchronized(cachedApps = null)
......@@ -111,8 +111,8 @@ class AppManager extends AppCompatActivity with OnMenuItemClickListener {
if (aProxied ^ proxiedApps.contains(b.packageName)) aProxied else a.name.compareToIgnoreCase(b.name) < 0
})
def getItemCount = apps.length
def onBindViewHolder(vh: AppViewHolder, i: Int) = vh.bind(apps(i))
def getItemCount: Int = apps.length
def onBindViewHolder(vh: AppViewHolder, i: Int): Unit = vh.bind(apps(i))
def onCreateViewHolder(vg: ViewGroup, i: Int) =
new AppViewHolder(LayoutInflater.from(vg.getContext).inflate(R.layout.layout_apps_item, vg, false))
}
......@@ -148,8 +148,8 @@ class AppManager extends AppCompatActivity with OnMenuItemClickListener {
p.individual = proxiedAppString
app.profileManager.updateProfile(p)
})
Toast.makeText(this, R.string.action_apply_all, Toast.LENGTH_SHORT).show
case _ => Toast.makeText(this, R.string.action_export_err, Toast.LENGTH_SHORT).show
Toast.makeText(this, R.string.action_apply_all, Toast.LENGTH_SHORT).show()
case _ => Toast.makeText(this, R.string.action_export_err, Toast.LENGTH_SHORT).show()
}
return true
case R.id.action_export =>
......@@ -180,7 +180,7 @@ class AppManager extends AppCompatActivity with OnMenuItemClickListener {
return true
} catch {
case _: IllegalArgumentException =>
Toast.makeText(this, R.string.action_import_err, Toast.LENGTH_SHORT).show
Toast.makeText(this, R.string.action_import_err, Toast.LENGTH_SHORT).show()
}
}
}
......@@ -239,7 +239,7 @@ class AppManager extends AppCompatActivity with OnMenuItemClickListener {
loadAppsAsync()
}
def reloadApps() = if (!appsLoading.compareAndSet(true, false)) loadAppsAsync()
def reloadApps(): Unit = if (!appsLoading.compareAndSet(true, false)) loadAppsAsync()
def loadAppsAsync() {
if (!appsLoading.compareAndSet(false, true)) return
Utils.ThrowableFuture {
......@@ -255,7 +255,7 @@ class AppManager extends AppCompatActivity with OnMenuItemClickListener {
}
}
override def onKeyUp(keyCode: Int, event: KeyEvent) = keyCode match {
override def onKeyUp(keyCode: Int, event: KeyEvent): Boolean = keyCode match {
case KeyEvent.KEYCODE_MENU =>
if (toolbar.isOverflowMenuShowing) toolbar.hideOverflowMenu else toolbar.showOverflowMenu
case _ => super.onKeyUp(keyCode, event)
......
......@@ -52,19 +52,19 @@ trait BaseService extends Service {
var callbacksCount: Int = _
lazy val handler = new Handler(getMainLooper)
lazy val restartHanlder = new Handler(getMainLooper)
lazy val protectPath = getApplicationInfo.dataDir + "/protect_path"
lazy val protectPath: String = getApplicationInfo.dataDir + "/protect_path"
private val closeReceiver: BroadcastReceiver = (context: Context, intent: Intent) => {
private val closeReceiver: BroadcastReceiver = (context: Context, _: Intent) => {
Toast.makeText(context, R.string.stopping, Toast.LENGTH_SHORT).show()
stopRunner(true)
stopRunner(stopService = true)
}
var closeReceiverRegistered: Boolean = _
var kcptunProcess: GuardedProcess = _
private val networkReceiver: BroadcastReceiver = (context: Context, intent: Intent) => {
private val networkReceiver: BroadcastReceiver = (context: Context, _: Intent) => {
val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE).asInstanceOf[ConnectivityManager]
val activeNetwork = cm.getActiveNetworkInfo()
val isConnected = activeNetwork != null && activeNetwork.isConnected()
val activeNetwork = cm.getActiveNetworkInfo
val isConnected = activeNetwork != null && activeNetwork.isConnected
if (isConnected && profile.kcp && kcptunProcess != null) {
restartHanlder.removeCallbacks(null)
......@@ -95,7 +95,7 @@ trait BaseService extends Service {
callbacksCount += 1
if (callbacksCount != 0 && timer == null) {
val task = new TimerTask {
def run {
def run() {
if (TrafficMonitor.updateRate()) updateTrafficRate()
}
}
......@@ -107,27 +107,27 @@ trait BaseService extends Service {
}
}
override def use(profileId: Int) = synchronized(if (profileId < 0) stopRunner(true) else {
override def use(profileId: Int): Unit = synchronized(if (profileId < 0) stopRunner(stopService = true) else {
val profile = app.profileManager.getProfile(profileId).orNull
if (profile == null) stopRunner(true) else state match {
if (profile == null) stopRunner(stopService = true) else state match {
case State.STOPPED => if (checkProfile(profile)) startRunner(profile)
case State.CONNECTED => if (profileId != BaseService.this.profile.id && checkProfile(profile)) {
stopRunner(false)
stopRunner(stopService = false)
startRunner(profile)
}
case _ => Log.w(BaseService.this.getClass.getSimpleName, "Illegal state when invoking use: " + state)
}
})
override def useSync(profileId: Int) = use(profileId)
override def useSync(profileId: Int): Unit = use(profileId)
}
def checkProfile(profile: Profile) = if (TextUtils.isEmpty(profile.host) || TextUtils.isEmpty(profile.password)) {
stopRunner(true, getString(R.string.proxy_empty))
def checkProfile(profile: Profile): Boolean = if (TextUtils.isEmpty(profile.host) || TextUtils.isEmpty(profile.password)) {
stopRunner(stopService = true, getString(R.string.proxy_empty))
false
} else true
def connect() = if (profile.host == "198.199.101.152") {
def connect(): Unit = if (profile.host == "198.199.101.152") {
val holder = app.containerHolder
val container = holder.getContainer
val url = container.getString("proxy_url")
......@@ -175,15 +175,16 @@ trait BaseService extends Service {
changeState(State.CONNECTING)
if (profile.isMethodUnsafe) handler.post(() => Toast.makeText(this, R.string.method_unsafe, Toast.LENGTH_LONG).show)
if (profile.isMethodUnsafe)
handler.post(() => Toast.makeText(this, R.string.method_unsafe, Toast.LENGTH_LONG).show())
Utils.ThrowableFuture(try connect catch {
case _: NameNotResolvedException => stopRunner(true, getString(R.string.invalid_server))
Utils.ThrowableFuture(try connect() catch {
case _: NameNotResolvedException => stopRunner(stopService = true, getString(R.string.invalid_server))
case exc: KcpcliParseException =>
stopRunner(true, getString(R.string.service_failed) + ": " + exc.cause.getMessage)
case _: NullConnectionException => stopRunner(true, getString(R.string.reboot_required))
stopRunner(stopService = true, getString(R.string.service_failed) + ": " + exc.cause.getMessage)
case _: NullConnectionException => stopRunner(stopService = true, getString(R.string.reboot_required))
case exc: Throwable =>
stopRunner(true, getString(R.string.service_failed) + ": " + exc.getMessage)
stopRunner(stopService = true, getString(R.string.service_failed) + ": " + exc.getMessage)
exc.printStackTrace()
app.track(exc)
})
......@@ -283,7 +284,7 @@ trait BaseService extends Service {
})
}
def getBlackList = {
def getBlackList: String = {
val default = getString(R.string.black_list)
try {
val container = app.containerHolder.getContainer
......@@ -291,7 +292,7 @@ trait BaseService extends Service {
val list = if (update == null || update.isEmpty) default else update
"exclude = " + list + ";"
} catch {
case ex: Exception => "exclude = " + default + ";"
case _: Exception => "exclude = " + default + ";"
}
}
}
......@@ -25,16 +25,16 @@ import android.content.{BroadcastReceiver, ComponentName, Context, Intent}
import com.github.shadowsocks.utils._
object BootReceiver {
def getEnabled(context: Context) = PackageManager.COMPONENT_ENABLED_STATE_ENABLED ==
def getEnabled(context: Context): Boolean = PackageManager.COMPONENT_ENABLED_STATE_ENABLED ==
context.getPackageManager.getComponentEnabledSetting(new ComponentName(context, classOf[BootReceiver]))
def setEnabled(context: Context, enabled: Boolean) = context.getPackageManager.setComponentEnabledSetting(
def setEnabled(context: Context, enabled: Boolean): Unit = context.getPackageManager.setComponentEnabledSetting(
new ComponentName(context, classOf[BootReceiver]),
if (enabled) PackageManager.COMPONENT_ENABLED_STATE_ENABLED else PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP)
}
class BootReceiver extends BroadcastReceiver {
def onReceive(context: Context, intent: Intent) = {
def onReceive(context: Context, intent: Intent): Unit = {
Utils.startSsService(context)
}
}
......@@ -25,24 +25,16 @@ import java.lang.System.currentTimeMillis
import java.util.concurrent.Semaphore
import android.util.Log
import com.github.shadowsocks.utils.CloseUtils._
import scala.collection.JavaConversions._
import scala.collection.immutable.Stream
import scala.util.control.Exception._
class StreamLogger(is: InputStream, tag: String) extends Thread {
def withCloseable[T <: Closeable, R](t: T)(f: T => R): R = {
allCatch.andFinally{t.close} apply { f(t) }
}
override def run() {
withCloseable(new BufferedReader(new InputStreamReader(is))) {
br => try Stream.continually(br.readLine()).takeWhile(_ != null).foreach(Log.i(tag, _)) catch {
case ignore: IOException =>
}
}
}
override def run(): Unit = autoClose(new BufferedReader(new InputStreamReader(is)))(br =>
try Stream.continually(br.readLine()).takeWhile(_ != null).foreach(Log.i(tag, _)) catch {
case _: IOException =>
})
}
/**
......@@ -58,7 +50,7 @@ class GuardedProcess(cmd: Seq[String]) {
def start(onRestartCallback: () => Unit = null): GuardedProcess = {
val semaphore = new Semaphore(1)
semaphore.acquire
semaphore.acquire()
@volatile var ioException: IOException = null
guardThread = new Thread(() => {
......@@ -71,11 +63,11 @@ class GuardedProcess(cmd: Seq[String]) {
process = new ProcessBuilder(cmd).redirectErrorStream(true).start
val is = process.getInputStream
new StreamLogger(is, TAG).start
new StreamLogger(is, TAG).start()
if (callback == null) callback = onRestartCallback else callback()
semaphore.release
semaphore.release()
process.waitFor
this.synchronized {
......@@ -88,22 +80,19 @@ class GuardedProcess(cmd: Seq[String]) {
}
}
}
}
} catch {
case ignored: InterruptedException =>
case _: InterruptedException =>
Log.i(TAG, "thread interrupt, destroy process: " + cmd)
process.destroy()
case e: IOException => ioException = e
} finally semaphore.release
} finally semaphore.release()
}, "GuardThread-" + cmd)
guardThread.start()
semaphore.acquire
semaphore.acquire()
if (ioException != null) {
throw ioException
}
if (ioException != null) throw ioException
this
}
......@@ -113,7 +102,7 @@ class GuardedProcess(cmd: Seq[String]) {
guardThread.interrupt()
process.destroy()
try guardThread.join() catch {
case ignored: InterruptedException =>
case _: InterruptedException =>
}
}
......@@ -125,7 +114,7 @@ class GuardedProcess(cmd: Seq[String]) {
}
@throws(classOf[InterruptedException])
def waitFor = {
def waitFor: Int = {
guardThread.join()
0
}
......
......@@ -22,7 +22,7 @@ package com.github.shadowsocks
import java.nio.charset.Charset
import android.app.{Activity, TaskStackBuilder}
import android.app.TaskStackBuilder
import android.content._
import android.content.pm.PackageManager
import android.nfc.NfcAdapter.CreateNdefMessageCallback
......@@ -97,7 +97,7 @@ final class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClic
})
shareBtn.setOnLongClickListener(_ => {
Utils.positionToast(Toast.makeText(ProfileManagerActivity.this, R.string.share, Toast.LENGTH_SHORT), shareBtn,
getWindow, 0, Utils.dpToPx(ProfileManagerActivity.this, 8)).show
getWindow, 0, Utils.dpToPx(ProfileManagerActivity.this, 8)).show()
true
})
}
......@@ -131,41 +131,42 @@ final class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClic
def onClick(v: View) {
app.switchProfile(item.id)
finish
finish()
}
def onKey(v: View, keyCode: Int, event: KeyEvent) = if (event.getAction == KeyEvent.ACTION_DOWN) keyCode match {
case KeyEvent.KEYCODE_DPAD_LEFT =>
val index = getAdapterPosition
if (index >= 0) {
profilesAdapter.remove(index)
undoManager.remove(index, item)
true
} else false
case _ => false
} else false
def onKey(v: View, keyCode: Int, event: KeyEvent): Boolean =
if (event.getAction == KeyEvent.ACTION_DOWN) keyCode match {
case KeyEvent.KEYCODE_DPAD_LEFT =>
val index = getAdapterPosition
if (index >= 0) {
profilesAdapter.remove(index)
undoManager.remove(index, item)
true
} else false
case _ => false
} else false
}
private class ProfilesAdapter extends RecyclerView.Adapter[ProfileViewHolder] {
var profiles = new ArrayBuffer[Profile]
profiles ++= app.profileManager.getAllProfiles.getOrElse(List.empty[Profile])
def getItemCount = profiles.length
def getItemCount: Int = profiles.length
def onBindViewHolder(vh: ProfileViewHolder, i: Int) = vh.bind(profiles(i))
def onBindViewHolder(vh: ProfileViewHolder, i: Int): Unit = vh.bind(profiles(i))
def onCreateViewHolder(vg: ViewGroup, i: Int) =
new ProfileViewHolder(LayoutInflater.from(vg.getContext).inflate(R.layout.layout_profiles_item, vg, false))
def add(item: Profile) {
undoManager.flush
undoManager.flush()
val pos = getItemCount
profiles += item
notifyItemInserted(pos)
}
def move(from: Int, to: Int) {
undoManager.flush
undoManager.flush()
val step = if (from < to) 1 else -1
val first = profiles(from)
var previousOrder = profiles(from).userOrder
......@@ -187,11 +188,11 @@ final class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClic
profiles.remove(pos)
notifyItemRemoved(pos)
}
def undo(actions: Iterator[(Int, Profile)]) = for ((index, item) <- actions) {
def undo(actions: Iterator[(Int, Profile)]): Unit = for ((index, item) <- actions) {
profiles.insert(index, item)
notifyItemInserted(index)
}
def commit(actions: Iterator[(Int, Profile)]) = for ((index, item) <- actions) {
def commit(actions: Iterator[(Int, Profile)]): Unit = for ((_, item) <- actions) {
app.profileManager.delProfile(item.id)
if (item.id == app.profileId) app.profileId(-1)
}
......@@ -214,8 +215,6 @@ final class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClic
private var isNfcEnabled: Boolean = _
private var isNfcBeamEnabled: Boolean = _
private val REQUEST_QRCODE = 1
override def onCreate(savedInstanceState: Bundle) {
super.onCreate(savedInstanceState)
setContentView(R.layout.layout_profiles)
......@@ -246,27 +245,27 @@ final class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClic
undoManager = new UndoSnackbarManager[Profile](profilesList, profilesAdapter.undo, profilesAdapter.commit)
new ItemTouchHelper(new SimpleCallback(ItemTouchHelper.UP | ItemTouchHelper.DOWN,
ItemTouchHelper.START | ItemTouchHelper.END) {
def onSwiped(viewHolder: ViewHolder, direction: Int) = {
def onSwiped(viewHolder: ViewHolder, direction: Int) {
val index = viewHolder.getAdapterPosition
profilesAdapter.remove(index)
undoManager.remove(index, viewHolder.asInstanceOf[ProfileViewHolder].item)
}
def onMove(recyclerView: RecyclerView, viewHolder: ViewHolder, target: ViewHolder) = {
def onMove(recyclerView: RecyclerView, viewHolder: ViewHolder, target: ViewHolder): Boolean = {
profilesAdapter.move(viewHolder.getAdapterPosition, target.getAdapterPosition)
true
}
}).attachToRecyclerView(profilesList)
attachService(new IShadowsocksServiceCallback.Stub {
def stateChanged(state: Int, profileName: String, msg: String) = () // ignore
def trafficUpdated(txRate: Long, rxRate: Long, txTotal: Long, rxTotal: Long) =
def stateChanged(state: Int, profileName: String, msg: String): Unit = () // ignore
def trafficUpdated(txRate: Long, rxRate: Long, txTotal: Long, rxTotal: Long): Unit =
if (selectedItem != null) selectedItem.updateText(txTotal, rxTotal)
})
if (app.settings.getBoolean(Key.profileTip, true)) {
app.editor.putBoolean(Key.profileTip, false).apply
app.editor.putBoolean(Key.profileTip, false).apply()
new AlertDialog.Builder(this).setTitle(R.string.profile_manager_dialog)
.setMessage(R.string.profile_manager_dialog_content).setPositiveButton(R.string.gotcha, null).create.show
.setMessage(R.string.profile_manager_dialog_content).setPositiveButton(R.string.gotcha, null).create().show()
}
val intent = getIntent
......@@ -311,7 +310,7 @@ final class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClic
val profile = app.profileManager.createProfile()
app.profileManager.updateProfile(profile)
app.switchProfile(profile.id)
finish
finish()
case R.id.fab_qrcode_add =>
menu.toggle(false)
val intent = new Intent(this, classOf[ScannerActivity])
......@@ -331,18 +330,18 @@ final class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClic
} else {
dialog.setMessage(getString(R.string.add_profile_nfc_hint))
}
dialog.show
dialog.show()
case R.id.fab_import_add =>
menu.toggle(true)
if (clipboard.hasPrimaryClip) {
val profiles = Parser.findAll(clipboard.getPrimaryClip.getItemAt(0).getText)
if (profiles.nonEmpty) {
profiles.foreach(app.profileManager.createProfile)
Toast.makeText(this, R.string.action_import_msg, Toast.LENGTH_SHORT).show
Toast.makeText(this, R.string.action_import_msg, Toast.LENGTH_SHORT).show()
return
}
}
Toast.makeText(this, R.string.action_import_err, Toast.LENGTH_SHORT).show
Toast.makeText(this, R.string.action_import_err, Toast.LENGTH_SHORT).show()
}
}
......@@ -398,11 +397,11 @@ final class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClic
unregisterCallback
}
override def onDestroy {
override def onDestroy() {
detachService()
undoManager.flush
undoManager.flush()
app.profileManager.setProfileAddedListener(null)
super.onDestroy
super.onDestroy()
}
override def onBackPressed() {
......@@ -417,8 +416,8 @@ final class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClic
app.profileManager.getAllProfiles match {
case Some(profiles) =>
clipboard.setPrimaryClip(ClipData.newPlainText(null, profiles.mkString("\n")))
Toast.makeText(this, R.string.action_export_msg, Toast.LENGTH_SHORT).show
case _ => Toast.makeText(this, R.string.action_export_err, Toast.LENGTH_SHORT).show
Toast.makeText(this, R.string.action_export_msg, Toast.LENGTH_SHORT).show()
case _ => Toast.makeText(this, R.string.action_export_err, Toast.LENGTH_SHORT).show()
}
true
case _ => false
......
......@@ -20,8 +20,7 @@
package com.github.shadowsocks
import android.app.{Activity, TaskStackBuilder}
import android.content.Intent
import android.app.TaskStackBuilder
import android.content.pm.{PackageManager, ShortcutManager}
import android.os.{Build, Bundle}
import android.support.v4.app.ActivityCompat
......@@ -30,9 +29,9 @@ import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.Toolbar
import android.text.TextUtils
import android.widget.Toast
import com.google.zxing.Result
import com.github.shadowsocks.ShadowsocksApplication.app
import com.github.shadowsocks.utils.Parser
import com.google.zxing.Result
import me.dm7.barcodescanner.zxing.ZXingScannerView
object ScannerActivity {
......@@ -95,7 +94,7 @@ class ScannerActivity extends AppCompatActivity with ZXingScannerView.ResultHand
scannerView.stopCamera() // Stop camera on pause
}
override def handleResult(rawResult: Result) = {
override def handleResult(rawResult: Result) {
val uri = rawResult.getText
if (!TextUtils.isEmpty(uri))
Parser.findAll(uri).foreach(app.profileManager.createProfile)
......
......@@ -35,34 +35,34 @@ trait ServiceBoundContext extends Context with IBinder.DeathRecipient {
binder = service
service.linkToDeath(ServiceBoundContext.this, 0)
bgService = IShadowsocksService.Stub.asInterface(service)
registerCallback
registerCallback()
ServiceBoundContext.this.onServiceConnected()
}
override def onServiceDisconnected(name: ComponentName) {
unregisterCallback
unregisterCallback()
ServiceBoundContext.this.onServiceDisconnected()
bgService = null
binder = null
}
}
protected def registerCallback = if (bgService != null && callback != null && !callbackRegistered) try {
protected def registerCallback(): Unit = if (bgService != null && callback != null && !callbackRegistered) try {
bgService.registerCallback(callback)
callbackRegistered = true
} catch {
case ignored: RemoteException => // Nothing
case _: RemoteException => // Nothing
}
protected def unregisterCallback = {
protected def unregisterCallback() {
if (bgService != null && callback != null && callbackRegistered) try bgService.unregisterCallback(callback) catch {
case ignored: RemoteException =>
case _: RemoteException =>
}
callbackRegistered = false
}
def onServiceConnected() = ()
def onServiceDisconnected() = ()
override def binderDied = ()
def onServiceConnected(): Unit = ()
def onServiceDisconnected(): Unit = ()
override def binderDied(): Unit = ()
private var callback: IShadowsocksServiceCallback.Stub = _
private var connection: ShadowsocksServiceConnection = _
......@@ -86,7 +86,7 @@ trait ServiceBoundContext extends Context with IBinder.DeathRecipient {
}
def detachService() {
unregisterCallback
unregisterCallback()
callback = null
if (connection != null) {
try unbindService(connection) catch {
......
......@@ -123,7 +123,7 @@ class Shadowsocks extends AppCompatActivity with ServiceBoundContext {
getString(R.string.vpn_error).formatLocal(Locale.ENGLISH, m), Snackbar.LENGTH_LONG)
if (m == getString(R.string.nat_no_root)) snackbar.setAction(R.string.switch_to_vpn,
(_ => preferences.natSwitch.setChecked(false)): View.OnClickListener)
snackbar.show
snackbar.show()
Log.e(TAG, "Error to start VPN service: " + m)
}
preferences.setEnabled(true)
......@@ -151,7 +151,7 @@ class Shadowsocks extends AppCompatActivity with ServiceBoundContext {
rxRateText.setText(TrafficMonitor.formatTraffic(rxRate) + "/s")
}
def attachService: Unit = attachService(callback)
def attachServiceCallback(): Unit = attachService(callback)
override def onServiceConnected() {
// Update the UI
......@@ -160,7 +160,7 @@ class Shadowsocks extends AppCompatActivity with ServiceBoundContext {
if (Build.VERSION.SDK_INT >= 21 && app.isNatEnabled) {
val snackbar = Snackbar.make(findViewById(android.R.id.content), R.string.nat_deprecated, Snackbar.LENGTH_LONG)
snackbar.setAction(R.string.switch_to_vpn, (_ => preferences.natSwitch.setChecked(false)): View.OnClickListener)
snackbar.show
snackbar.show()
}
}
......@@ -168,10 +168,10 @@ class Shadowsocks extends AppCompatActivity with ServiceBoundContext {
if (fab != null) fab.setEnabled(false)
}
override def binderDied {
override def binderDied() {
detachService()
app.crashRecovery()
attachService
attachServiceCallback()
}
private var testCount: Int = _
......@@ -243,7 +243,7 @@ class Shadowsocks extends AppCompatActivity with ServiceBoundContext {
title.setOnClickListener(_ => startActivity(new Intent(this, classOf[ProfileManagerActivity])))
val typedArray = obtainStyledAttributes(Array(R.attr.selectableItemBackgroundBorderless))
title.setBackgroundResource(typedArray.getResourceId(0, 0))
typedArray.recycle
typedArray.recycle()
val tf = Typefaces.get(this, "fonts/Iceland.ttf")
if (tf != null) title.setTypeface(tf)
title.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_arrow_drop_down, 0)
......@@ -287,7 +287,7 @@ class Shadowsocks extends AppCompatActivity with ServiceBoundContext {
synchronized(if (testCount == id && app.isVpnEnabled) handler.post(() =>
if (success) connectionTestText.setText(result) else {
connectionTestText.setText(R.string.connection_test_fail)
Snackbar.make(findViewById(android.R.id.content), result, Snackbar.LENGTH_LONG).show
Snackbar.make(findViewById(android.R.id.content), result, Snackbar.LENGTH_LONG).show()
}))
}
}
......@@ -301,12 +301,12 @@ class Shadowsocks extends AppCompatActivity with ServiceBoundContext {
else changeSwitch(checked = false))
fab.setOnLongClickListener((v: View) => {
Utils.positionToast(Toast.makeText(this, if (serviceStarted) R.string.stop else R.string.connect,
Toast.LENGTH_SHORT), fab, getWindow, 0, Utils.dpToPx(this, 8)).show
Toast.LENGTH_SHORT), fab, getWindow, 0, Utils.dpToPx(this, 8)).show()
true
})
updateTraffic(0, 0, 0, 0)
handler.post(() => attachService)
handler.post(attachServiceCallback)
}
private def hideCircle() {
......@@ -412,11 +412,11 @@ class Shadowsocks extends AppCompatActivity with ServiceBoundContext {
override def onStart() {
super.onStart()
registerCallback
registerCallback()
}
override def onStop() {
super.onStop()
unregisterCallback
unregisterCallback()
clearDialog()
}
......@@ -436,7 +436,7 @@ class Shadowsocks extends AppCompatActivity with ServiceBoundContext {
}
}
override def onActivityResult(requestCode: Int, resultCode: Int, data: Intent) = resultCode match {
override def onActivityResult(requestCode: Int, resultCode: Int, data: Intent): Unit = resultCode match {
case Activity.RESULT_OK =>
serviceLoad()
case _ =>
......
......@@ -27,17 +27,18 @@ import java.util.concurrent.TimeUnit
import android.annotation.SuppressLint
import android.app.Application
import android.content.SharedPreferences
import android.content.res.Configuration
import android.os.{Build, LocaleList}
import android.preference.PreferenceManager
import android.support.v7.app.AppCompatDelegate
import android.util.Log
import com.evernote.android.job.JobManager
import com.github.shadowsocks.database.{DBHelper, ProfileManager}
import com.github.shadowsocks.database.{DBHelper, Profile, ProfileManager}
import com.github.shadowsocks.job.DonaldTrump
import com.github.shadowsocks.utils.CloseUtils._
import com.github.shadowsocks.utils._
import com.google.android.gms.analytics.{GoogleAnalytics, HitBuilders, StandardExceptionParser}
import com.google.android.gms.analytics.{GoogleAnalytics, HitBuilders, StandardExceptionParser, Tracker}
import com.google.android.gms.common.api.ResultCallback
import com.google.android.gms.tagmanager.{ContainerHolder, TagManager}
import com.j256.ormlite.logger.LocalLog
......@@ -64,29 +65,29 @@ class ShadowsocksApplication extends Application {
final val SIG_FUNC = "getSignature"
var containerHolder: ContainerHolder = _
lazy val tracker = GoogleAnalytics.getInstance(this).newTracker(R.xml.tracker)
lazy val settings = PreferenceManager.getDefaultSharedPreferences(this)
lazy val editor = settings.edit
lazy val tracker: Tracker = GoogleAnalytics.getInstance(this).newTracker(R.xml.tracker)
lazy val settings: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
lazy val editor: SharedPreferences.Editor = settings.edit
lazy val profileManager = new ProfileManager(new DBHelper(this))
def isNatEnabled = settings.getBoolean(Key.isNAT, false)
def isVpnEnabled = !isNatEnabled
def isNatEnabled: Boolean = settings.getBoolean(Key.isNAT, false)
def isVpnEnabled: Boolean = !isNatEnabled
// send event
def track(category: String, action: String) = tracker.send(new HitBuilders.EventBuilder()
def track(category: String, action: String): Unit = tracker.send(new HitBuilders.EventBuilder()
.setAction(action)
.setLabel(BuildConfig.VERSION_NAME)
.build())
def track(t: Throwable) = tracker.send(new HitBuilders.ExceptionBuilder()
def track(t: Throwable): Unit = tracker.send(new HitBuilders.ExceptionBuilder()
.setDescription(new StandardExceptionParser(this, null).getDescription(Thread.currentThread.getName, t))
.setFatal(false)
.build())
def profileId = settings.getInt(Key.id, -1)
def profileId(i: Int) = editor.putInt(Key.id, i).apply
def currentProfile = profileManager.getProfile(profileId)
def profileId: Int = settings.getInt(Key.id, -1)
def profileId(i: Int): Unit = editor.putInt(Key.id, i).apply()
def currentProfile: Option[Profile] = profileManager.getProfile(profileId)
def switchProfile(id: Int) = {
def switchProfile(id: Int): Profile = {
profileId(id)
profileManager.getProfile(id) getOrElse profileManager.createProfile()
}
......@@ -128,9 +129,11 @@ class ShadowsocksApplication extends Application {
res.updateConfiguration(newConfig, res.getDisplayMetrics)
}
} else {
//noinspection ScalaDeprecation
val newLocale = checkChineseLocale(config.locale)
if (newLocale != null) {
val newConfig = new Configuration(config)
//noinspection ScalaDeprecation
newConfig.locale = newLocale
val res = getResources
res.updateConfiguration(newConfig, res.getDisplayMetrics)
......@@ -171,7 +174,7 @@ class ShadowsocksApplication extends Application {
TcpFastOpen.enabled(settings.getBoolean(Key.tfo, TcpFastOpen.sendEnabled))
}
def refreshContainerHolder {
def refreshContainerHolder() {
val holder = app.containerHolder
if (holder != null) holder.refresh()
}
......@@ -215,5 +218,5 @@ class ShadowsocksApplication extends Application {
editor.putInt(Key.currentVersionCode, BuildConfig.VERSION_CODE).apply()
}
def updateAssets() = if (settings.getInt(Key.currentVersionCode, -1) != BuildConfig.VERSION_CODE) copyAssets()
def updateAssets(): Unit = if (settings.getInt(Key.currentVersionCode, -1) != BuildConfig.VERSION_CODE) copyAssets()
}
......@@ -40,11 +40,11 @@ class ShadowsocksNatService extends BaseService {
val TAG = "ShadowsocksNatService"
val CMD_IPTABLES_DNAT_ADD_SOCKS = "iptables -t nat -A OUTPUT -p tcp " +
"-j DNAT --to-destination 127.0.0.1:8123"
val CMD_IPTABLES_DNAT_ADD_SOCKS =
"iptables -t nat -A OUTPUT -p tcp -j DNAT --to-destination 127.0.0.1:8123"
private var notification: ShadowsocksNotification = _
val myUid = android.os.Process.myUid()
val myUid: Int = android.os.Process.myUid()
var sslocalProcess: GuardedProcess = _
var sstunnelProcess: GuardedProcess = _
......@@ -169,20 +169,17 @@ class ShadowsocksNatService extends BaseService {
val reject = if (profile.ipv6) "224.0.0.0/3" else "224.0.0.0/3, ::/0"
val conf = profile.route match {
case Route.BYPASS_CHN | Route.BYPASS_LAN_CHN | Route.GFWLIST => {
case Route.BYPASS_CHN | Route.BYPASS_LAN_CHN | Route.GFWLIST =>
ConfigUtils.PDNSD_DIRECT.formatLocal(Locale.ENGLISH, "", getApplicationInfo.dataDir,
"127.0.0.1", profile.localPort + 53, "114.114.114.114, 223.5.5.5, 1.2.4.8",
getBlackList, reject, profile.localPort + 63, reject)
}
case Route.CHINALIST => {
case Route.CHINALIST =>
ConfigUtils.PDNSD_DIRECT.formatLocal(Locale.ENGLISH, "", getApplicationInfo.dataDir,
"127.0.0.1", profile.localPort + 53, "8.8.8.8, 8.8.4.4, 208.67.222.222",
"", reject, profile.localPort + 63, reject)
}
case _ => {
case _ =>
ConfigUtils.PDNSD_LOCAL.formatLocal(Locale.ENGLISH, "", getApplicationInfo.dataDir,
"127.0.0.1", profile.localPort + 53, profile.localPort + 63, reject)
}
}
Utils.printToFile(new File(getApplicationInfo.dataDir + "/pdnsd-nat.conf"))(p => {
......@@ -254,7 +251,7 @@ class ShadowsocksNatService extends BaseService {
su.addCommand("iptables -t nat -F OUTPUT")
}
def setupIptables() = {
def setupIptables() {
val init_sb = new ArrayBuffer[String]
val http_sb = new ArrayBuffer[String]
......@@ -291,14 +288,14 @@ class ShadowsocksNatService extends BaseService {
su.addCommand((init_sb ++ http_sb).toArray)
}
override def startRunner(profile: Profile) = if (su == null)
override def startRunner(profile: Profile): Unit = if (su == null)
su = new Shell.Builder().useSU().setWantSTDERR(true).setWatchdogTimeout(10).open((_, exitCode, _) =>
if (exitCode == 0) super.startRunner(profile) else {
if (su != null) {
su.close()
su = null
}
super.stopRunner(true, getString(R.string.nat_no_root))
super.stopRunner(stopService = true, getString(R.string.nat_no_root))
})
override def connect() {
......
......@@ -39,7 +39,7 @@ class ShadowsocksNotification(private val service: BaseService, profileName: Str
private val keyGuard = service.getSystemService(Context.KEYGUARD_SERVICE).asInstanceOf[KeyguardManager]
private lazy val nm = service.getSystemService(Context.NOTIFICATION_SERVICE).asInstanceOf[NotificationManager]
private lazy val callback = new Stub {
override def stateChanged(state: Int, profileName: String, msg: String) = () // ignore
override def stateChanged(state: Int, profileName: String, msg: String): Unit = () // ignore
override def trafficUpdated(txRate: Long, rxRate: Long, txTotal: Long, rxTotal: Long) {
val txr = TrafficMonitor.formatTraffic(txRate)
val rxr = TrafficMonitor.formatTraffic(rxRate)
......@@ -71,8 +71,8 @@ class ShadowsocksNotification(private val service: BaseService, profileName: Str
private lazy val style = new BigTextStyle(builder)
private var isVisible = true
update(if (service.getSystemService(Context.POWER_SERVICE).asInstanceOf[PowerManager].isScreenOn)
Intent.ACTION_SCREEN_ON else Intent.ACTION_SCREEN_OFF, true)
lockReceiver = (context: Context, intent: Intent) => update(intent.getAction)
Intent.ACTION_SCREEN_ON else Intent.ACTION_SCREEN_OFF, forceShow = true)
lockReceiver = (_: Context, intent: Intent) => update(intent.getAction)
val screenFilter = new IntentFilter()
screenFilter.addAction(Intent.ACTION_SCREEN_ON)
screenFilter.addAction(Intent.ACTION_SCREEN_OFF)
......@@ -83,33 +83,33 @@ class ShadowsocksNotification(private val service: BaseService, profileName: Str
if (forceShow || service.getState == State.CONNECTED) action match {
case Intent.ACTION_SCREEN_OFF =>
setVisible(visible && !Utils.isLollipopOrAbove, forceShow)
unregisterCallback // unregister callback to save battery
unregisterCallback() // unregister callback to save battery
case Intent.ACTION_SCREEN_ON =>
setVisible(visible && Utils.isLollipopOrAbove && !keyGuard.inKeyguardRestrictedInputMode, forceShow)
service.binder.registerCallback(callback)
callbackRegistered = true
case Intent.ACTION_USER_PRESENT => setVisible(true, forceShow)
case Intent.ACTION_USER_PRESENT => setVisible(visible = true, forceShow = forceShow)
}
private def unregisterCallback = if (callbackRegistered) {
private def unregisterCallback() = if (callbackRegistered) {
service.binder.unregisterCallback(callback)
callbackRegistered = false
}
def setVisible(visible: Boolean, forceShow: Boolean = false) = if (isVisible != visible) {
def setVisible(visible: Boolean, forceShow: Boolean = false): Unit = if (isVisible != visible) {
isVisible = visible
builder.setPriority(if (visible) NotificationCompat.PRIORITY_LOW else NotificationCompat.PRIORITY_MIN)
show()
} else if (forceShow) show()
def show() = service.startForeground(1, builder.build)
def show(): Unit = service.startForeground(1, builder.build)
def destroy() {
if (lockReceiver != null) {
service.unregisterReceiver(lockReceiver)
lockReceiver = null
}
unregisterCallback
unregisterCallback()
service.stopForeground(true)
nm.cancel(1)
}
......
......@@ -40,7 +40,7 @@ class ShadowsocksQuickSwitchActivity extends AppCompatActivity {
{
val typedArray = obtainStyledAttributes(Array(android.R.attr.selectableItemBackground))
view.setBackgroundResource(typedArray.getResourceId(0, 0))
typedArray.recycle
typedArray.recycle()
}
private var item: Profile = _
private val text = itemView.findViewById(android.R.id.text1).asInstanceOf[CheckedTextView]
......@@ -55,16 +55,16 @@ class ShadowsocksQuickSwitchActivity extends AppCompatActivity {
def onClick(v: View) {
app.switchProfile(item.id)
Utils.startSsService(ShadowsocksQuickSwitchActivity.this)
finish
finish()
}
}
private class ProfilesAdapter extends RecyclerView.Adapter[ProfileViewHolder] {
val profiles = app.profileManager.getAllProfiles.getOrElse(List.empty[Profile])
val profiles: List[Profile] = app.profileManager.getAllProfiles.getOrElse(List.empty[Profile])
def getItemCount = profiles.length
def getItemCount: Int = profiles.length
def onBindViewHolder(vh: ProfileViewHolder, i: Int) = i match {
def onBindViewHolder(vh: ProfileViewHolder, i: Int): Unit = i match {
case _ => vh.bind(profiles(i))
}
......
......@@ -25,7 +25,6 @@ import android.content.{BroadcastReceiver, Context, Intent, IntentFilter}
import android.net.VpnService
import android.os.{Bundle, Handler}
import android.util.Log
import com.github.shadowsocks.utils.ConfigUtils
import com.github.shadowsocks.ShadowsocksApplication.app
object ShadowsocksRunnerActivity {
......@@ -65,7 +64,7 @@ class ShadowsocksRunnerActivity extends Activity with ServiceBoundContext {
val locked = km.inKeyguardRestrictedInputMode
if (locked) {
val filter = new IntentFilter(Intent.ACTION_USER_PRESENT)
receiver = (context: Context, intent: Intent) => {
receiver = (_: Context, intent: Intent) => {
if (intent.getAction == Intent.ACTION_USER_PRESENT) {
attachService()
}
......@@ -74,7 +73,7 @@ class ShadowsocksRunnerActivity extends Activity with ServiceBoundContext {
} else {
attachService()
}
finish
finish()
}
override def onDestroy() {
......
......@@ -23,8 +23,7 @@ package com.github.shadowsocks
import android.app.Service
import android.content.Intent
import android.net.VpnService
import android.os.{IBinder, Handler}
import com.github.shadowsocks.utils.ConfigUtils
import android.os.{Handler, IBinder}
import com.github.shadowsocks.ShadowsocksApplication.app
class ShadowsocksRunnerService extends Service with ServiceBoundContext {
......@@ -44,7 +43,7 @@ class ShadowsocksRunnerService extends Service with ServiceBoundContext {
}, 1000)
}
def startBackgroundService() = bgService.useSync(app.profileId)
def startBackgroundService(): Unit = bgService.useSync(app.profileId)
override def onCreate() {
super.onCreate()
......
......@@ -97,7 +97,7 @@ class ShadowsocksSettings extends PreferenceFragment with OnSharedPreferenceChan
import ShadowsocksSettings._
private def activity = getActivity.asInstanceOf[Shadowsocks]
lazy val natSwitch = findPreference(Key.isNAT).asInstanceOf[SwitchPreference]
lazy val natSwitch: SwitchPreference = findPreference(Key.isNAT).asInstanceOf[SwitchPreference]
private var isProxyApps: SwitchPreference = _
......@@ -182,7 +182,7 @@ class ShadowsocksSettings extends PreferenceFragment with OnSharedPreferenceChan
})
if (getPreferenceManager.getSharedPreferences.getBoolean(Key.isAutoConnect, false)) {
BootReceiver.setEnabled(activity, true)
getPreferenceManager.getSharedPreferences.edit.remove(Key.isAutoConnect).apply
getPreferenceManager.getSharedPreferences.edit.remove(Key.isAutoConnect).apply()
}
switch.setChecked(BootReceiver.getEnabled(activity))
......@@ -200,13 +200,13 @@ class ShadowsocksSettings extends PreferenceFragment with OnSharedPreferenceChan
tfo.setSummary(getString(R.string.tcp_fastopen_summary_unsupported, java.lang.System.getProperty("os.version")))
}
findPreference("recovery").setOnPreferenceClickListener((preference: Preference) => {
findPreference("recovery").setOnPreferenceClickListener(_ => {
app.track(TAG, "reset")
activity.recovery()
true
})
findPreference("about").setOnPreferenceClickListener((preference: Preference) => {
findPreference("about").setOnPreferenceClickListener(_ => {
app.track(TAG, "about")
val web = new WebView(activity)
web.loadUrl("file:///android_asset/pages/about.html")
......@@ -231,7 +231,7 @@ class ShadowsocksSettings extends PreferenceFragment with OnSharedPreferenceChan
})
}
override def onDisplayPreferenceDialog(preference: Preference) = preference.getKey match {
override def onDisplayPreferenceDialog(preference: Preference): Unit = preference.getKey match {
case Key.kcpcli => displayPreferenceDialog(Key.kcpcli, new KcpCliPreferenceDialogFragment())
case _ => super.onDisplayPreferenceDialog(preference)
}
......@@ -253,16 +253,16 @@ class ShadowsocksSettings extends PreferenceFragment with OnSharedPreferenceChan
isProxyApps.setChecked(profile.proxyApps)
}
override def onDestroy {
override def onDestroy() {
super.onDestroy()
app.settings.unregisterOnSharedPreferenceChangeListener(this)
}
def onSharedPreferenceChanged(pref: SharedPreferences, key: String) = key match {
def onSharedPreferenceChanged(pref: SharedPreferences, key: String): Unit = key match {
case Key.isNAT =>
activity.handler.post(() => {
activity.detachService
activity.attachService
activity.detachService()
activity.attachServiceCallback()
})
case _ =>
}
......
......@@ -36,7 +36,7 @@ final class ShadowsocksTileService extends TileService with ServiceBoundContext
private lazy val iconBusy = Icon.createWithResource(this, R.drawable.ic_start_busy)
private lazy val iconConnected = Icon.createWithResource(this, R.drawable.ic_start_connected)
private lazy val callback = new IShadowsocksServiceCallback.Stub {
def trafficUpdated(txRate: Long, rxRate: Long, txTotal: Long, rxTotal: Long) = ()
def trafficUpdated(txRate: Long, rxRate: Long, txTotal: Long, rxTotal: Long): Unit = ()
def stateChanged(state: Int, profileName: String, msg: String) {
val tile = getQsTile
if (tile != null) {
......@@ -54,23 +54,23 @@ final class ShadowsocksTileService extends TileService with ServiceBoundContext
tile.setLabel(getString(R.string.app_name))
tile.setState(Tile.STATE_UNAVAILABLE)
}
tile.updateTile
tile.updateTile()
}
}
}
override def onServiceConnected() = callback.stateChanged(bgService.getState, bgService.getProfileName, null)
override def onServiceConnected(): Unit = callback.stateChanged(bgService.getState, bgService.getProfileName, null)
override def onStartListening {
super.onStartListening
override def onStartListening() {
super.onStartListening()
attachService(callback)
}
override def onStopListening {
super.onStopListening
detachService // just in case the user switches to NAT mode, also saves battery
override def onStopListening() {
super.onStopListening()
detachService() // just in case the user switches to NAT mode, also saves battery
}
override def onClick() = if (isLocked) unlockAndRun(toggle) else toggle()
override def onClick(): Unit = if (isLocked) unlockAndRun(toggle) else toggle()
private def toggle() = if (bgService != null) bgService.getState match {
case State.STOPPED => Utils.startSsService(this)
......
......@@ -61,7 +61,7 @@ class ShadowsocksVpnService extends VpnService with BaseService {
}
override def onRevoke() {
stopRunner(true)
stopRunner(stopService = true)
}
override def stopRunner(stopService: Boolean, msg: String = null) {
......@@ -120,14 +120,14 @@ class ShadowsocksVpnService extends VpnService with BaseService {
val i = new Intent(this, classOf[ShadowsocksRunnerActivity])
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(i)
stopRunner(true)
stopRunner(stopService = true)
return
}
super.startRunner(profile)
}
override def connect() = {
override def connect() {
super.connect()
vpnThread = new ShadowsocksVpnThread(this)
......@@ -253,7 +253,7 @@ class ShadowsocksVpnService extends VpnService with BaseService {
sslocalProcess = new GuardedProcess(cmd).start()
}
def startDnsTunnel() = {
def startDnsTunnel() {
val conf = if (profile.kcp) {
ConfigUtils
.SHADOWSOCKS.formatLocal(Locale.ENGLISH, "127.0.0.1", profile.localPort + 90, profile.localPort + 63,
......@@ -291,20 +291,17 @@ class ShadowsocksVpnService extends VpnService with BaseService {
val reject = if (profile.ipv6) "224.0.0.0/3" else "224.0.0.0/3, ::/0"
val protect = "protect = \"" + protectPath +"\";"
val conf = profile.route match {
case Route.BYPASS_CHN | Route.BYPASS_LAN_CHN | Route.GFWLIST => {
case Route.BYPASS_CHN | Route.BYPASS_LAN_CHN | Route.GFWLIST =>
ConfigUtils.PDNSD_DIRECT.formatLocal(Locale.ENGLISH, protect, getApplicationInfo.dataDir,
"0.0.0.0", profile.localPort + 53, "114.114.114.114, 223.5.5.5, 1.2.4.8",
getBlackList, reject, profile.localPort + 63, reject)
}
case Route.CHINALIST => {
case Route.CHINALIST =>
ConfigUtils.PDNSD_DIRECT.formatLocal(Locale.ENGLISH, protect, getApplicationInfo.dataDir,
"0.0.0.0", profile.localPort + 53, "8.8.8.8, 8.8.4.4, 208.67.222.222",
"", reject, profile.localPort + 63, reject)
}
case _ => {
case _ =>
ConfigUtils.PDNSD_LOCAL.formatLocal(Locale.ENGLISH, protect, getApplicationInfo.dataDir,
"0.0.0.0", profile.localPort + 53, profile.localPort + 63, reject)
}
}
Utils.printToFile(new File(getApplicationInfo.dataDir + "/pdnsd-vpn.conf"))(p => {
p.println(conf)
......
......@@ -21,6 +21,7 @@
package com.github.shadowsocks
import java.io.{File, FileDescriptor, IOException}
import java.lang.reflect.Method
import java.util.concurrent.Executors
import android.net.{LocalServerSocket, LocalSocket, LocalSocketAddress}
......@@ -28,14 +29,14 @@ import android.util.Log
import com.github.shadowsocks.ShadowsocksApplication.app
object ShadowsocksVpnThread {
val getInt = classOf[FileDescriptor].getDeclaredMethod("getInt$")
val getInt: Method = classOf[FileDescriptor].getDeclaredMethod("getInt$")
}
class ShadowsocksVpnThread(vpnService: ShadowsocksVpnService) extends Thread {
import ShadowsocksVpnThread._
val TAG = "ShadowsocksVpnService"
lazy val PATH = vpnService.getApplicationInfo.dataDir + "/protect_path"
lazy val PATH: String = vpnService.getApplicationInfo.dataDir + "/protect_path"
@volatile var isRunning: Boolean = true
@volatile var serverSocket: LocalServerSocket = _
......
......@@ -39,13 +39,13 @@ class TaskerActivity extends AppCompatActivity {
{
val typedArray = obtainStyledAttributes(Array(android.R.attr.selectableItemBackground))
view.setBackgroundResource(typedArray.getResourceId(0, 0))
typedArray.recycle
typedArray.recycle()
}
private var item: Profile = _
private val text = itemView.findViewById(android.R.id.text1).asInstanceOf[CheckedTextView]
itemView.setOnClickListener(this)
def bindDefault {
def bindDefault() {
item = null
text.setText(R.string.profile_default)
text.setChecked(taskerOption.profileId < 0)
......@@ -60,15 +60,15 @@ class TaskerActivity extends AppCompatActivity {
taskerOption.switchOn = switch.isChecked
taskerOption.profileId = if (item == null) -1 else item.id
setResult(Activity.RESULT_OK, taskerOption.toIntent(TaskerActivity.this))
finish
finish()
}
}
private class ProfilesAdapter extends RecyclerView.Adapter[ProfileViewHolder] {
val profiles = app.profileManager.getAllProfiles.getOrElse(List.empty[Profile])
def getItemCount = 1 + profiles.length
def onBindViewHolder(vh: ProfileViewHolder, i: Int) = i match {
case 0 => vh.bindDefault
val profiles: List[Profile] = app.profileManager.getAllProfiles.getOrElse(List.empty[Profile])
def getItemCount: Int = 1 + profiles.length
def onBindViewHolder(vh: ProfileViewHolder, i: Int): Unit = i match {
case 0 => vh.bindDefault()
case _ => vh.bind(profiles(i - 1))
}
private val name = "select_dialog_singlechoice_" + (if (Build.VERSION.SDK_INT >= 21) "material" else "holo")
......
......@@ -30,11 +30,9 @@ import com.github.shadowsocks.ShadowsocksApplication.app
class TaskerReceiver extends BroadcastReceiver {
override def onReceive(context: Context, intent: Intent) {
val settings = TaskerSettings.fromIntent(intent)
val switched = app.profileManager.getProfile(settings.profileId) match {
case Some(p) =>
app.switchProfile(settings.profileId)
true
case _ => false
app.profileManager.getProfile(settings.profileId) match {
case Some(_) => app.switchProfile(settings.profileId)
case _ =>
}
if (settings.switchOn) Utils.startSsService(context) else Utils.stopSsService(context)
}
......
......@@ -36,9 +36,9 @@ object DBHelper {
final val PROFILE = "profile.db"
private var apps: mutable.Buffer[ApplicationInfo] = _
def isAllDigits(x: String) = !x.isEmpty && (x forall Character.isDigit)
def isAllDigits(x: String): Boolean = !x.isEmpty && (x forall Character.isDigit)
def updateProxiedApps(context: Context, old: String) = {
def updateProxiedApps(context: Context, old: String): String = {
synchronized(if (apps == null) apps = context.getPackageManager.getInstalledApplications(0).asScala)
val uidSet = old.split('|').filter(isAllDigits).map(_.toInt).toSet
apps.filter(ai => uidSet.contains(ai.uid)).map(_.packageName).mkString("\n")
......
......@@ -95,9 +95,9 @@ class Profile {
@DatabaseField
var kcpcli: String = "--crypt none --mode normal --mtu 1200 --nocomp --dscp 46 --parityshard 0"
override def toString = "ss://" + Base64.encodeToString("%s%s:%s@%s:%d".formatLocal(Locale.ENGLISH,
override def toString: String = "ss://" + Base64.encodeToString("%s%s:%s@%s:%d".formatLocal(Locale.ENGLISH,
method, if (auth) "-auth" else "", password, host, remotePort).getBytes, Base64.NO_PADDING | Base64.NO_WRAP) +
'#' + URLEncoder.encode(name, "utf-8")
def isMethodUnsafe = "table".equalsIgnoreCase(method) || "rc4".equalsIgnoreCase(method)
def isMethodUnsafe: Boolean = "table".equalsIgnoreCase(method) || "rc4".equalsIgnoreCase(method)
}
......@@ -31,7 +31,7 @@ class ProfileManager(dbHelper: DBHelper) {
import ProfileManager._
var profileAddedListener: Profile => Any = _
def setProfileAddedListener(listener: Profile => Any) = this.profileAddedListener = listener
def setProfileAddedListener(listener: Profile => Any): Unit = this.profileAddedListener = listener
def createProfile(p: Profile = null): Profile = {
val profile = if (p == null) new Profile else p
......@@ -99,7 +99,7 @@ class ProfileManager(dbHelper: DBHelper) {
}
}
def getFirstProfile = {
def getFirstProfile: Option[Profile] = {
try {
val result = dbHelper.profileDao.query(dbHelper.profileDao.queryBuilder.limit(1L).prepare)
if (result.size == 1) Option(result.get(0)) else None
......
......@@ -36,7 +36,7 @@ import com.github.shadowsocks.utils.IOUtils
object AclSyncJob {
final val TAG = "AclSyncJob"
def schedule(route: String) = new JobRequest.Builder(AclSyncJob.TAG + ':' + route)
def schedule(route: String): Int = new JobRequest.Builder(AclSyncJob.TAG + ':' + route)
.setExecutionWindow(1, TimeUnit.DAYS.toMillis(28))
.setRequirementsEnforced(true)
.setRequiredNetworkType(JobRequest.NetworkType.UNMETERED)
......
......@@ -32,7 +32,7 @@ import com.evernote.android.job.JobCreator
* @author !Mygod
*/
object DonaldTrump extends JobCreator {
def create(tag: String) = {
def create(tag: String): AclSyncJob = {
val parts = tag.split(":")
parts(0) match {
case AclSyncJob.TAG => new AclSyncJob(parts(1))
......
......@@ -35,9 +35,9 @@ object CloseUtils {
block(a.get)
} finally if (a.nonEmpty) try {
val v = a.get
if (v ne null) v.close
if (v ne null) v.close()
} catch {
case ignore: Exception =>
case _: Exception =>
}
}
def autoDisconnect[A <: Disconnectable, B](x: => A)(block: A => B): B = {
......@@ -47,9 +47,9 @@ object CloseUtils {
block(a.get)
} finally if (a.nonEmpty) try {
val v = a.get
if (v ne null) v.disconnect
if (v ne null) v.disconnect()
} catch {
case ignore: Exception =>
case _: Exception =>
}
}
}
......@@ -47,5 +47,6 @@ object IOUtils {
null
}
def writeString(file: String, content: String) = autoClose(new FileWriter(file))(writer => writer.write(content))
def writeString(file: String, content: String): Unit =
autoClose(new FileWriter(file))(writer => writer.write(content))
}
......@@ -30,23 +30,23 @@ object Parser {
private val pattern = "(?i)ss://([A-Za-z0-9+-/=_]+)(#(.+))?".r
private val decodedPattern = "(?i)^((.+?)(-auth)??:(.*)@(.+?):(\\d+?))$".r
def findAll(data: CharSequence) = pattern.findAllMatchIn(if (data == null) "" else data).map(m => try
decodedPattern.findFirstMatchIn(new String(Base64.decode(m.group(1), Base64.NO_PADDING), "UTF-8")) match {
case Some(ss) =>
val profile = new Profile
profile.method = ss.group(2).toLowerCase
if (ss.group(3) != null) profile.auth = true
profile.password = ss.group(4)
profile.name = ss.group(5)
profile.host = profile.name
profile.remotePort = ss.group(6).toInt
if (m.group(2) != null) profile.name = URLDecoder.decode(m.group(3), "utf-8")
profile
case _ => null
}
catch {
case ex: Exception =>
Log.e(TAG, "parser error: " + m.source, ex)// Ignore
null
}).filter(_ != null)
def findAll(data: CharSequence): Iterator[Profile] =
pattern.findAllMatchIn(if (data == null) "" else data).map(m => try
decodedPattern.findFirstMatchIn(new String(Base64.decode(m.group(1), Base64.NO_PADDING), "UTF-8")) match {
case Some(ss) =>
val profile = new Profile
profile.method = ss.group(2).toLowerCase
if (ss.group(3) != null) profile.auth = true
profile.password = ss.group(4)
profile.name = ss.group(5)
profile.host = profile.name
profile.remotePort = ss.group(6).toInt
if (m.group(2) != null) profile.name = URLDecoder.decode(m.group(3), "utf-8")
profile
case _ => null
} catch {
case ex: Exception =>
Log.e(TAG, "parser error: " + m.source, ex)// Ignore
null
}).filter(_ != null)
}
......@@ -37,10 +37,10 @@ object TaskerSettings {
class TaskerSettings(bundle: Bundle) {
import TaskerSettings._
var switchOn = bundle.getBoolean(KEY_SWITCH_ON, true)
var profileId = bundle.getInt(KEY_PROFILE_ID, -1)
var switchOn: Boolean = bundle.getBoolean(KEY_SWITCH_ON, true)
var profileId: Int = bundle.getInt(KEY_PROFILE_ID, -1)
def toIntent(context: Context) = {
def toIntent(context: Context): Intent = {
val bundle = new Bundle()
if (!switchOn) bundle.putBoolean(KEY_SWITCH_ON, false)
if (profileId >= 0) bundle.putInt(KEY_PROFILE_ID, profileId)
......
......@@ -33,7 +33,7 @@ object TcpFastOpen {
/**
* Is kernel version >= 3.7.1.
*/
lazy val supported = "^(\\d+)\\.(\\d+)\\.(\\d+)".r.findFirstMatchIn(System.getProperty("os.version")) match {
lazy val supported: Boolean = "^(\\d+)\\.(\\d+)\\.(\\d+)".r.findFirstMatchIn(System.getProperty("os.version")) match {
case Some(m) =>
val kernel = m.group(1).toInt
if (kernel < 3) false else if (kernel > 3) true else {
......@@ -43,7 +43,7 @@ object TcpFastOpen {
case _ => false
}
def sendEnabled = {
def sendEnabled: Boolean = {
val file = new File("/proc/sys/net/ipv4/tcp_fastopen")
file.canRead && (Utils.readAllLines(file).toInt & 1) > 0
}
......
......@@ -53,7 +53,7 @@ object TrafficMonitor {
else numberFormat.format(n) + ' ' + units(i)
}
def updateRate() = {
def updateRate(): Boolean = {
val now = System.currentTimeMillis()
val delta = now - timestampLast
var updated = false
......
......@@ -32,7 +32,7 @@ import com.github.shadowsocks.ShadowsocksApplication.app
class TrafficMonitorThread(context: Context) extends Thread {
val TAG = "TrafficMonitorThread"
lazy val PATH = context.getApplicationInfo.dataDir + "/stat_path"
lazy val PATH: String = context.getApplicationInfo.dataDir + "/stat_path"
@volatile var serverSocket: LocalServerSocket = _
@volatile var isRunning: Boolean = true
......
......@@ -66,7 +66,7 @@ object Utils {
*/
// Based on: http://stackoverflow.com/a/21026866/2245107
def positionToast(toast: Toast, view: View, window: Window, offsetX: Int = 0, offsetY: Int = 0) = {
def positionToast(toast: Toast, view: View, window: Window, offsetX: Int = 0, offsetY: Int = 0): Toast = {
val rect = new Rect
window.getDecorView.getWindowVisibleDisplayFrame(rect)
val viewLocation = new Array[Int](2)
......@@ -88,11 +88,11 @@ object Utils {
to.setVisibility(View.VISIBLE)
to.animate().alpha(1).setDuration(shortAnimTime)
from.animate().alpha(0).setDuration(shortAnimTime).setListener(new AnimatorListenerAdapter {
override def onAnimationEnd(animation: Animator) = from.setVisibility(View.GONE)
override def onAnimationEnd(animation: Animator): Unit = from.setVisibility(View.GONE)
})
}
def readAllLines(f: File) = {
def readAllLines(f: File): String = {
val scanner = new Scanner(f)
try {
scanner.useDelimiter("\\Z")
......@@ -168,40 +168,18 @@ object Utils {
}
}
} catch {
case e: Exception =>
case _: Exception =>
}
None
}
def resolve(host: String): Option[String] = {
try {
val addr = InetAddress.getByName(host)
Some(addr.getHostAddress)
} catch {
case e: UnknownHostException => None
}
def resolve(host: String): Option[String] = try Some(InetAddress.getByName(host).getHostAddress) catch {
case _: UnknownHostException => None
}
def resolve(host: String, enableIPv6: Boolean): Option[String] = {
if (enableIPv6 && Utils.isIPv6Support) {
resolve(host, Type.AAAA) match {
case Some(addr) =>
return Some(addr)
case None =>
}
}
resolve(host, Type.A) match {
case Some(addr) =>
return Some(addr)
case None =>
}
resolve(host) match {
case Some(addr) =>
return Some(addr)
case None =>
}
None
}
def resolve(host: String, enableIPv6: Boolean): Option[String] =
(if (enableIPv6 && Utils.isIPv6Support) resolve(host, Type.AAAA) else None).orElse(resolve(host, Type.A))
.orElse(resolve(host))
private lazy val isNumericMethod = classOf[InetAddress].getMethod("isNumeric", classOf[String])
def isNumeric(address: String): Boolean = isNumericMethod.invoke(null, address).asInstanceOf[Boolean]
......@@ -242,5 +220,5 @@ object Utils {
case _ =>
}
def ThrowableFuture[T](f: => T) = Future(f) onComplete handleFailure
def ThrowableFuture[T](f: => T): Unit = Future(f) onComplete handleFailure
}
......@@ -42,10 +42,11 @@ class FloatingActionMenuBehavior(context: Context, attrs: AttributeSet)
private var fabTranslationYAnimator: ValueAnimator = _
private var fabTranslationY: Float = _
override def layoutDependsOn(parent: CoordinatorLayout, child: FloatingActionMenu, dependency: View) =
override def layoutDependsOn(parent: CoordinatorLayout, child: FloatingActionMenu, dependency: View): Boolean =
dependency.isInstanceOf[SnackbarLayout]
override def onDependentViewChanged(parent: CoordinatorLayout, child: FloatingActionMenu, dependency: View) = {
override def onDependentViewChanged(parent: CoordinatorLayout, child: FloatingActionMenu,
dependency: View): Boolean = {
dependency match {
case _: SnackbarLayout =>
var targetTransY = parent.getDependencies(child).asScala
......@@ -54,7 +55,7 @@ class FloatingActionMenuBehavior(context: Context, attrs: AttributeSet)
if (targetTransY > 0) targetTransY = 0
if (fabTranslationY != targetTransY) {
val currentTransY = child.getTranslationY
if (fabTranslationYAnimator != null && fabTranslationYAnimator.isRunning) fabTranslationYAnimator.cancel
if (fabTranslationYAnimator != null && fabTranslationYAnimator.isRunning) fabTranslationYAnimator.cancel()
if (child.isShown && Math.abs(currentTransY - targetTransY) > child.getHeight * 0.667F) {
if (fabTranslationYAnimator == null) {
fabTranslationYAnimator = new ValueAnimator
......@@ -63,7 +64,7 @@ class FloatingActionMenuBehavior(context: Context, attrs: AttributeSet)
child.setTranslationY(animation.getAnimatedValue.asInstanceOf[Float]))
}
fabTranslationYAnimator.setFloatValues(currentTransY, targetTransY)
fabTranslationYAnimator.start
fabTranslationYAnimator.start()
} else child.setTranslationY(targetTransY)
fabTranslationY = targetTransY
}
......@@ -74,7 +75,7 @@ class FloatingActionMenuBehavior(context: Context, attrs: AttributeSet)
override def onStartNestedScroll(parent: CoordinatorLayout, child: FloatingActionMenu, directTargetChild: View,
target: View, nestedScrollAxes: Int) = true
override def onNestedScroll(parent: CoordinatorLayout, child: FloatingActionMenu, target: View, dxConsumed: Int,
dyConsumed: Int, dxUnconsumed: Int, dyUnconsumed: Int) = {
dyConsumed: Int, dxUnconsumed: Int, dyUnconsumed: Int) {
super.onNestedScroll(parent, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed)
val dy = dyConsumed + dyUnconsumed
if (child.isMenuButtonHidden) {
......
......@@ -37,12 +37,12 @@ class UndoSnackbarManager[T](view: View, undo: Iterator[(Int, T)] => Unit,
commit: Iterator[(Int, T)] => Unit = null) {
private val recycleBin = new ArrayBuffer[(Int, T)]
private val removedCallback = new Snackbar.Callback {
override def onDismissed(snackbar: Snackbar, event: Int) = {
override def onDismissed(snackbar: Snackbar, event: Int) {
event match {
case Snackbar.Callback.DISMISS_EVENT_SWIPE | Snackbar.Callback.DISMISS_EVENT_MANUAL |
Snackbar.Callback.DISMISS_EVENT_TIMEOUT =>
if (commit != null) commit(recycleBin.iterator)
recycleBin.clear
recycleBin.clear()
case _ =>
}
last = null
......@@ -50,7 +50,7 @@ class UndoSnackbarManager[T](view: View, undo: Iterator[(Int, T)] => Unit,
}
private var last: Snackbar = _
def remove(index: Int, item: T) = {
def remove(index: Int, item: T) {
recycleBin.append((index, item))
val count = recycleBin.length
last = Snackbar
......@@ -59,8 +59,8 @@ class UndoSnackbarManager[T](view: View, undo: Iterator[(Int, T)] => Unit,
undo(recycleBin.reverseIterator)
recycleBin.clear
}): View.OnClickListener)
last.show
last.show()
}
def flush = if (last != null) last.dismiss
def flush(): Unit = if (last != null) last.dismiss()
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment