TrackDataHub handles listeners itself.
This commit is contained in:
Dennis Guse
2021-05-24 09:10:13 +02:00
parent 4171d9cc4c
commit d6f4d3f599
4 changed files with 34 additions and 136 deletions
@@ -29,6 +29,7 @@ import androidx.annotation.VisibleForTesting;
import java.io.IOException; import java.io.IOException;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet;
import java.util.Set; import java.util.Set;
import de.dennisguse.opentracks.content.data.Altitude; import de.dennisguse.opentracks.content.data.Altitude;
@@ -71,7 +72,7 @@ public class TrackDataHub {
private static final String TAG = TrackDataHub.class.getSimpleName(); private static final String TAG = TrackDataHub.class.getSimpleName();
private final Context context; private final Context context;
private final TrackDataManager trackDataManager; private final Set<TrackDataListener> listeners;
private final ContentProviderUtils contentProviderUtils; private final ContentProviderUtils contentProviderUtils;
private final int targetNumPoints; private final int targetNumPoints;
@@ -100,13 +101,13 @@ public class TrackDataHub {
private ContentObserver trackPointsTableObserver; private ContentObserver trackPointsTableObserver;
public TrackDataHub(Context context) { public TrackDataHub(Context context) {
this(context, new TrackDataManager(), new ContentProviderUtils(context), TARGET_DISPLAYED_TRACKPOINTS); this(context, new ContentProviderUtils(context), TARGET_DISPLAYED_TRACKPOINTS);
} }
@VisibleForTesting @VisibleForTesting
private TrackDataHub(Context context, TrackDataManager trackDataManager, ContentProviderUtils contentProviderUtils, int targetNumPoints) { private TrackDataHub(Context context, ContentProviderUtils contentProviderUtils, int targetNumPoints) {
this.context = context; this.context = context;
this.trackDataManager = trackDataManager; this.listeners = new HashSet<>();
this.contentProviderUtils = contentProviderUtils; this.contentProviderUtils = contentProviderUtils;
this.targetNumPoints = targetNumPoints; this.targetNumPoints = targetNumPoints;
resetSamplingState(); resetSamplingState();
@@ -127,7 +128,7 @@ public class TrackDataHub {
tracksTableObserver = new ContentObserver(handler) { tracksTableObserver = new ContentObserver(handler) {
@Override @Override
public void onChange(boolean selfChange) { public void onChange(boolean selfChange) {
notifyTracksTableUpdate(trackDataManager.getListenerTracks()); notifyTracksTableUpdate(listeners);
} }
}; };
contentResolver.registerContentObserver(TracksColumns.CONTENT_URI, false, tracksTableObserver); contentResolver.registerContentObserver(TracksColumns.CONTENT_URI, false, tracksTableObserver);
@@ -135,7 +136,7 @@ public class TrackDataHub {
markersTableObserver = new ContentObserver(handler) { markersTableObserver = new ContentObserver(handler) {
@Override @Override
public void onChange(boolean selfChange) { public void onChange(boolean selfChange) {
notifyMarkersTableUpdate(trackDataManager.getListenerMarkers()); notifyMarkersTableUpdate(listeners);
} }
}; };
contentResolver.registerContentObserver(MarkerColumns.CONTENT_URI, false, markersTableObserver); contentResolver.registerContentObserver(MarkerColumns.CONTENT_URI, false, markersTableObserver);
@@ -143,7 +144,7 @@ public class TrackDataHub {
trackPointsTableObserver = new ContentObserver(handler) { trackPointsTableObserver = new ContentObserver(handler) {
@Override @Override
public void onChange(boolean selfChange) { public void onChange(boolean selfChange) {
notifyTrackPointsTableUpdate(true, trackDataManager.getListenerTrackPoints_SampledIn(), trackDataManager.getListenerTrackPoints_SampledOut()); notifyTrackPointsTableUpdate(true, listeners);
} }
}; };
contentResolver.registerContentObserver(TrackPointsColumns.CONTENT_URI_BY_ID, false, trackPointsTableObserver); contentResolver.registerContentObserver(TrackPointsColumns.CONTENT_URI_BY_ID, false, trackPointsTableObserver);
@@ -187,9 +188,9 @@ public class TrackDataHub {
* *
* @param trackDataListener the track data listener * @param trackDataListener the track data listener
*/ */
public void registerTrackDataListener(final TrackDataListener trackDataListener, final boolean tracksTable, final boolean markersTable, final boolean trackPointsTable_SampleIn, final boolean trackPointsTable_SampleOut) { public void registerTrackDataListener(final TrackDataListener trackDataListener) {
handler.post(() -> { handler.post(() -> {
trackDataManager.registerTrackDataListener(trackDataListener, tracksTable, markersTable, trackPointsTable_SampleIn, trackPointsTable_SampleOut); listeners.add(trackDataListener);
if (started) { if (started) {
loadDataForListener(trackDataListener); loadDataForListener(trackDataListener);
} }
@@ -202,7 +203,7 @@ public class TrackDataHub {
* @param trackDataListener the track data listener * @param trackDataListener the track data listener
*/ */
public void unregisterTrackDataListener(final TrackDataListener trackDataListener) { public void unregisterTrackDataListener(final TrackDataListener trackDataListener) {
handler.post(() -> trackDataManager.unregisterTrackDataListener(trackDataListener)); handler.post(() -> listeners.remove(trackDataListener));
} }
/** /**
@@ -224,17 +225,17 @@ public class TrackDataHub {
*/ */
private void loadDataForAll() { private void loadDataForAll() {
resetSamplingState(); resetSamplingState();
if (!trackDataManager.hasListeners()) { if (listeners.isEmpty()) {
return; return;
} }
notifyTracksTableUpdate(trackDataManager.getListenerTracks()); notifyTracksTableUpdate(listeners);
for (TrackDataListener listener : trackDataManager.getListenerTrackPoints_SampledIn()) { for (TrackDataListener listener : listeners) {
listener.clearTrackPoints(); listener.clearTrackPoints();
} }
notifyTrackPointsTableUpdate(true, trackDataManager.getListenerTrackPoints_SampledIn(), trackDataManager.getListenerTrackPoints_SampledOut()); notifyTrackPointsTableUpdate(true, listeners);
notifyMarkersTableUpdate(trackDataManager.getListenerMarkers()); notifyMarkersTableUpdate(listeners);
} }
/** /**
@@ -245,25 +246,19 @@ public class TrackDataHub {
private void loadDataForListener(TrackDataListener trackDataListener) { private void loadDataForListener(TrackDataListener trackDataListener) {
Set<TrackDataListener> trackDataListeners = Collections.singleton(trackDataListener); Set<TrackDataListener> trackDataListeners = Collections.singleton(trackDataListener);
if (trackDataManager.listensForTracks(trackDataListener)) { //Track
notifyTracksTableUpdate(trackDataListeners); notifyTracksTableUpdate(trackDataListeners);
}
boolean hasSampledIn = trackDataManager.listensForTrackPoints_SampledIn(trackDataListener); //TrackPoints
boolean hasSampledOut = trackDataManager.listensForTrackPoints_SampledOut(trackDataListener); trackDataListener.clearTrackPoints();
if (hasSampledIn || hasSampledOut) { boolean isOnlyListener = listeners.size() == 1;
trackDataListener.clearTrackPoints(); if (isOnlyListener) {
boolean isOnlyListener = trackDataManager.getNumberOfListeners() == 1; resetSamplingState();
if (isOnlyListener) {
resetSamplingState();
}
Set<TrackDataListener> sampledOutListeners = hasSampledOut ? trackDataListeners : Collections.emptySet();
notifyTrackPointsTableUpdate(isOnlyListener, trackDataListeners, sampledOutListeners);
} }
notifyTrackPointsTableUpdate(isOnlyListener, trackDataListeners);
if (trackDataManager.listensForMarkers(trackDataListener)) { //Markers
notifyMarkersTableUpdate(trackDataListeners); notifyMarkersTableUpdate(trackDataListeners);
}
} }
/** /**
@@ -316,11 +311,9 @@ public class TrackDataHub {
* Notifies track points table update; to be run in the {@link #handler} thread. * Notifies track points table update; to be run in the {@link #handler} thread.
* *
* @param updateSamplingState true to update the sampling state * @param updateSamplingState true to update the sampling state
* @param sampledInListeners the sampled-in listeners
* @param sampledOutListeners the sampled-out listeners
*/ */
private void notifyTrackPointsTableUpdate(boolean updateSamplingState, Set<TrackDataListener> sampledInListeners, Set<TrackDataListener> sampledOutListeners) { private void notifyTrackPointsTableUpdate(boolean updateSamplingState, Set<TrackDataListener> listeners) {
if (sampledInListeners.isEmpty() && sampledOutListeners.isEmpty()) { if (listeners.isEmpty()) {
return; return;
} }
@@ -328,7 +321,7 @@ public class TrackDataHub {
// Reload and resample the track at a lower frequency. // Reload and resample the track at a lower frequency.
Log.i(TAG, "Resampling track after " + numLoadedPoints + " points."); Log.i(TAG, "Resampling track after " + numLoadedPoints + " points.");
resetSamplingState(); resetSamplingState();
for (TrackDataListener listener : sampledInListeners) { for (TrackDataListener listener : listeners) {
listener.clearTrackPoints(); listener.clearTrackPoints();
} }
} }
@@ -384,11 +377,11 @@ public class TrackDataHub {
// Also include the last point if the selected track is not recording. // Also include the last point if the selected track is not recording.
if ((localNumLoadedTrackPoints % samplingFrequency == 0) || (trackPointId == lastTrackPointId && !isSelectedTrackRecording())) { if ((localNumLoadedTrackPoints % samplingFrequency == 0) || (trackPointId == lastTrackPointId && !isSelectedTrackRecording())) {
for (TrackDataListener trackDataListener : sampledInListeners) { for (TrackDataListener trackDataListener : listeners) {
trackDataListener.onSampledInTrackPoint(trackPoint, currentUpdater.getTrackStatistics(), currentUpdater.getSmoothedSpeed(), currentUpdater.getSmoothedAltitude()); trackDataListener.onSampledInTrackPoint(trackPoint, currentUpdater.getTrackStatistics(), currentUpdater.getSmoothedSpeed(), currentUpdater.getSmoothedAltitude());
} }
} else { } else {
for (TrackDataListener trackDataListener : sampledOutListeners) { for (TrackDataListener trackDataListener : listeners) {
trackDataListener.onSampledOutTrackPoint(trackPoint, currentUpdater.getTrackStatistics()); trackDataListener.onSampledOutTrackPoint(trackPoint, currentUpdater.getTrackStatistics());
} }
} }
@@ -407,7 +400,7 @@ public class TrackDataHub {
lastSeenTrackPointId = localLastSeenTrackPointIdId; lastSeenTrackPointId = localLastSeenTrackPointIdId;
} }
sampledInListeners.stream().forEach(TrackDataListener::onNewTrackPointsDone); listeners.stream().forEach(TrackDataListener::onNewTrackPointsDone);
} }
private void correctAltitude(TrackPoint trackPoint) { private void correctAltitude(TrackPoint trackPoint) {
@@ -1,95 +0,0 @@
/*
* Copyright 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package de.dennisguse.opentracks.content;
import java.util.HashSet;
import java.util.Set;
/**
* Manages register/unregister {@link TrackDataListener} and keeping the state for each registered listener.
*
* @author Rodrigo Damazio
*/
class TrackDataManager {
private static final String TAG = TrackDataManager.class.getSimpleName();
private final Set<TrackDataListener> dataListenerTracks = new HashSet<>();
private final Set<TrackDataListener> dataListenerMarkers = new HashSet<>();
private final Set<TrackDataListener> dataListenerTrackPoints_SampledIn = new HashSet<>();
private final Set<TrackDataListener> dataListenerTrackPoints_SampledOut = new HashSet<>();
void registerTrackDataListener(final TrackDataListener trackDataListener, boolean tracksTable, boolean markersTable, boolean trackPointsTable_SampleIn, boolean trackPointsTable_SampleOut) {
if (tracksTable) dataListenerTracks.add(trackDataListener);
if (markersTable) dataListenerMarkers.add(trackDataListener);
if (trackPointsTable_SampleIn) dataListenerTrackPoints_SampledIn.add(trackDataListener);
if (trackPointsTable_SampleOut) dataListenerTrackPoints_SampledOut.add(trackDataListener);
}
void unregisterTrackDataListener(TrackDataListener trackDataListener) {
dataListenerTracks.remove(trackDataListener);
dataListenerMarkers.remove(trackDataListener);
dataListenerTrackPoints_SampledIn.remove(trackDataListener);
dataListenerTrackPoints_SampledOut.remove(trackDataListener);
}
boolean hasListeners() {
return dataListenerTracks.size() + dataListenerMarkers.size() + dataListenerTrackPoints_SampledIn.size() + dataListenerTrackPoints_SampledOut.size() > 0;
}
int getNumberOfListeners() {
Set<TrackDataListener> listener = new HashSet<>();
listener.addAll(dataListenerTracks);
listener.addAll(dataListenerMarkers);
listener.addAll(dataListenerTrackPoints_SampledIn);
listener.addAll(dataListenerTrackPoints_SampledOut);
return listener.size();
}
boolean listensForTracks(TrackDataListener listener) {
return dataListenerTracks.contains(listener);
}
boolean listensForMarkers(TrackDataListener listener) {
return dataListenerMarkers.contains(listener);
}
boolean listensForTrackPoints_SampledIn(TrackDataListener listener) {
return dataListenerTrackPoints_SampledIn.contains(listener);
}
boolean listensForTrackPoints_SampledOut(TrackDataListener listener) {
return dataListenerTrackPoints_SampledOut.contains(listener);
}
Set<TrackDataListener> getListenerTracks() {
return dataListenerTracks;
}
Set<TrackDataListener> getListenerMarkers() {
return dataListenerMarkers;
}
Set<TrackDataListener> getListenerTrackPoints_SampledIn() {
return dataListenerTrackPoints_SampledIn;
}
Set<TrackDataListener> getListenerTrackPoints_SampledOut() {
return dataListenerTrackPoints_SampledOut;
}
}
@@ -250,7 +250,7 @@ public class ChartFragment extends Fragment implements TrackDataListener {
*/ */
private synchronized void resumeTrackDataHub() { private synchronized void resumeTrackDataHub() {
trackDataHub = ((TrackActivityDataHubInterface) getActivity()).getTrackDataHub(); trackDataHub = ((TrackActivityDataHubInterface) getActivity()).getTrackDataHub();
trackDataHub.registerTrackDataListener(this, true, true, true, true); trackDataHub.registerTrackDataListener(this);
} }
/** /**
@@ -194,7 +194,7 @@ public class IntervalsFragment extends Fragment implements TrackDataListener {
*/ */
private synchronized void resumeTrackDataHub() { private synchronized void resumeTrackDataHub() {
trackDataHub = ((TrackActivityDataHubInterface) getActivity()).getTrackDataHub(); trackDataHub = ((TrackActivityDataHubInterface) getActivity()).getTrackDataHub();
trackDataHub.registerTrackDataListener(this, true, false, true, true); trackDataHub.registerTrackDataListener(this);
} }
/** /**