Add a toggle for showing traffic in notification.
TODO: Disabling it causes weird behavior. :-(
This commit is contained in:
@@ -32,8 +32,7 @@
|
||||
<string name="bypass_apps_summary">启用该选项,以使所选应用程序的流量不经过代理</string>
|
||||
<string name="auto_connect">自动连接</string>
|
||||
<string name="auto_connect_summary">随系统启动后台服务</string>
|
||||
<string name="traffic_stat">流量统计</string>
|
||||
<string name="traffic_stat_summary">在通知栏上显示当前上下行速率</string>
|
||||
<string name="notification_traffic">在通知内显示当前上下行速率</string>
|
||||
<string name="forward_success">后台服务已开始运行。</string>
|
||||
<string name="service_running">影梭 → %s</string>
|
||||
<string name="service_failed">无法连接远程服务器</string>
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
<string name="nat_summary">Use NAT mode instead of VPN mode</string>
|
||||
<string name="nat_summary_no_root">NAT mode is disabled without root</string>
|
||||
<string name="stat">Network Traffic</string>
|
||||
<string name="notification_traffic">Show traffic in notification</string>
|
||||
<string name="stat_summary">Sent: \t\t\t\t\t%3$s\t↑\t%1$s/s\nReceived: \t%4$s\t↓\t%2$s/s</string>
|
||||
<string name="stat_profiles">\n%1$s↑\t%2$s↓</string>
|
||||
<string name="traffic_summary">%1$s/s↑\t%2$s/s↓</string>
|
||||
@@ -55,8 +56,6 @@
|
||||
<string name="bypass_apps_summary">Enable this option to bypass selected apps</string>
|
||||
<string name="auto_connect">Auto Connect</string>
|
||||
<string name="auto_connect_summary">Enable Shadowsocks on startup</string>
|
||||
<string name="traffic_stat">Traffic Stats</string>
|
||||
<string name="traffic_stat_summary">Show traffic stats in notification bar</string>
|
||||
<string name="udp_dns">UDP Forwarding</string>
|
||||
<string name="udp_dns_summary">Forward UDP packets to remote</string>
|
||||
|
||||
|
||||
@@ -82,6 +82,8 @@
|
||||
android:key="isAutoConnect"
|
||||
android:summary="@string/auto_connect_summary"
|
||||
android:title="@string/auto_connect"/>
|
||||
<SwitchPreference android:key="notificationTraffic" android:defaultValue="true"
|
||||
android:title="@string/notification_traffic"/>
|
||||
|
||||
<com.github.shadowsocks.preferences.NatSwitchPreference android:key="isNAT"
|
||||
android:title="@string/nat"
|
||||
|
||||
@@ -452,6 +452,7 @@ class Shadowsocks
|
||||
}
|
||||
|
||||
private def setPreferenceEnabled(enabled: Boolean) {
|
||||
preferences.findPreference(Key.notificationTraffic).setEnabled(enabled)
|
||||
preferences.findPreference(Key.isNAT).setEnabled(enabled)
|
||||
for (name <- Shadowsocks.PROXY_PREFS) {
|
||||
val pref = preferences.findPreference(name)
|
||||
@@ -472,7 +473,8 @@ class Shadowsocks
|
||||
}
|
||||
|
||||
private def updatePreferenceScreen() {
|
||||
if (ShadowsocksApplication.proxy == "198.199.101.152" && adView == null) {
|
||||
val profile = currentProfile
|
||||
if (profile.host == "198.199.101.152" && adView == null) {
|
||||
adView = new AdView(this)
|
||||
adView.setAdUnitId("ca-app-pub-9097031975646651/7760346322")
|
||||
adView.setAdSize(AdSize.SMART_BANNER)
|
||||
@@ -480,7 +482,6 @@ class Shadowsocks
|
||||
adView.loadAd(new AdRequest.Builder().build())
|
||||
}
|
||||
|
||||
val profile = currentProfile
|
||||
for (name <- Shadowsocks.PROXY_PREFS) {
|
||||
val pref = preferences.findPreference(name)
|
||||
Shadowsocks.updatePreference(pref, name, profile)
|
||||
|
||||
@@ -76,9 +76,10 @@ object ShadowsocksApplication {
|
||||
.setLabel(getVersionName)
|
||||
.build())
|
||||
|
||||
def notificationTraffic = settings.getBoolean(Key.notificationTraffic, true)
|
||||
|
||||
def profileId = settings.getInt(Key.profileId, -1)
|
||||
def profileId(i: Int) = settings.edit.putInt(Key.profileId, i).apply
|
||||
def proxy = settings.getString(Key.proxy, "")
|
||||
def currentProfile = profileManager.getProfile(profileId)
|
||||
|
||||
def switchProfile(id: Int) = {
|
||||
|
||||
@@ -13,8 +13,7 @@ import com.github.shadowsocks.utils.{Action, State, Utils}
|
||||
/**
|
||||
* @author Mygod
|
||||
*/
|
||||
class ShadowsocksNotification(private val service: BaseService, profileName: String, visible: Boolean = false,
|
||||
private val showTraffic: Boolean = true) {
|
||||
class ShadowsocksNotification(private val service: BaseService, profileName: String, visible: Boolean = false) {
|
||||
private lazy val keyGuard = service.getSystemService(Context.KEYGUARD_SERVICE).asInstanceOf[KeyguardManager]
|
||||
private lazy val callback = new Stub {
|
||||
override def stateChanged(state: Int, msg: String) = () // ignore
|
||||
@@ -26,6 +25,7 @@ class ShadowsocksNotification(private val service: BaseService, profileName: Str
|
||||
}
|
||||
}
|
||||
private var lockReceiver: BroadcastReceiver = _
|
||||
private var callbackRegistered: Boolean = true
|
||||
|
||||
private val builder = new NotificationCompat.Builder(service)
|
||||
.setWhen(0)
|
||||
@@ -39,8 +39,8 @@ class ShadowsocksNotification(private val service: BaseService, profileName: Str
|
||||
PendingIntent.getBroadcast(service, 0, new Intent(Action.CLOSE), 0))
|
||||
private lazy val style = new BigTextStyle(builder)
|
||||
private val showOnUnlock = visible && Utils.isLollipopOrAbove
|
||||
if (showOnUnlock || showTraffic) {
|
||||
update(Intent.ACTION_USER_PRESENT)
|
||||
if (showOnUnlock || ShadowsocksApplication.notificationTraffic) {
|
||||
update()
|
||||
lockReceiver = (context: Context, intent: Intent) => update(intent.getAction)
|
||||
val screenFilter = new IntentFilter()
|
||||
screenFilter.addAction(Intent.ACTION_SCREEN_ON)
|
||||
@@ -49,32 +49,39 @@ class ShadowsocksNotification(private val service: BaseService, profileName: Str
|
||||
service.registerReceiver(lockReceiver, screenFilter)
|
||||
} else setVisible(visible).show()
|
||||
|
||||
private def update(action: String) = if (service.getState == State.CONNECTED) {
|
||||
def update(action: String = Intent.ACTION_SCREEN_ON) = if (service.getState == State.CONNECTED) {
|
||||
if (action == Intent.ACTION_SCREEN_OFF) {
|
||||
if (showOnUnlock) setVisible(false)
|
||||
if (showTraffic) service.binder.unregisterCallback(callback)
|
||||
} else if (action == Intent.ACTION_USER_PRESENT ||
|
||||
action == Intent.ACTION_SCREEN_ON && !keyGuard.inKeyguardRestrictedInputMode) {
|
||||
setVisible(showOnUnlock)
|
||||
if (showTraffic) service.binder.registerCallback(callback)
|
||||
}
|
||||
unregisterCallback // unregister callback to save battery
|
||||
} else if (action == Intent.ACTION_SCREEN_ON) {
|
||||
if (ShadowsocksApplication.notificationTraffic) {
|
||||
service.binder.registerCallback(callback)
|
||||
callbackRegistered = true
|
||||
} else unregisterCallback
|
||||
if (!keyGuard.inKeyguardRestrictedInputMode) setVisible(showOnUnlock)
|
||||
} else if (action == Intent.ACTION_USER_PRESENT) setVisible(showOnUnlock)
|
||||
show()
|
||||
}
|
||||
|
||||
private def unregisterCallback = if (callbackRegistered) {
|
||||
service.binder.unregisterCallback(callback)
|
||||
callbackRegistered = false
|
||||
}
|
||||
|
||||
def setVisible(visible: Boolean) = {
|
||||
builder.setPriority(if (visible) NotificationCompat.PRIORITY_DEFAULT else NotificationCompat.PRIORITY_MIN)
|
||||
this
|
||||
}
|
||||
|
||||
def notification = if (showTraffic) style.build() else builder.build()
|
||||
def notification = if (callbackRegistered) style.build() else builder.build()
|
||||
def show() = service.startForeground(1, notification)
|
||||
|
||||
def destroy() = {
|
||||
def destroy() {
|
||||
if (lockReceiver != null) {
|
||||
service.unregisterReceiver(lockReceiver)
|
||||
lockReceiver = null
|
||||
}
|
||||
if (showTraffic) service.binder.unregisterCallback(callback)
|
||||
unregisterCallback
|
||||
service.stopForeground(true)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,8 @@ package com.github.shadowsocks
|
||||
|
||||
import java.util.Locale
|
||||
|
||||
import android.content.{DialogInterface, Intent}
|
||||
import android.content.SharedPreferences.OnSharedPreferenceChangeListener
|
||||
import android.content.{DialogInterface, Intent, SharedPreferences}
|
||||
import android.net.Uri
|
||||
import android.os.{Build, Bundle}
|
||||
import android.preference.{Preference, PreferenceFragment, SwitchPreference}
|
||||
@@ -11,7 +12,7 @@ import android.webkit.{WebView, WebViewClient}
|
||||
import com.github.shadowsocks.utils.Key
|
||||
|
||||
// TODO: Move related logic here
|
||||
class ShadowsocksSettings extends PreferenceFragment {
|
||||
class ShadowsocksSettings extends PreferenceFragment with OnSharedPreferenceChangeListener {
|
||||
private lazy val activity = getActivity.asInstanceOf[Shadowsocks]
|
||||
|
||||
private var isProxyApps: SwitchPreference = _
|
||||
@@ -19,6 +20,7 @@ class ShadowsocksSettings extends PreferenceFragment {
|
||||
override def onCreate(savedInstanceState: Bundle) {
|
||||
super.onCreate(savedInstanceState)
|
||||
addPreferencesFromResource(R.xml.pref_all)
|
||||
getPreferenceManager.getSharedPreferences.registerOnSharedPreferenceChangeListener(this)
|
||||
|
||||
isProxyApps = findPreference(Key.isProxyApps).asInstanceOf[SwitchPreference]
|
||||
isProxyApps.setOnPreferenceChangeListener((preference: Preference, newValue: Any) => {
|
||||
@@ -26,12 +28,6 @@ class ShadowsocksSettings extends PreferenceFragment {
|
||||
newValue.asInstanceOf[Boolean] // keep it ON
|
||||
})
|
||||
|
||||
findPreference(Key.isNAT).setOnPreferenceChangeListener((preference: Preference, newValue: Any) =>
|
||||
if (ShadowsocksApplication.isRoot) activity.handler.post(() => {
|
||||
activity.deattachService()
|
||||
activity.attachService()
|
||||
}) else false)
|
||||
|
||||
findPreference("recovery").setOnPreferenceClickListener((preference: Preference) => {
|
||||
ShadowsocksApplication.track(Shadowsocks.TAG, "reset")
|
||||
activity.recovery()
|
||||
@@ -75,4 +71,12 @@ class ShadowsocksSettings extends PreferenceFragment {
|
||||
super.onResume
|
||||
isProxyApps.setChecked(ShadowsocksApplication.settings.getBoolean(Key.isProxyApps, false)) // update
|
||||
}
|
||||
|
||||
def onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) = key match {
|
||||
case Key.isNAT => if (ShadowsocksApplication.isRoot) activity.handler.post(() => {
|
||||
activity.deattachService()
|
||||
activity.attachService()
|
||||
})
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,6 +68,7 @@ object Key {
|
||||
val profiles = "profiles"
|
||||
val isNAT = "isNAT"
|
||||
val route = "route"
|
||||
val notificationTraffic = "notificationTraffic"
|
||||
val stat = "stat"
|
||||
|
||||
val isRunning = "isRunning"
|
||||
|
||||
Reference in New Issue
Block a user