Code cleanup: Add TrackExporter interface

This commit is contained in:
Jimmy Shih
2013-08-28 15:25:55 -07:00
parent ee7376919e
commit b8bd8d62ce
6 changed files with 372 additions and 295 deletions
@@ -0,0 +1,278 @@
/*
* 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 com.google.android.apps.mytracks.io.file;
import com.google.android.apps.mytracks.Constants;
import com.google.android.apps.mytracks.content.MyTracksLocation;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils.LocationIterator;
import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.util.LocationUtils;
import com.google.common.annotations.VisibleForTesting;
import android.content.Context;
import android.database.Cursor;
import android.location.Location;
import android.util.Log;
import java.io.OutputStream;
/**
* Track Writer for writing tracks to an {@link OutputStream}.
*
* @author Sandor Dornbush
* @author Rodrigo Damazio
*/
public class FileTrackExporter implements TrackExporter {
private final static String TAG = FileTrackExporter.class.getSimpleName();
private final MyTracksProviderUtils myTracksProviderUtils;
private final Track[] tracks;
private final TrackWriter trackWriter;
private final TrackExporterListener trackExporterListener;
private Thread writeThread;
private boolean success = false;
/**
* Constructor.
*
* @param context the context
* @param myTracksProviderUtils the my tracks provider utils
* @param tracks the tracks
* @param trackFileFormat the track file format
* @param trackExporterListener the track export listener
*/
public FileTrackExporter(Context context, MyTracksProviderUtils myTracksProviderUtils,
Track[] tracks, TrackFileFormat trackFileFormat,
TrackExporterListener trackExporterListener) {
this(myTracksProviderUtils, tracks, trackFileFormat.newTrackWriter(context),
trackExporterListener);
}
@VisibleForTesting
public FileTrackExporter(MyTracksProviderUtils myTracksProviderUtils, Track[] tracks,
TrackWriter trackWriter, TrackExporterListener trackExporterListener) {
this.myTracksProviderUtils = myTracksProviderUtils;
this.tracks = tracks;
this.trackWriter = trackWriter;
this.trackExporterListener = trackExporterListener;
}
@Override
public boolean isSuccess() {
return success;
}
@Override
public void writeTrack(final OutputStream outputStream) {
writeThread = new Thread() {
@Override
public void run() {
try {
trackWriter.prepare(outputStream);
trackWriter.writeHeader(tracks[0]);
long startTime = tracks[0].getTripStatistics().getStartTime();
for (int i = 0; i < tracks.length; i++) {
writeWaypoints(tracks[i]);
long offset = tracks[i].getTripStatistics().getStartTime() - startTime;
writeLocations(tracks[i], offset);
}
trackWriter.writeFooter();
trackWriter.close();
success = true;
} catch (InterruptedException e) {
success = false;
}
}
};
writeThread.start();
try {
writeThread.join();
} catch (InterruptedException e) {
Log.e(TAG, "Interrupted while waiting for write to complete", e);
success = false;
}
}
@Override
public void stopWriteTrack() {
if (writeThread != null && writeThread.isAlive()) {
Log.i(TAG, "Attempting to stop track write");
writeThread.interrupt();
try {
writeThread.join();
Log.i(TAG, "Track write stopped");
} catch (InterruptedException e) {
Log.e(TAG, "Interrupted while waiting for writer to stop", e);
success = false;
}
}
}
/**
* Writes the waypoints.
*/
private void writeWaypoints(Track track) {
/*
* TODO: Stream through the waypoints in chunks. I am leaving the number of
* waypoints very high which should not be a problem because we don't try to
* load them into objects all at the same time.
*/
boolean hasWaypoints = false;
Cursor cursor = null;
try {
cursor = myTracksProviderUtils.getWaypointCursor(
track.getId(), -1L, Constants.MAX_LOADED_WAYPOINTS_POINTS);
if (cursor != null && cursor.moveToFirst()) {
/*
* Yes, this will skip the first waypoint and that is intentional as the
* first waypoint holds the stats for the track.
*/
while (cursor.moveToNext()) {
if (!hasWaypoints) {
trackWriter.writeBeginWaypoints();
hasWaypoints = true;
}
Waypoint waypoint = myTracksProviderUtils.createWaypoint(cursor);
trackWriter.writeWaypoint(waypoint);
}
}
} finally {
if (cursor != null) {
cursor.close();
}
}
if (hasWaypoints) {
trackWriter.writeEndWaypoints();
}
}
/**
* Writes the locations.
*/
private void writeLocations(Track track, long offset) throws InterruptedException {
boolean wroteTrack = false;
boolean wroteSegment = false;
boolean isLastLocationValid = false;
TrackWriterLocationFactory locationFactory = new TrackWriterLocationFactory();
LocationIterator iterator = myTracksProviderUtils.getTrackPointLocationIterator(
track.getId(), -1L, false, locationFactory);
try {
int locationNumber = 0;
while (iterator.hasNext()) {
Location location = iterator.next();
setLocationTime(location, offset);
if (Thread.interrupted()) {
throw new InterruptedException();
}
locationNumber++;
boolean isLocationValid = LocationUtils.isValidLocation(location);
boolean isSegmentValid = isLocationValid && isLastLocationValid;
if (!wroteTrack && isSegmentValid) {
// Found the first two consecutive locations that are valid
trackWriter.writeBeginTrack(track, locationFactory.lastLocation);
wroteTrack = true;
}
if (isSegmentValid) {
if (!wroteSegment) {
// Start a segment
trackWriter.writeOpenSegment();
wroteSegment = true;
// Write the previous location, which we had previously skipped
trackWriter.writeLocation(locationFactory.lastLocation);
}
// Write the current location
trackWriter.writeLocation(location);
if (trackExporterListener != null) {
trackExporterListener.onProgressUpdate(locationNumber, track.getNumberOfPoints());
}
} else {
if (wroteSegment) {
trackWriter.writeCloseSegment();
wroteSegment = false;
}
}
locationFactory.swapLocations();
isLastLocationValid = isLocationValid;
}
if (wroteSegment) {
trackWriter.writeCloseSegment();
wroteSegment = false;
}
if (wroteTrack) {
Location lastValidTrackPoint = myTracksProviderUtils.getLastValidTrackPoint(track.getId());
setLocationTime(lastValidTrackPoint, offset);
trackWriter.writeEndTrack(track, lastValidTrackPoint);
} else {
// Write an empty track
trackWriter.writeBeginTrack(track, null);
trackWriter.writeEndTrack(track, null);
}
} finally {
iterator.close();
}
}
/**
* Sets a location time.
*
* @param location the location
* @param offset the time offset
*/
private void setLocationTime(Location location, long offset) {
if (location != null) {
location.setTime(location.getTime() - offset);
}
}
/**
* Track writer location factory. Keeping the last two locations.
*
* @author Jimmy Shih
*/
private class TrackWriterLocationFactory implements MyTracksProviderUtils.LocationFactory {
Location currentLocation;
Location lastLocation;
@Override
public Location createLocation() {
if (currentLocation == null) {
currentLocation = new MyTracksLocation("");
}
return currentLocation;
}
public void swapLocations() {
Location tempLocation = lastLocation;
lastLocation = currentLocation;
currentLocation = tempLocation;
if (currentLocation != null) {
currentLocation.reset();
}
}
}
}
@@ -19,6 +19,7 @@ package com.google.android.apps.mytracks.io.file;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils; import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.Track; import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.content.TracksColumns; import com.google.android.apps.mytracks.content.TracksColumns;
import com.google.android.apps.mytracks.io.file.TrackExporter.TrackExporterListener;
import com.google.android.apps.mytracks.util.FileUtils; import com.google.android.apps.mytracks.util.FileUtils;
import com.google.android.apps.mytracks.util.PreferencesUtils; import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.apps.mytracks.util.SystemUtils; import com.google.android.apps.mytracks.util.SystemUtils;
@@ -52,7 +53,7 @@ public class SaveAsyncTask extends AsyncTask<Void, Integer, Boolean> {
private final MyTracksProviderUtils myTracksProviderUtils; private final MyTracksProviderUtils myTracksProviderUtils;
private WakeLock wakeLock; private WakeLock wakeLock;
private TrackExporter trackExporter; private FileTrackExporter fileTrackExporter;
// true if the AsyncTask has completed // true if the AsyncTask has completed
private boolean completed; private boolean completed;
@@ -163,8 +164,8 @@ public class SaveAsyncTask extends AsyncTask<Void, Integer, Boolean> {
@Override @Override
protected void onCancelled() { protected void onCancelled() {
if (trackExporter != null) { if (fileTrackExporter != null) {
trackExporter.stopWriteTrack(); fileTrackExporter.stopWriteTrack();
} }
} }
@@ -186,10 +187,11 @@ public class SaveAsyncTask extends AsyncTask<Void, Integer, Boolean> {
return false; return false;
} }
trackExporter = new TrackExporter( fileTrackExporter = new FileTrackExporter(
context, myTracksProviderUtils, tracks, trackFileFormat, new TrackExporter.OnWriteListener() { context, myTracksProviderUtils, tracks, trackFileFormat, new TrackExporterListener() {
@Override @Override
public void onWrite(int number, int max) { public void onProgressUpdate(int number, int max) {
/* /*
* If only saving one track, update the progress dialog once every * If only saving one track, update the progress dialog once every
* 500 points * 500 points
@@ -204,20 +206,20 @@ public class SaveAsyncTask extends AsyncTask<Void, Integer, Boolean> {
try { try {
file = new File(directory, fileName); file = new File(directory, fileName);
OutputStream outputStream = new FileOutputStream(file); OutputStream outputStream = new FileOutputStream(file);
trackExporter.writeTrack(outputStream); fileTrackExporter.writeTrack(outputStream);
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
Log.d(TAG, "File not found " + fileName, e); Log.d(TAG, "File not found " + fileName, e);
return false; return false;
} }
if (trackExporter.wasSuccess()) { if (fileTrackExporter.isSuccess()) {
savedPath = file.getAbsolutePath(); savedPath = file.getAbsolutePath();
} else { } else {
if (!file.delete()) { if (!file.delete()) {
Log.w(TAG, "Failed to delete file " + file.getAbsolutePath()); Log.w(TAG, "Failed to delete file " + file.getAbsolutePath());
} }
} }
return trackExporter.wasSuccess(); return fileTrackExporter.isSuccess();
} }
/** /**
@@ -16,284 +16,47 @@
package com.google.android.apps.mytracks.io.file; package com.google.android.apps.mytracks.io.file;
import com.google.android.apps.mytracks.Constants;
import com.google.android.apps.mytracks.content.MyTracksLocation;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils.LocationIterator;
import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.util.LocationUtils;
import com.google.common.annotations.VisibleForTesting;
import android.content.Context;
import android.database.Cursor;
import android.location.Location;
import android.util.Log;
import java.io.OutputStream; import java.io.OutputStream;
/** /**
* Track Writer for writing tracks to an {@link OutputStream}. * Track exporting for exporting track to an {@link OutputStream}.
* *
* @author Sandor Dornbush * @author Jimmy Shih
* @author Rodrigo Damazio
*/ */
public class TrackExporter { public interface TrackExporter {
/** /**
* Listener for when a track location is written. * Listener for {@link TrackExporter} progress.
*/
public interface OnWriteListener {
/**
* When a track location is written.
*
* @param number the location number
* @param max the maximum number of locations in a track, for calculation of completion
* percentage
*/
public void onWrite(int number, int max);
}
private final static String TAG = TrackExporter.class.getSimpleName();
private final MyTracksProviderUtils myTracksProviderUtils;
private final Track[] tracks;
private final TrackWriter trackWriter;
private final OnWriteListener onWriteListener;
private Thread writeThread;
private boolean success = false;
/**
* Constructor.
*
* @param context the context
* @param myTracksProviderUtils the my tracks provider utils
* @param tracks the tracks
* @param trackFileFormat the track file format
* @param onWriteListener the on write listener
*/
public TrackExporter(Context context, MyTracksProviderUtils myTracksProviderUtils, Track[] tracks,
TrackFileFormat trackFileFormat, OnWriteListener onWriteListener) {
this(myTracksProviderUtils, tracks, trackFileFormat.newTrackWriter(context), onWriteListener);
}
@VisibleForTesting
public TrackExporter(MyTracksProviderUtils myTracksProviderUtils, Track[] tracks,
TrackWriter trackWriter, OnWriteListener onWriteListener) {
this.myTracksProviderUtils = myTracksProviderUtils;
this.tracks = tracks;
this.trackWriter = trackWriter;
this.onWriteListener = onWriteListener;
}
/**
* Returns true if the write completed successfully.
*/
public boolean wasSuccess() {
return success;
}
/**
* Writes the given track to the output stream.
*
* @param outputStream the output stream.
*/
public void writeTrack(final OutputStream outputStream) {
writeThread = new Thread() {
@Override
public void run() {
try {
trackWriter.prepare(outputStream);
trackWriter.writeHeader(tracks[0]);
long startTime = tracks[0].getTripStatistics().getStartTime();
for (int i = 0; i < tracks.length; i++) {
writeWaypoints(tracks[i]);
long offset = tracks[i].getTripStatistics().getStartTime() - startTime;
writeLocations(tracks[i], offset);
}
trackWriter.writeFooter();
trackWriter.close();
success = true;
} catch (InterruptedException e) {
success = false;
}
}
};
writeThread.start();
try {
writeThread.join();
} catch (InterruptedException e) {
Log.e(TAG, "Interrupted while waiting for write to complete", e);
success = false;
}
}
/**
* Stops any in-progress writes.
*/
public void stopWriteTrack() {
if (writeThread != null && writeThread.isAlive()) {
Log.i(TAG, "Attempting to stop track write");
writeThread.interrupt();
try {
writeThread.join();
Log.i(TAG, "Track write stopped");
} catch (InterruptedException e) {
Log.e(TAG, "Interrupted while waiting for writer to stop", e);
success = false;
}
}
}
/**
* Writes the waypoints.
*/
private void writeWaypoints(Track track) {
/*
* TODO: Stream through the waypoints in chunks. I am leaving the number of
* waypoints very high which should not be a problem because we don't try to
* load them into objects all at the same time.
*/
boolean hasWaypoints = false;
Cursor cursor = null;
try {
cursor = myTracksProviderUtils.getWaypointCursor(
track.getId(), -1L, Constants.MAX_LOADED_WAYPOINTS_POINTS);
if (cursor != null && cursor.moveToFirst()) {
/*
* Yes, this will skip the first waypoint and that is intentional as the
* first waypoint holds the stats for the track.
*/
while (cursor.moveToNext()) {
if (!hasWaypoints) {
trackWriter.writeBeginWaypoints();
hasWaypoints = true;
}
Waypoint waypoint = myTracksProviderUtils.createWaypoint(cursor);
trackWriter.writeWaypoint(waypoint);
}
}
} finally {
if (cursor != null) {
cursor.close();
}
}
if (hasWaypoints) {
trackWriter.writeEndWaypoints();
}
}
/**
* Writes the locations.
*/
private void writeLocations(Track track, long offset) throws InterruptedException {
boolean wroteTrack = false;
boolean wroteSegment = false;
boolean isLastLocationValid = false;
TrackWriterLocationFactory locationFactory = new TrackWriterLocationFactory();
LocationIterator iterator = myTracksProviderUtils.getTrackPointLocationIterator(
track.getId(), -1L, false, locationFactory);
try {
int locationNumber = 0;
while (iterator.hasNext()) {
Location location = iterator.next();
setLocationTime(location, offset);
if (Thread.interrupted()) {
throw new InterruptedException();
}
locationNumber++;
boolean isLocationValid = LocationUtils.isValidLocation(location);
boolean isSegmentValid = isLocationValid && isLastLocationValid;
if (!wroteTrack && isSegmentValid) {
// Found the first two consecutive locations that are valid
trackWriter.writeBeginTrack(track, locationFactory.lastLocation);
wroteTrack = true;
}
if (isSegmentValid) {
if (!wroteSegment) {
// Start a segment
trackWriter.writeOpenSegment();
wroteSegment = true;
// Write the previous location, which we had previously skipped
trackWriter.writeLocation(locationFactory.lastLocation);
}
// Write the current location
trackWriter.writeLocation(location);
if (onWriteListener != null) {
onWriteListener.onWrite(locationNumber, track.getNumberOfPoints());
}
} else {
if (wroteSegment) {
trackWriter.writeCloseSegment();
wroteSegment = false;
}
}
locationFactory.swapLocations();
isLastLocationValid = isLocationValid;
}
if (wroteSegment) {
trackWriter.writeCloseSegment();
wroteSegment = false;
}
if (wroteTrack) {
Location lastValidTrackPoint = myTracksProviderUtils.getLastValidTrackPoint(track.getId());
setLocationTime(lastValidTrackPoint, offset);
trackWriter.writeEndTrack(track, lastValidTrackPoint);
} else {
// Write an empty track
trackWriter.writeBeginTrack(track, null);
trackWriter.writeEndTrack(track, null);
}
} finally {
iterator.close();
}
}
/**
* Sets a location time.
*
* @param location the location
* @param offset the time offset
*/
private void setLocationTime(Location location, long offset) {
if (location != null) {
location.setTime(location.getTime() - offset);
}
}
/**
* Track writer location factory. Keeping the last two locations.
* *
* @author Jimmy Shih * @author Jimmy Shih
*/ */
private class TrackWriterLocationFactory implements MyTracksProviderUtils.LocationFactory { interface TrackExporterListener {
Location currentLocation;
Location lastLocation;
@Override /**
public Location createLocation() { * Called to update progress.
if (currentLocation == null) { *
currentLocation = new MyTracksLocation(""); * @param number the number of locations written
} * @param max the maximum number of locations in a track, for calculation of
return currentLocation; * completion percentage
} */
void onProgressUpdate(int number, int max);
public void swapLocations() {
Location tempLocation = lastLocation;
lastLocation = currentLocation;
currentLocation = tempLocation;
if (currentLocation != null) {
currentLocation.reset();
}
}
} }
/**
* Write track to an output stream
*
* @param outputStream the output stream
*/
void writeTrack(OutputStream outputStream);
/**
* Stops {@link #writeTrack(OutputStream)}.
*/
void stopWriteTrack();
/**
* Returns true if {@link #writeTrack(OutputStream)} completed successfully.
*/
boolean isSuccess();
} }
@@ -0,0 +1,33 @@
/*
* Copyright 2010 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 com.google.android.apps.mytracks.io.file;
/**
* Listener for {@link TrackExporter} progress.
*
* @author Jimmy Shih
*/
public interface TrackExporterListener {
/**
* Called to update progress.
*
* @param number the number of locations written
* @param max the maximum number of locations in a track, for calculation of
* completion percentage
*/
public void onProgressUpdate(int number, int max);
}
@@ -20,8 +20,8 @@ import com.google.android.apps.mytracks.Constants;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils; import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.Track; import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.content.TracksColumns; import com.google.android.apps.mytracks.content.TracksColumns;
import com.google.android.apps.mytracks.io.file.FileTrackExporter;
import com.google.android.apps.mytracks.io.file.TrackFileFormat; import com.google.android.apps.mytracks.io.file.TrackFileFormat;
import com.google.android.apps.mytracks.io.file.TrackExporter;
import com.google.android.apps.mytracks.util.FileUtils; import com.google.android.apps.mytracks.util.FileUtils;
import com.google.android.apps.mytracks.util.PreferencesUtils; import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.maps.mytracks.R; import com.google.android.maps.mytracks.R;
@@ -441,11 +441,11 @@ public class SyncUtils {
java.io.File file = new java.io.File(directory, java.io.File file = new java.io.File(directory,
FileUtils.buildUniqueFileName(directory, track.getName(), trackFileFormat.getExtension())); FileUtils.buildUniqueFileName(directory, track.getName(), trackFileFormat.getExtension()));
TrackExporter trackExporter = new TrackExporter( FileTrackExporter fileTrackExporter = new FileTrackExporter(
context, myTracksProviderUtils, new Track[] {track}, trackFileFormat, null); context, myTracksProviderUtils, new Track[] {track}, trackFileFormat, null);
trackExporter.writeTrack(new FileOutputStream(file)); fileTrackExporter.writeTrack(new FileOutputStream(file));
if (trackExporter.wasSuccess()) { if (fileTrackExporter.isSuccess()) {
return file; return file;
} }
Log.d(TAG, "Unable to get file for track " + track.getName()); Log.d(TAG, "Unable to get file for track " + track.getName());
@@ -7,7 +7,7 @@ import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils.Factory; import com.google.android.apps.mytracks.content.MyTracksProviderUtils.Factory;
import com.google.android.apps.mytracks.content.Track; import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.content.Waypoint; import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.io.file.TrackExporter.OnWriteListener; import com.google.android.apps.mytracks.io.file.TrackExporter.TrackExporterListener;
import com.google.android.apps.mytracks.services.TrackRecordingServiceTest.MockContext; import com.google.android.apps.mytracks.services.TrackRecordingServiceTest.MockContext;
import com.google.android.apps.mytracks.testing.TestingProviderUtilsFactory; import com.google.android.apps.mytracks.testing.TestingProviderUtilsFactory;
@@ -25,11 +25,11 @@ import org.easymock.IArgumentMatcher;
import org.easymock.IMocksControl; import org.easymock.IMocksControl;
/** /**
* Tests for {@link TrackExporter}. * Tests for {@link FileTrackExporter}.
* *
* @author Rodrigo Damazio * @author Rodrigo Damazio
*/ */
public class TrackExporterTest extends AndroidTestCase { public class FileTrackExporterTest extends AndroidTestCase {
private static final long TRACK_ID = 1234567L; private static final long TRACK_ID = 1234567L;
private static final String TRACK_NAME = "Swimming across the pacific"; private static final String TRACK_NAME = "Swimming across the pacific";
@@ -42,7 +42,7 @@ public class TrackExporterTest extends AndroidTestCase {
private TrackWriter trackWriter; private TrackWriter trackWriter;
private Track track; private Track track;
private OutputStream outputStream; private OutputStream outputStream;
private TrackExporter trackExporter; private FileTrackExporter fileTrackExporter;
@Override @Override
protected void setUp() throws Exception { protected void setUp() throws Exception {
@@ -68,15 +68,16 @@ public class TrackExporterTest extends AndroidTestCase {
track.setId(TRACK_ID); track.setId(TRACK_ID);
outputStream = new ByteArrayOutputStream(); outputStream = new ByteArrayOutputStream();
OnWriteListener onWriteListener = new OnWriteListener() { TrackExporterListener trackExporterListener = new TrackExporterListener() {
@Override @Override
public void onWrite(int number, int max) { public void onProgressUpdate(int number, int max) {
// Safe to ignore // Safe to ignore
} }
}; };
trackExporter = new TrackExporter(myTracksProviderUtils, new Track[] {track}, trackWriter, onWriteListener); fileTrackExporter = new FileTrackExporter(
myTracksProviderUtils, new Track[] { track }, trackWriter, trackExporterListener);
} }
@Override @Override
@@ -99,9 +100,9 @@ public class TrackExporterTest extends AndroidTestCase {
trackWriter.close(); trackWriter.close();
mocksControl.replay(); mocksControl.replay();
trackExporter.writeTrack(outputStream); fileTrackExporter.writeTrack(outputStream);
assertTrue(trackExporter.wasSuccess()); assertTrue(fileTrackExporter.isSuccess());
mocksControl.verify(); mocksControl.verify();
} }
@@ -131,9 +132,9 @@ public class TrackExporterTest extends AndroidTestCase {
trackWriter.close(); trackWriter.close();
mocksControl.replay(); mocksControl.replay();
trackExporter.writeTrack(outputStream); fileTrackExporter.writeTrack(outputStream);
assertTrue(trackExporter.wasSuccess()); assertTrue(fileTrackExporter.isSuccess());
mocksControl.verify(); mocksControl.verify();
} }
@@ -196,9 +197,9 @@ public class TrackExporterTest extends AndroidTestCase {
trackWriter.close(); trackWriter.close();
mocksControl.replay(); mocksControl.replay();
trackExporter.writeTrack(outputStream); fileTrackExporter.writeTrack(outputStream);
assertTrue(trackExporter.wasSuccess()); assertTrue(fileTrackExporter.isSuccess());
mocksControl.verify(); mocksControl.verify();
} }