Fix bandwidth display in ProfilesFragment when hot swapping profiles
This commit is contained in:
@@ -2,5 +2,7 @@ package com.github.shadowsocks.aidl;
|
||||
|
||||
interface IShadowsocksServiceCallback {
|
||||
oneway void stateChanged(int state, String profileName, String msg);
|
||||
oneway void trafficUpdated(long txRate, long rxRate, long txTotal, long rxTotal);
|
||||
oneway void trafficUpdated(int profileId, long txRate, long rxRate, long txTotal, long rxTotal);
|
||||
// Traffic data has persisted to database, listener should refetch their data from database
|
||||
oneway void trafficPersisted(int profileId);
|
||||
}
|
||||
|
||||
@@ -97,7 +97,8 @@ trait BaseService extends Service {
|
||||
}, 1000, 1000)
|
||||
}
|
||||
TrafficMonitor.updateRate()
|
||||
cb.trafficUpdated(TrafficMonitor.txRate, TrafficMonitor.rxRate, TrafficMonitor.txTotal, TrafficMonitor.rxTotal)
|
||||
cb.trafficUpdated(profile.id,
|
||||
TrafficMonitor.txRate, TrafficMonitor.rxRate, TrafficMonitor.txTotal, TrafficMonitor.rxTotal)
|
||||
}
|
||||
|
||||
override def stopListeningForBandwidth(cb: IShadowsocksServiceCallback): Unit =
|
||||
@@ -246,6 +247,20 @@ trait BaseService extends Service {
|
||||
p.tx += tx
|
||||
p.rx += rx
|
||||
app.profileManager.updateProfile(p)
|
||||
handler.post(() => {
|
||||
if (bandwidthListeners.nonEmpty) {
|
||||
val n = callbacks.beginBroadcast()
|
||||
for (i <- 0 until n) {
|
||||
try {
|
||||
val item = callbacks.getBroadcastItem(i)
|
||||
if (bandwidthListeners.contains(item.asBinder)) item.trafficPersisted(p.id)
|
||||
} catch {
|
||||
case _: Exception => // Ignore
|
||||
}
|
||||
}
|
||||
callbacks.finishBroadcast()
|
||||
}
|
||||
})
|
||||
case None =>
|
||||
}
|
||||
}
|
||||
@@ -266,7 +281,8 @@ trait BaseService extends Service {
|
||||
for (i <- 0 until n) {
|
||||
try {
|
||||
val item = callbacks.getBroadcastItem(i)
|
||||
if (bandwidthListeners.contains(item.asBinder)) item.trafficUpdated(txRate, rxRate, txTotal, rxTotal)
|
||||
if (bandwidthListeners.contains(item.asBinder))
|
||||
item.trafficUpdated(profile.id, txRate, rxRate, txTotal, rxTotal)
|
||||
} catch {
|
||||
case _: Exception => // Ignore
|
||||
}
|
||||
|
||||
@@ -97,8 +97,10 @@ class MainActivity extends Activity with ServiceBoundContext with Drawer.OnDrawe
|
||||
var state: Int = _
|
||||
private val callback = new IShadowsocksServiceCallback.Stub {
|
||||
def stateChanged(s: Int, profileName: String, m: String): Unit = handler.post(() => changeState(s, profileName, m))
|
||||
def trafficUpdated(txRate: Long, rxRate: Long, txTotal: Long, rxTotal: Long): Unit =
|
||||
handler.post(() => updateTraffic(txRate, rxRate, txTotal, rxTotal))
|
||||
def trafficUpdated(profileId: Int, txRate: Long, rxRate: Long, txTotal: Long, rxTotal: Long): Unit =
|
||||
handler.post(() => updateTraffic(profileId, txRate, rxRate, txTotal, rxTotal))
|
||||
override def trafficPersisted(profileId: Int): Unit = handler.post(() => if (ProfilesFragment.instance != null)
|
||||
ProfilesFragment.instance.onTrafficPersisted(profileId))
|
||||
}
|
||||
|
||||
private lazy val greyTint = ContextCompat.getColorStateList(MainActivity.this, R.color.material_primary_500)
|
||||
@@ -136,25 +138,22 @@ class MainActivity extends Activity with ServiceBoundContext with Drawer.OnDrawe
|
||||
state = s
|
||||
if (state == State.CONNECTED) fab.setBackgroundTintList(greenTint) else {
|
||||
fab.setBackgroundTintList(greyTint)
|
||||
updateTraffic(0, 0, 0, 0)
|
||||
updateTraffic(-1, 0, 0, 0, 0)
|
||||
testCount += 1 // suppress previous test messages
|
||||
}
|
||||
if (ProfilesFragment.instance != null) {
|
||||
val adapter = ProfilesFragment.instance.profilesAdapter
|
||||
adapter.notifyDataSetChanged() // refresh button enabled state
|
||||
if (state == State.STOPPED) adapter.refreshId(app.profileId) // refresh bandwidth statistics
|
||||
}
|
||||
if (ProfilesFragment.instance != null)
|
||||
ProfilesFragment.instance.profilesAdapter.notifyDataSetChanged() // refresh button enabled state
|
||||
fab.setEnabled(false)
|
||||
if (state == State.CONNECTED || state == State.STOPPED)
|
||||
handler.postDelayed(() => fab.setEnabled(state == State.CONNECTED || state == State.STOPPED), 1000)
|
||||
}
|
||||
def updateTraffic(txRate: Long, rxRate: Long, txTotal: Long, rxTotal: Long) {
|
||||
def updateTraffic(profileId: Int, txRate: Long, rxRate: Long, txTotal: Long, rxTotal: Long) {
|
||||
txText.setText(TrafficMonitor.formatTraffic(txTotal))
|
||||
rxText.setText(TrafficMonitor.formatTraffic(rxTotal))
|
||||
txRateText.setText(TrafficMonitor.formatTraffic(txRate) + "/s")
|
||||
rxRateText.setText(TrafficMonitor.formatTraffic(rxRate) + "/s")
|
||||
val child = getFragmentManager.findFragmentById(R.id.fragment_holder).asInstanceOf[ToolbarFragment]
|
||||
if (state != State.STOPPING && child != null) child.onTrafficUpdated(txRate, rxRate, txTotal, rxTotal)
|
||||
if (state != State.STOPPING && child != null) child.onTrafficUpdated(profileId, txRate, rxRate, txTotal, rxTotal)
|
||||
}
|
||||
|
||||
override def onServiceConnected() {
|
||||
|
||||
@@ -101,7 +101,7 @@ class ProfileConfigFragment extends PreferenceFragment with OnMenuItemClickListe
|
||||
def saveAndExit() {
|
||||
profile.deserialize(app.settings)
|
||||
app.profileManager.updateProfile(profile)
|
||||
if (ProfilesFragment.instance != null) ProfilesFragment.instance.profilesAdapter.refreshId(profile.id)
|
||||
if (ProfilesFragment.instance != null) ProfilesFragment.instance.profilesAdapter.deepRefreshId(profile.id)
|
||||
getActivity.finish()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ final class ProfilesFragment extends ToolbarFragment with Toolbar.OnMenuItemClic
|
||||
edit.setAlpha(if (editable) 1 else 0.5F)
|
||||
var tx = item.tx
|
||||
var rx = item.rx
|
||||
if (item.id == app.profileId) {
|
||||
if (item.id == bandwidthProfile) {
|
||||
tx += txTotal
|
||||
rx += rxTotal
|
||||
}
|
||||
@@ -222,6 +222,10 @@ final class ProfilesFragment extends ToolbarFragment with Toolbar.OnMenuItemClic
|
||||
for ((_, item) <- actions) app.profileManager.delProfile(item.id)
|
||||
|
||||
def refreshId(id: Int) {
|
||||
val index = profiles.indexWhere(_.id == id)
|
||||
if (index >= 0) notifyItemChanged(index)
|
||||
}
|
||||
def deepRefreshId(id: Int) {
|
||||
val index = profiles.indexWhere(_.id == id)
|
||||
if (index >= 0) {
|
||||
profiles(index) = app.profileManager.getProfile(id).get
|
||||
@@ -242,6 +246,7 @@ final class ProfilesFragment extends ToolbarFragment with Toolbar.OnMenuItemClic
|
||||
|
||||
lazy val profilesAdapter = new ProfilesAdapter
|
||||
private var undoManager: UndoSnackbarManager[Profile] = _
|
||||
private var bandwidthProfile: Int = _
|
||||
private var txTotal: Long = _
|
||||
private var rxTotal: Long = _
|
||||
|
||||
@@ -292,10 +297,24 @@ final class ProfilesFragment extends ToolbarFragment with Toolbar.OnMenuItemClic
|
||||
}).attachToRecyclerView(profilesList)
|
||||
}
|
||||
|
||||
override def onTrafficUpdated(txRate: Long, rxRate: Long, txTotal: Long, rxTotal: Long): Unit = {
|
||||
this.txTotal = txTotal
|
||||
this.rxTotal = rxTotal
|
||||
profilesAdapter.refreshId(app.profileId)
|
||||
override def onTrafficUpdated(profileId: Int, txRate: Long, rxRate: Long, txTotal: Long, rxTotal: Long): Unit =
|
||||
if (profileId != -1) { // ignore resets from MainActivity
|
||||
if (bandwidthProfile != profileId) {
|
||||
onTrafficPersisted(bandwidthProfile)
|
||||
bandwidthProfile = profileId
|
||||
}
|
||||
this.txTotal = txTotal
|
||||
this.rxTotal = rxTotal
|
||||
profilesAdapter.refreshId(profileId)
|
||||
}
|
||||
def onTrafficPersisted(profileId: Int) {
|
||||
txTotal = 0
|
||||
rxTotal = 0
|
||||
if (bandwidthProfile != profileId) {
|
||||
onTrafficPersisted(bandwidthProfile)
|
||||
bandwidthProfile = profileId
|
||||
}
|
||||
profilesAdapter.deepRefreshId(profileId)
|
||||
}
|
||||
|
||||
override def onDetach() {
|
||||
|
||||
@@ -39,7 +39,7 @@ class ShadowsocksNotification(private val service: BaseService, profileName: Str
|
||||
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): Unit = () // ignore
|
||||
override def trafficUpdated(txRate: Long, rxRate: Long, txTotal: Long, rxTotal: Long) {
|
||||
override def trafficUpdated(profileId: Int, txRate: Long, rxRate: Long, txTotal: Long, rxTotal: Long) {
|
||||
val txr = TrafficMonitor.formatTraffic(txRate)
|
||||
val rxr = TrafficMonitor.formatTraffic(rxRate)
|
||||
builder.setContentText(service.getString(R.string.traffic_summary).formatLocal(Locale.ENGLISH, txr, rxr))
|
||||
@@ -47,6 +47,7 @@ class ShadowsocksNotification(private val service: BaseService, profileName: Str
|
||||
TrafficMonitor.formatTraffic(txTotal), TrafficMonitor.formatTraffic(rxTotal)))
|
||||
show()
|
||||
}
|
||||
override def trafficPersisted(profileId: Int): Unit = ()
|
||||
}
|
||||
private var lockReceiver: BroadcastReceiver = _
|
||||
private var callbackRegistered: Boolean = _
|
||||
|
||||
@@ -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): Unit = ()
|
||||
def trafficUpdated(profileId: Int, txRate: Long, rxRate: Long, txTotal: Long, rxTotal: Long): Unit = ()
|
||||
def stateChanged(state: Int, profileName: String, msg: String) {
|
||||
val tile = getQsTile
|
||||
if (tile != null) {
|
||||
@@ -57,6 +57,7 @@ final class ShadowsocksTileService extends TileService with ServiceBoundContext
|
||||
tile.updateTile()
|
||||
}
|
||||
}
|
||||
override def trafficPersisted(profileId: Int): Unit = ()
|
||||
}
|
||||
|
||||
override def onServiceConnected(): Unit = callback.stateChanged(bgService.getState, bgService.getProfileName, null)
|
||||
|
||||
@@ -35,5 +35,5 @@ class ToolbarFragment extends Fragment {
|
||||
if (activity.crossfader == null) activity.drawer.setToolbar(activity, toolbar, true)
|
||||
}
|
||||
|
||||
def onTrafficUpdated(txRate: Long, rxRate: Long, txTotal: Long, rxTotal: Long): Unit = ()
|
||||
def onTrafficUpdated(profileId: Int, txRate: Long, rxRate: Long, txTotal: Long, rxTotal: Long): Unit = ()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user