You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
304 lines
8.3 KiB
304 lines
8.3 KiB
/*
|
|
This file is part of Libresonic.
|
|
|
|
Libresonic is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
Libresonic is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with Libresonic. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
Copyright 2016 (C) Libresonic Authors
|
|
Based upon Subsonic, Copyright 2009 (C) Sindre Mehus
|
|
*/
|
|
package org.libresonic.player.domain;
|
|
|
|
import org.libresonic.player.util.BoundedList;
|
|
|
|
import java.io.File;
|
|
|
|
/**
|
|
* Status for a single transfer (stream, download or upload).
|
|
*
|
|
* @author Sindre Mehus
|
|
*/
|
|
public class TransferStatus {
|
|
|
|
private static final int HISTORY_LENGTH = 200;
|
|
private static final long SAMPLE_INTERVAL_MILLIS = 5000;
|
|
|
|
private Player player;
|
|
private File file;
|
|
private long bytesTransfered;
|
|
private long bytesSkipped;
|
|
private long bytesTotal;
|
|
private final SampleHistory history = new SampleHistory();
|
|
private boolean terminated;
|
|
private boolean active = true;
|
|
|
|
/**
|
|
* Return the number of bytes transferred.
|
|
*
|
|
* @return The number of bytes transferred.
|
|
*/
|
|
public synchronized long getBytesTransfered() {
|
|
return bytesTransfered;
|
|
}
|
|
|
|
/**
|
|
* Adds the given byte count to the total number of bytes transferred.
|
|
*
|
|
* @param byteCount The byte count.
|
|
*/
|
|
public synchronized void addBytesTransfered(long byteCount) {
|
|
setBytesTransfered(bytesTransfered + byteCount);
|
|
}
|
|
|
|
/**
|
|
* Sets the number of bytes transferred.
|
|
*
|
|
* @param bytesTransfered The number of bytes transferred.
|
|
*/
|
|
public synchronized void setBytesTransfered(long bytesTransfered) {
|
|
this.bytesTransfered = bytesTransfered;
|
|
createSample(bytesTransfered, false);
|
|
}
|
|
|
|
private void createSample(long bytesTransfered, boolean force) {
|
|
long now = System.currentTimeMillis();
|
|
|
|
if (history.isEmpty()) {
|
|
history.add(new Sample(bytesTransfered, now));
|
|
} else {
|
|
Sample lastSample = history.getLast();
|
|
if (force || now - lastSample.getTimestamp() > TransferStatus.SAMPLE_INTERVAL_MILLIS) {
|
|
history.add(new Sample(bytesTransfered, now));
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the number of milliseconds since the transfer status was last updated.
|
|
*
|
|
* @return Number of milliseconds, or <code>0</code> if never updated.
|
|
*/
|
|
public synchronized long getMillisSinceLastUpdate() {
|
|
if (history.isEmpty()) {
|
|
return 0L;
|
|
}
|
|
return System.currentTimeMillis() - history.getLast().timestamp;
|
|
}
|
|
|
|
/**
|
|
* Returns the total number of bytes, or 0 if unknown.
|
|
*
|
|
* @return The total number of bytes, or 0 if unknown.
|
|
*/
|
|
public long getBytesTotal() {
|
|
return bytesTotal;
|
|
}
|
|
|
|
/**
|
|
* Sets the total number of bytes, or 0 if unknown.
|
|
*
|
|
* @param bytesTotal The total number of bytes, or 0 if unknown.
|
|
*/
|
|
public void setBytesTotal(long bytesTotal) {
|
|
this.bytesTotal = bytesTotal;
|
|
}
|
|
|
|
/**
|
|
* Returns the number of bytes that has been skipped (for instance when
|
|
* resuming downloads).
|
|
*
|
|
* @return The number of skipped bytes.
|
|
*/
|
|
public synchronized long getBytesSkipped() {
|
|
return bytesSkipped;
|
|
}
|
|
|
|
/**
|
|
* Sets the number of bytes that has been skipped (for instance when
|
|
* resuming downloads).
|
|
*
|
|
* @param bytesSkipped The number of skipped bytes.
|
|
*/
|
|
public synchronized void setBytesSkipped(long bytesSkipped) {
|
|
this.bytesSkipped = bytesSkipped;
|
|
}
|
|
|
|
|
|
/**
|
|
* Adds the given byte count to the total number of bytes skipped.
|
|
*
|
|
* @param byteCount The byte count.
|
|
*/
|
|
public synchronized void addBytesSkipped(long byteCount) {
|
|
bytesSkipped += byteCount;
|
|
}
|
|
|
|
/**
|
|
* Returns the file that is currently being transferred.
|
|
*
|
|
* @return The file that is currently being transferred.
|
|
*/
|
|
public synchronized File getFile() {
|
|
return file;
|
|
}
|
|
|
|
/**
|
|
* Sets the file that is currently being transferred.
|
|
*
|
|
* @param file The file that is currently being transferred.
|
|
*/
|
|
public synchronized void setFile(File file) {
|
|
this.file = file;
|
|
}
|
|
|
|
/**
|
|
* Returns the remote player for the stream.
|
|
*
|
|
* @return The remote player for the stream.
|
|
*/
|
|
public synchronized Player getPlayer() {
|
|
return player;
|
|
}
|
|
|
|
/**
|
|
* Sets the remote player for the stream.
|
|
*
|
|
* @param player The remote player for the stream.
|
|
*/
|
|
public synchronized void setPlayer(Player player) {
|
|
this.player = player;
|
|
}
|
|
|
|
/**
|
|
* Returns a history of samples for the stream
|
|
*
|
|
* @return A (copy of) the history list of samples.
|
|
*/
|
|
public synchronized SampleHistory getHistory() {
|
|
return new SampleHistory(history);
|
|
}
|
|
|
|
/**
|
|
* Returns the history length in milliseconds.
|
|
*
|
|
* @return The history length in milliseconds.
|
|
*/
|
|
public long getHistoryLengthMillis() {
|
|
return TransferStatus.SAMPLE_INTERVAL_MILLIS * (TransferStatus.HISTORY_LENGTH - 1);
|
|
}
|
|
|
|
/**
|
|
* Indicate that the stream should be terminated.
|
|
*/
|
|
public void terminate() {
|
|
terminated = true;
|
|
}
|
|
|
|
/**
|
|
* Returns whether this stream has been terminated.
|
|
* Not that the <em>terminated status</em> is cleared by this method.
|
|
*
|
|
* @return Whether this stream has been terminated.
|
|
*/
|
|
public boolean terminated() {
|
|
boolean result = terminated;
|
|
terminated = false;
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Returns whether this transfer is active, i.e., if the connection is still established.
|
|
*
|
|
* @return Whether this transfer is active.
|
|
*/
|
|
public boolean isActive() {
|
|
return active;
|
|
}
|
|
|
|
/**
|
|
* Sets whether this transfer is active, i.e., if the connection is still established.
|
|
*
|
|
* @param active Whether this transfer is active.
|
|
*/
|
|
public void setActive(boolean active) {
|
|
this.active = active;
|
|
|
|
if (active) {
|
|
setBytesSkipped(0L);
|
|
setBytesTotal(0L);
|
|
setBytesTransfered(0L);
|
|
} else {
|
|
createSample(getBytesTransfered(), true);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* A sample containing a timestamp and the number of bytes transferred up to that point in time.
|
|
*/
|
|
public static class Sample {
|
|
private long bytesTransfered;
|
|
private long timestamp;
|
|
|
|
/**
|
|
* Creates a new sample.
|
|
*
|
|
* @param bytesTransfered The total number of bytes transferred.
|
|
* @param timestamp A point in time, in milliseconds.
|
|
*/
|
|
public Sample(long bytesTransfered, long timestamp) {
|
|
this.bytesTransfered = bytesTransfered;
|
|
this.timestamp = timestamp;
|
|
}
|
|
|
|
/**
|
|
* Returns the number of bytes transferred.
|
|
*
|
|
* @return The number of bytes transferred.
|
|
*/
|
|
public long getBytesTransfered() {
|
|
return bytesTransfered;
|
|
}
|
|
|
|
/**
|
|
* Returns the timestamp of the sample.
|
|
*
|
|
* @return The timestamp in milliseconds.
|
|
*/
|
|
public long getTimestamp() {
|
|
return timestamp;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
StringBuilder builder = new StringBuilder();
|
|
builder.append("TransferStatus-").append(hashCode()).append(" [player: ").append(player.getId()).append(", file: ");
|
|
builder.append(file).append(", terminated: ").append(terminated).append(", active: ").append(active).append("]");
|
|
return builder.toString();
|
|
}
|
|
|
|
/**
|
|
* Contains recent history of samples.
|
|
*/
|
|
public static class SampleHistory extends BoundedList<Sample> {
|
|
|
|
public SampleHistory() {
|
|
super(HISTORY_LENGTH);
|
|
}
|
|
|
|
public SampleHistory(SampleHistory other) {
|
|
super(HISTORY_LENGTH);
|
|
addAll(other);
|
|
}
|
|
}
|
|
}
|
|
|