660
demo/assets/ic_launcher.svg
Normal file
After Width: | Height: | Size: 31 KiB |
665
demo/assets/ic_launcher.svg~
Normal file
After Width: | Height: | Size: 31 KiB |
@ -29,6 +29,7 @@
|
|||||||
|
|
||||||
<application
|
<application
|
||||||
android:label="@string/application_name"
|
android:label="@string/application_name"
|
||||||
|
android:icon="@drawable/ic_launcher"
|
||||||
android:largeHeap="true"
|
android:largeHeap="true"
|
||||||
android:allowBackup="false">
|
android:allowBackup="false">
|
||||||
|
|
||||||
|
BIN
demo/src/main/res/drawable-hdpi/ic_launcher.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
demo/src/main/res/drawable-mdpi/ic_launcher.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
demo/src/main/res/drawable-xhdpi/ic_launcher.png
Normal file
After Width: | Height: | Size: 4.1 KiB |
BIN
demo/src/main/res/drawable-xxhdpi/ic_launcher.png
Normal file
After Width: | Height: | Size: 6.7 KiB |
BIN
demo/src/main/res/drawable-xxxhdpi/ic_launcher.png
Normal file
After Width: | Height: | Size: 9.6 KiB |
@ -14,6 +14,7 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:id="@+id/root"
|
android:id="@+id/root"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
@ -49,14 +50,16 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:paddingLeft="4dp"
|
android:paddingLeft="4dp"
|
||||||
android:paddingRight="4dp"
|
android:paddingRight="4dp"
|
||||||
android:textSize="10sp"/>
|
android:textSize="10sp"
|
||||||
|
tools:ignore="SmallSp"/>
|
||||||
|
|
||||||
<TextView android:id="@+id/debug_text_view"
|
<TextView android:id="@+id/debug_text_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:paddingLeft="4dp"
|
android:paddingLeft="4dp"
|
||||||
android:paddingRight="4dp"
|
android:paddingRight="4dp"
|
||||||
android:textSize="10sp"/>
|
android:textSize="10sp"
|
||||||
|
tools:ignore="SmallSp"/>
|
||||||
|
|
||||||
<LinearLayout android:id="@+id/controls_root"
|
<LinearLayout android:id="@+id/controls_root"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -199,11 +199,9 @@ public final class Ac3PassthroughAudioTrackRenderer extends TrackRenderer {
|
|||||||
|
|
||||||
int result =
|
int result =
|
||||||
source.readData(trackIndex, currentPositionUs, formatHolder, sampleHolder, false);
|
source.readData(trackIndex, currentPositionUs, formatHolder, sampleHolder, false);
|
||||||
sampleHolder.data.flip();
|
|
||||||
shouldReadInputBuffer = false;
|
|
||||||
|
|
||||||
if (result == SampleSource.FORMAT_READ) {
|
if (result == SampleSource.FORMAT_READ) {
|
||||||
format = formatHolder.format;
|
format = formatHolder.format;
|
||||||
|
audioTrack.reconfigure(format.getFrameworkMediaFormatV16(), AudioFormat.ENCODING_AC3, 0);
|
||||||
}
|
}
|
||||||
if (result == SampleSource.END_OF_STREAM) {
|
if (result == SampleSource.END_OF_STREAM) {
|
||||||
inputStreamEnded = true;
|
inputStreamEnded = true;
|
||||||
@ -211,6 +209,7 @@ public final class Ac3PassthroughAudioTrackRenderer extends TrackRenderer {
|
|||||||
if (result != SampleSource.SAMPLE_READ) {
|
if (result != SampleSource.SAMPLE_READ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
shouldReadInputBuffer = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int handleBufferResult =
|
int handleBufferResult =
|
||||||
@ -227,16 +226,12 @@ public final class Ac3PassthroughAudioTrackRenderer extends TrackRenderer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStarted() {
|
protected void onStarted() {
|
||||||
if (audioTrack.isInitialized()) {
|
audioTrack.play();
|
||||||
audioTrack.play();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStopped() {
|
protected void onStopped() {
|
||||||
if (audioTrack.isInitialized()) {
|
audioTrack.pause();
|
||||||
audioTrack.pause();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -53,6 +53,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||||||
@SuppressLint("HandlerLeak")
|
@SuppressLint("HandlerLeak")
|
||||||
public ExoPlayerImpl(int rendererCount, int minBufferMs, int minRebufferMs) {
|
public ExoPlayerImpl(int rendererCount, int minBufferMs, int minRebufferMs) {
|
||||||
Log.i(TAG, "Init " + ExoPlayerLibraryInfo.VERSION);
|
Log.i(TAG, "Init " + ExoPlayerLibraryInfo.VERSION);
|
||||||
|
this.playWhenReady = false;
|
||||||
this.playbackState = STATE_IDLE;
|
this.playbackState = STATE_IDLE;
|
||||||
this.listeners = new CopyOnWriteArraySet<Listener>();
|
this.listeners = new CopyOnWriteArraySet<Listener>();
|
||||||
this.rendererEnabledFlags = new boolean[rendererCount];
|
this.rendererEnabledFlags = new boolean[rendererCount];
|
||||||
|
@ -164,7 +164,7 @@ public class MediaFormat {
|
|||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
if (hashCode == 0) {
|
if (hashCode == 0) {
|
||||||
int result = 17;
|
int result = 17;
|
||||||
result = 31 * result + mimeType == null ? 0 : mimeType.hashCode();
|
result = 31 * result + (mimeType == null ? 0 : mimeType.hashCode());
|
||||||
result = 31 * result + maxInputSize;
|
result = 31 * result + maxInputSize;
|
||||||
result = 31 * result + width;
|
result = 31 * result + width;
|
||||||
result = 31 * result + height;
|
result = 31 * result + height;
|
||||||
|
@ -310,8 +310,8 @@ public final class AudioTrack {
|
|||||||
|
|
||||||
// TODO: Does channelConfig determine channelCount?
|
// TODO: Does channelConfig determine channelCount?
|
||||||
boolean isAc3 = encoding == AudioFormat.ENCODING_AC3 || encoding == AudioFormat.ENCODING_E_AC3;
|
boolean isAc3 = encoding == AudioFormat.ENCODING_AC3 || encoding == AudioFormat.ENCODING_E_AC3;
|
||||||
if (audioTrack != null && this.sampleRate == sampleRate
|
if (isInitialized() && this.sampleRate == sampleRate && this.channelConfig == channelConfig
|
||||||
&& this.channelConfig == channelConfig && !this.isAc3 && !isAc3) {
|
&& !this.isAc3 && !isAc3) {
|
||||||
// We already have an existing audio track with the correct sample rate and channel config.
|
// We already have an existing audio track with the correct sample rate and channel config.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -450,7 +450,7 @@ public final class AudioTrack {
|
|||||||
|
|
||||||
/** Returns whether the audio track has more data pending that will be played back. */
|
/** Returns whether the audio track has more data pending that will be played back. */
|
||||||
public boolean hasPendingData() {
|
public boolean hasPendingData() {
|
||||||
return audioTrack != null && bytesToFrames(submittedBytes) > getPlaybackPositionFrames();
|
return isInitialized() && bytesToFrames(submittedBytes) > getPlaybackPositionFrames();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns whether enough data has been supplied via {@link #handleBuffer} to begin playback. */
|
/** Returns whether enough data has been supplied via {@link #handleBuffer} to begin playback. */
|
||||||
@ -461,7 +461,7 @@ public final class AudioTrack {
|
|||||||
/** Sets the playback volume. */
|
/** Sets the playback volume. */
|
||||||
public void setVolume(float volume) {
|
public void setVolume(float volume) {
|
||||||
this.volume = volume;
|
this.volume = volume;
|
||||||
if (audioTrack != null) {
|
if (isInitialized()) {
|
||||||
if (Util.SDK_INT >= 21) {
|
if (Util.SDK_INT >= 21) {
|
||||||
setVolumeV21(audioTrack, volume);
|
setVolumeV21(audioTrack, volume);
|
||||||
} else {
|
} else {
|
||||||
@ -482,7 +482,7 @@ public final class AudioTrack {
|
|||||||
|
|
||||||
/** Pauses playback. */
|
/** Pauses playback. */
|
||||||
public void pause() {
|
public void pause() {
|
||||||
if (audioTrack != null) {
|
if (isInitialized()) {
|
||||||
resetSyncParams();
|
resetSyncParams();
|
||||||
audioTrack.pause();
|
audioTrack.pause();
|
||||||
}
|
}
|
||||||
@ -494,7 +494,7 @@ public final class AudioTrack {
|
|||||||
* after resetting.
|
* after resetting.
|
||||||
*/
|
*/
|
||||||
public void reset() {
|
public void reset() {
|
||||||
if (audioTrack != null) {
|
if (isInitialized()) {
|
||||||
submittedBytes = 0;
|
submittedBytes = 0;
|
||||||
temporaryBufferSize = 0;
|
temporaryBufferSize = 0;
|
||||||
lastRawPlaybackHeadPosition = 0;
|
lastRawPlaybackHeadPosition = 0;
|
||||||
|
@ -80,9 +80,11 @@ import java.util.ArrayList;
|
|||||||
public final static class ContainerAtom extends Atom {
|
public final static class ContainerAtom extends Atom {
|
||||||
|
|
||||||
public final ArrayList<Atom> children;
|
public final ArrayList<Atom> children;
|
||||||
|
public final int endByteOffset;
|
||||||
|
|
||||||
public ContainerAtom(int type) {
|
public ContainerAtom(int type, int endByteOffset) {
|
||||||
super(type);
|
super(type);
|
||||||
|
this.endByteOffset = endByteOffset;
|
||||||
children = new ArrayList<Atom>();
|
children = new ArrayList<Atom>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,7 +139,6 @@ public final class FragmentedMp4Extractor implements Extractor {
|
|||||||
private final ParsableByteArray atomHeader;
|
private final ParsableByteArray atomHeader;
|
||||||
private final byte[] extendedTypeScratch;
|
private final byte[] extendedTypeScratch;
|
||||||
private final Stack<ContainerAtom> containerAtoms;
|
private final Stack<ContainerAtom> containerAtoms;
|
||||||
private final Stack<Integer> containerAtomEndPoints;
|
|
||||||
private final TrackFragment fragmentRun;
|
private final TrackFragment fragmentRun;
|
||||||
|
|
||||||
private int parserState;
|
private int parserState;
|
||||||
@ -174,7 +173,6 @@ public final class FragmentedMp4Extractor implements Extractor {
|
|||||||
atomHeader = new ParsableByteArray(ATOM_HEADER_SIZE);
|
atomHeader = new ParsableByteArray(ATOM_HEADER_SIZE);
|
||||||
extendedTypeScratch = new byte[16];
|
extendedTypeScratch = new byte[16];
|
||||||
containerAtoms = new Stack<ContainerAtom>();
|
containerAtoms = new Stack<ContainerAtom>();
|
||||||
containerAtomEndPoints = new Stack<Integer>();
|
|
||||||
fragmentRun = new TrackFragment();
|
fragmentRun = new TrackFragment();
|
||||||
psshData = new HashMap<UUID, byte[]>();
|
psshData = new HashMap<UUID, byte[]>();
|
||||||
}
|
}
|
||||||
@ -258,7 +256,6 @@ public final class FragmentedMp4Extractor implements Extractor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
containerAtoms.clear();
|
containerAtoms.clear();
|
||||||
containerAtomEndPoints.clear();
|
|
||||||
enterState(STATE_READING_ATOM_HEADER);
|
enterState(STATE_READING_ATOM_HEADER);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -267,7 +264,7 @@ public final class FragmentedMp4Extractor implements Extractor {
|
|||||||
switch (state) {
|
switch (state) {
|
||||||
case STATE_READING_ATOM_HEADER:
|
case STATE_READING_ATOM_HEADER:
|
||||||
atomBytesRead = 0;
|
atomBytesRead = 0;
|
||||||
if (containerAtomEndPoints.isEmpty()) {
|
if (containerAtoms.isEmpty()) {
|
||||||
rootAtomBytesRead = 0;
|
rootAtomBytesRead = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -300,11 +297,12 @@ public final class FragmentedMp4Extractor implements Extractor {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PARSED_ATOMS.contains(atomType)) {
|
Integer atomTypeInteger = atomType; // Avoids boxing atomType twice.
|
||||||
if (CONTAINER_TYPES.contains(atomType)) {
|
if (PARSED_ATOMS.contains(atomTypeInteger)) {
|
||||||
|
if (CONTAINER_TYPES.contains(atomTypeInteger)) {
|
||||||
enterState(STATE_READING_ATOM_HEADER);
|
enterState(STATE_READING_ATOM_HEADER);
|
||||||
containerAtoms.add(new ContainerAtom(atomType));
|
containerAtoms.add(new ContainerAtom(atomType,
|
||||||
containerAtomEndPoints.add(rootAtomBytesRead + atomSize - ATOM_HEADER_SIZE);
|
rootAtomBytesRead + atomSize - ATOM_HEADER_SIZE));
|
||||||
} else {
|
} else {
|
||||||
atomData = new ParsableByteArray(atomSize);
|
atomData = new ParsableByteArray(atomSize);
|
||||||
System.arraycopy(atomHeader.data, 0, atomData.data, 0, ATOM_HEADER_SIZE);
|
System.arraycopy(atomHeader.data, 0, atomData.data, 0, ATOM_HEADER_SIZE);
|
||||||
@ -339,9 +337,7 @@ public final class FragmentedMp4Extractor implements Extractor {
|
|||||||
results |= onLeafAtomRead(new LeafAtom(atomType, atomData));
|
results |= onLeafAtomRead(new LeafAtom(atomType, atomData));
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!containerAtomEndPoints.isEmpty()
|
while (!containerAtoms.isEmpty() && containerAtoms.peek().endByteOffset == rootAtomBytesRead) {
|
||||||
&& containerAtomEndPoints.peek() == rootAtomBytesRead) {
|
|
||||||
containerAtomEndPoints.pop();
|
|
||||||
results |= onContainerAtomRead(containerAtoms.pop());
|
results |= onContainerAtomRead(containerAtoms.pop());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -343,8 +343,8 @@ public class SmoothStreamingChunkSource implements ChunkSource {
|
|||||||
TrackElement trackElement = streamElement.tracks[trackIndex];
|
TrackElement trackElement = streamElement.tracks[trackIndex];
|
||||||
String mimeType = trackElement.mimeType;
|
String mimeType = trackElement.mimeType;
|
||||||
if (streamElement.type == StreamElement.TYPE_VIDEO) {
|
if (streamElement.type == StreamElement.TYPE_VIDEO) {
|
||||||
MediaFormat format = MediaFormat.createVideoFormat(mimeType, -1, trackElement.maxWidth,
|
MediaFormat format = MediaFormat.createVideoFormat(mimeType, MediaFormat.NO_VALUE,
|
||||||
trackElement.maxHeight, Arrays.asList(trackElement.csd));
|
trackElement.maxWidth, trackElement.maxHeight, Arrays.asList(trackElement.csd));
|
||||||
format.setMaxVideoDimensions(streamElement.maxWidth, streamElement.maxHeight);
|
format.setMaxVideoDimensions(streamElement.maxWidth, streamElement.maxHeight);
|
||||||
return format;
|
return format;
|
||||||
} else if (streamElement.type == StreamElement.TYPE_AUDIO) {
|
} else if (streamElement.type == StreamElement.TYPE_AUDIO) {
|
||||||
@ -355,8 +355,8 @@ public class SmoothStreamingChunkSource implements ChunkSource {
|
|||||||
csd = Collections.singletonList(CodecSpecificDataUtil.buildAudioSpecificConfig(
|
csd = Collections.singletonList(CodecSpecificDataUtil.buildAudioSpecificConfig(
|
||||||
trackElement.sampleRate, trackElement.numChannels));
|
trackElement.sampleRate, trackElement.numChannels));
|
||||||
}
|
}
|
||||||
MediaFormat format = MediaFormat.createAudioFormat(mimeType, -1, trackElement.numChannels,
|
MediaFormat format = MediaFormat.createAudioFormat(mimeType, MediaFormat.NO_VALUE,
|
||||||
trackElement.sampleRate, csd);
|
trackElement.numChannels, trackElement.sampleRate, csd);
|
||||||
return format;
|
return format;
|
||||||
} else if (streamElement.type == StreamElement.TYPE_TEXT) {
|
} else if (streamElement.type == StreamElement.TYPE_TEXT) {
|
||||||
return MediaFormat.createFormatForMimeType(streamElement.tracks[trackIndex].mimeType);
|
return MediaFormat.createFormatForMimeType(streamElement.tracks[trackIndex].mimeType);
|
||||||
|
@ -273,7 +273,7 @@ public class SmoothStreamingManifest {
|
|||||||
Assertions.checkState(chunkIndex < chunkStartTimes.size());
|
Assertions.checkState(chunkIndex < chunkStartTimes.size());
|
||||||
String chunkUrl = chunkTemplate
|
String chunkUrl = chunkTemplate
|
||||||
.replace(URL_PLACEHOLDER_BITRATE, Integer.toString(tracks[track].bitrate))
|
.replace(URL_PLACEHOLDER_BITRATE, Integer.toString(tracks[track].bitrate))
|
||||||
.replace(URL_PLACEHOLDER_START_TIME, Long.toString(chunkStartTimes.get(chunkIndex)));
|
.replace(URL_PLACEHOLDER_START_TIME, chunkStartTimes.get(chunkIndex).toString());
|
||||||
return Util.getMergedUri(baseUri, chunkUrl);
|
return Util.getMergedUri(baseUri, chunkUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ public class SubtitleView extends View {
|
|||||||
|
|
||||||
Resources resources = getContext().getResources();
|
Resources resources = getContext().getResources();
|
||||||
DisplayMetrics displayMetrics = resources.getDisplayMetrics();
|
DisplayMetrics displayMetrics = resources.getDisplayMetrics();
|
||||||
int twoDpInPx = Math.round((2 * displayMetrics.densityDpi) / DisplayMetrics.DENSITY_DEFAULT);
|
int twoDpInPx = Math.round((2f * displayMetrics.densityDpi) / DisplayMetrics.DENSITY_DEFAULT);
|
||||||
cornerRadius = twoDpInPx;
|
cornerRadius = twoDpInPx;
|
||||||
outlineWidth = twoDpInPx;
|
outlineWidth = twoDpInPx;
|
||||||
shadowRadius = twoDpInPx;
|
shadowRadius = twoDpInPx;
|
||||||
|
@ -53,10 +53,17 @@ public final class NetworkLock {
|
|||||||
*/
|
*/
|
||||||
public static final int DOWNLOAD_PRIORITY = 10;
|
public static final int DOWNLOAD_PRIORITY = 10;
|
||||||
|
|
||||||
|
private final Object lock = new Object();
|
||||||
|
|
||||||
|
/** Guarded by {@link #lock}. */
|
||||||
private final PriorityQueue<Integer> queue;
|
private final PriorityQueue<Integer> queue;
|
||||||
|
|
||||||
|
/** Guarded by {@link #lock}. */
|
||||||
|
private int highestPriority;
|
||||||
|
|
||||||
private NetworkLock() {
|
private NetworkLock() {
|
||||||
queue = new PriorityQueue<Integer>();
|
queue = new PriorityQueue<Integer>();
|
||||||
|
highestPriority = Integer.MAX_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -64,9 +71,11 @@ public final class NetworkLock {
|
|||||||
*
|
*
|
||||||
* @param priority The priority of the task that would like to proceed.
|
* @param priority The priority of the task that would like to proceed.
|
||||||
*/
|
*/
|
||||||
public synchronized void proceed(int priority) throws InterruptedException {
|
public void proceed(int priority) throws InterruptedException {
|
||||||
while (queue.peek() < priority) {
|
synchronized (lock) {
|
||||||
wait();
|
while (highestPriority < priority) {
|
||||||
|
lock.wait();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,8 +85,10 @@ public final class NetworkLock {
|
|||||||
* @param priority The priority of the task that would like to proceed.
|
* @param priority The priority of the task that would like to proceed.
|
||||||
* @return Whether the passed priority is allowed to proceed.
|
* @return Whether the passed priority is allowed to proceed.
|
||||||
*/
|
*/
|
||||||
public synchronized boolean proceedNonBlocking(int priority) {
|
public boolean proceedNonBlocking(int priority) {
|
||||||
return queue.peek() >= priority;
|
synchronized (lock) {
|
||||||
|
return highestPriority >= priority;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -86,10 +97,11 @@ public final class NetworkLock {
|
|||||||
* @param priority The priority of the task that would like to proceed.
|
* @param priority The priority of the task that would like to proceed.
|
||||||
* @throws PriorityTooLowException If the passed priority is not high enough to proceed.
|
* @throws PriorityTooLowException If the passed priority is not high enough to proceed.
|
||||||
*/
|
*/
|
||||||
public synchronized void proceedOrThrow(int priority) throws PriorityTooLowException {
|
public void proceedOrThrow(int priority) throws PriorityTooLowException {
|
||||||
int highestPriority = queue.peek();
|
synchronized (lock) {
|
||||||
if (highestPriority < priority) {
|
if (highestPriority < priority) {
|
||||||
throw new PriorityTooLowException(priority, highestPriority);
|
throw new PriorityTooLowException(priority, highestPriority);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,8 +112,11 @@ public final class NetworkLock {
|
|||||||
*
|
*
|
||||||
* @param priority The priority of the task.
|
* @param priority The priority of the task.
|
||||||
*/
|
*/
|
||||||
public synchronized void add(int priority) {
|
public void add(int priority) {
|
||||||
queue.add(priority);
|
synchronized (lock) {
|
||||||
|
queue.add(priority);
|
||||||
|
highestPriority = Math.min(highestPriority, priority);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -109,9 +124,12 @@ public final class NetworkLock {
|
|||||||
*
|
*
|
||||||
* @param priority The priority of the task.
|
* @param priority The priority of the task.
|
||||||
*/
|
*/
|
||||||
public synchronized void remove(int priority) {
|
public void remove(int priority) {
|
||||||
queue.remove(priority);
|
synchronized (lock) {
|
||||||
notifyAll();
|
queue.remove(priority);
|
||||||
|
highestPriority = queue.isEmpty() ? Integer.MAX_VALUE : queue.peek();
|
||||||
|
lock.notifyAll();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -317,8 +317,8 @@ public final class Util {
|
|||||||
} else if (matcher.group(9).equalsIgnoreCase("Z")) {
|
} else if (matcher.group(9).equalsIgnoreCase("Z")) {
|
||||||
timezoneShift = 0;
|
timezoneShift = 0;
|
||||||
} else {
|
} else {
|
||||||
timezoneShift = ((Integer.valueOf(matcher.group(12)) * 60
|
timezoneShift = ((Integer.parseInt(matcher.group(12)) * 60
|
||||||
+ Integer.valueOf(matcher.group(13))));
|
+ Integer.parseInt(matcher.group(13))));
|
||||||
if (matcher.group(11).equals("-")) {
|
if (matcher.group(11).equals("-")) {
|
||||||
timezoneShift *= -1;
|
timezoneShift *= -1;
|
||||||
}
|
}
|
||||||
@ -328,12 +328,12 @@ public final class Util {
|
|||||||
|
|
||||||
dateTime.clear();
|
dateTime.clear();
|
||||||
// Note: The month value is 0-based, hence the -1 on group(2)
|
// Note: The month value is 0-based, hence the -1 on group(2)
|
||||||
dateTime.set(Integer.valueOf(matcher.group(1)),
|
dateTime.set(Integer.parseInt(matcher.group(1)),
|
||||||
Integer.valueOf(matcher.group(2)) - 1,
|
Integer.parseInt(matcher.group(2)) - 1,
|
||||||
Integer.valueOf(matcher.group(3)),
|
Integer.parseInt(matcher.group(3)),
|
||||||
Integer.valueOf(matcher.group(4)),
|
Integer.parseInt(matcher.group(4)),
|
||||||
Integer.valueOf(matcher.group(5)),
|
Integer.parseInt(matcher.group(5)),
|
||||||
Integer.valueOf(matcher.group(6)));
|
Integer.parseInt(matcher.group(6)));
|
||||||
if (!TextUtils.isEmpty(matcher.group(8))) {
|
if (!TextUtils.isEmpty(matcher.group(8))) {
|
||||||
final BigDecimal bd = new BigDecimal("0." + matcher.group(8));
|
final BigDecimal bd = new BigDecimal("0." + matcher.group(8));
|
||||||
// we care only for milliseconds, so movePointRight(3)
|
// we care only for milliseconds, so movePointRight(3)
|
||||||
|