mirror of
https://github.com/Pinball3D/Rabbit-R1.git
synced 2024-12-27 01:22:33 -06:00
480 lines
22 KiB
Java
480 lines
22 KiB
Java
package com.google.android.exoplayer2.offline;
|
|
|
|
import android.net.Uri;
|
|
import com.google.android.exoplayer2.MediaItem;
|
|
import com.google.android.exoplayer2.offline.Downloader;
|
|
import com.google.android.exoplayer2.offline.FilterableManifest;
|
|
import com.google.android.exoplayer2.upstream.DataSource;
|
|
import com.google.android.exoplayer2.upstream.DataSpec;
|
|
import com.google.android.exoplayer2.upstream.ParsingLoadable;
|
|
import com.google.android.exoplayer2.upstream.cache.Cache;
|
|
import com.google.android.exoplayer2.upstream.cache.CacheDataSource;
|
|
import com.google.android.exoplayer2.upstream.cache.CacheKeyFactory;
|
|
import com.google.android.exoplayer2.upstream.cache.CacheWriter;
|
|
import com.google.android.exoplayer2.upstream.cache.ContentMetadata;
|
|
import com.google.android.exoplayer2.util.Assertions;
|
|
import com.google.android.exoplayer2.util.PriorityTaskManager;
|
|
import com.google.android.exoplayer2.util.RunnableFutureTask;
|
|
import com.google.android.exoplayer2.util.Util;
|
|
import java.io.IOException;
|
|
import java.util.ArrayDeque;
|
|
import java.util.ArrayList;
|
|
import java.util.Collections;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.concurrent.ExecutionException;
|
|
import java.util.concurrent.Executor;
|
|
|
|
/* loaded from: classes2.dex */
|
|
public abstract class SegmentDownloader<M extends FilterableManifest<M>> implements Downloader {
|
|
private static final int BUFFER_SIZE_BYTES = 131072;
|
|
public static final long DEFAULT_MAX_MERGED_SEGMENT_START_TIME_DIFF_MS = 20000;
|
|
private final ArrayList<RunnableFutureTask<?, ?>> activeRunnables;
|
|
private final Cache cache;
|
|
private final CacheDataSource.Factory cacheDataSourceFactory;
|
|
private final CacheKeyFactory cacheKeyFactory;
|
|
private final Executor executor;
|
|
private volatile boolean isCanceled;
|
|
private final DataSpec manifestDataSpec;
|
|
private final ParsingLoadable.Parser<M> manifestParser;
|
|
private final long maxMergedSegmentStartTimeDiffUs;
|
|
private final PriorityTaskManager priorityTaskManager;
|
|
private final ArrayList<StreamKey> streamKeys;
|
|
|
|
protected abstract List<Segment> getSegments(DataSource dataSource, M m, boolean z) throws IOException, InterruptedException;
|
|
|
|
/* JADX INFO: Access modifiers changed from: protected */
|
|
/* loaded from: classes2.dex */
|
|
public static class Segment implements Comparable<Segment> {
|
|
public final DataSpec dataSpec;
|
|
public final long startTimeUs;
|
|
|
|
public Segment(long j, DataSpec dataSpec) {
|
|
this.startTimeUs = j;
|
|
this.dataSpec = dataSpec;
|
|
}
|
|
|
|
@Override // java.lang.Comparable
|
|
public int compareTo(Segment segment) {
|
|
return Util.compareLong(this.startTimeUs, segment.startTimeUs);
|
|
}
|
|
}
|
|
|
|
@Deprecated
|
|
public SegmentDownloader(MediaItem mediaItem, ParsingLoadable.Parser<M> parser, CacheDataSource.Factory factory, Executor executor) {
|
|
this(mediaItem, parser, factory, executor, 20000L);
|
|
}
|
|
|
|
public SegmentDownloader(MediaItem mediaItem, ParsingLoadable.Parser<M> parser, CacheDataSource.Factory factory, Executor executor, long j) {
|
|
Assertions.checkNotNull(mediaItem.localConfiguration);
|
|
this.manifestDataSpec = getCompressibleDataSpec(mediaItem.localConfiguration.uri);
|
|
this.manifestParser = parser;
|
|
this.streamKeys = new ArrayList<>(mediaItem.localConfiguration.streamKeys);
|
|
this.cacheDataSourceFactory = factory;
|
|
this.executor = executor;
|
|
this.cache = (Cache) Assertions.checkNotNull(factory.getCache());
|
|
this.cacheKeyFactory = factory.getCacheKeyFactory();
|
|
this.priorityTaskManager = factory.getUpstreamPriorityTaskManager();
|
|
this.activeRunnables = new ArrayList<>();
|
|
this.maxMergedSegmentStartTimeDiffUs = Util.msToUs(j);
|
|
}
|
|
|
|
/* JADX WARN: Multi-variable type inference failed */
|
|
@Override // com.google.android.exoplayer2.offline.Downloader
|
|
public final void download(Downloader.ProgressListener progressListener) throws IOException, InterruptedException {
|
|
int i;
|
|
int size;
|
|
CacheDataSource createDataSourceForDownloading;
|
|
byte[] bArr;
|
|
int i2;
|
|
ArrayDeque arrayDeque = new ArrayDeque();
|
|
ArrayDeque arrayDeque2 = new ArrayDeque();
|
|
PriorityTaskManager priorityTaskManager = this.priorityTaskManager;
|
|
if (priorityTaskManager != null) {
|
|
priorityTaskManager.add(-1000);
|
|
}
|
|
try {
|
|
CacheDataSource createDataSourceForDownloading2 = this.cacheDataSourceFactory.createDataSourceForDownloading();
|
|
FilterableManifest manifest = getManifest(createDataSourceForDownloading2, this.manifestDataSpec, false);
|
|
if (!this.streamKeys.isEmpty()) {
|
|
manifest = (FilterableManifest) manifest.copy(this.streamKeys);
|
|
}
|
|
List<Segment> segments = getSegments(createDataSourceForDownloading2, manifest, false);
|
|
Collections.sort(segments);
|
|
mergeSegments(segments, this.cacheKeyFactory, this.maxMergedSegmentStartTimeDiffUs);
|
|
int size2 = segments.size();
|
|
int i3 = 0;
|
|
long j = 0;
|
|
long j2 = 0;
|
|
for (int size3 = segments.size() - 1; size3 >= 0; size3 = i2 - 1) {
|
|
DataSpec dataSpec = segments.get(size3).dataSpec;
|
|
String buildCacheKey = this.cacheKeyFactory.buildCacheKey(dataSpec);
|
|
long j3 = dataSpec.length;
|
|
if (j3 == -1) {
|
|
long contentLength = ContentMetadata.getContentLength(this.cache.getContentMetadata(buildCacheKey));
|
|
if (contentLength != -1) {
|
|
j3 = contentLength - dataSpec.position;
|
|
}
|
|
}
|
|
int i4 = size3;
|
|
long cachedBytes = this.cache.getCachedBytes(buildCacheKey, dataSpec.position, j3);
|
|
j2 += cachedBytes;
|
|
if (j3 != -1) {
|
|
if (j3 == cachedBytes) {
|
|
i3++;
|
|
i2 = i4;
|
|
segments.remove(i2);
|
|
} else {
|
|
i2 = i4;
|
|
}
|
|
if (j != -1) {
|
|
j += j3;
|
|
}
|
|
} else {
|
|
i2 = i4;
|
|
j = -1;
|
|
}
|
|
}
|
|
ProgressNotifier progressNotifier = progressListener != null ? new ProgressNotifier(progressListener, j, size2, j2, i3) : null;
|
|
arrayDeque.addAll(segments);
|
|
while (!this.isCanceled && !arrayDeque.isEmpty()) {
|
|
PriorityTaskManager priorityTaskManager2 = this.priorityTaskManager;
|
|
if (priorityTaskManager2 != null) {
|
|
priorityTaskManager2.proceed(-1000);
|
|
}
|
|
if (!arrayDeque2.isEmpty()) {
|
|
SegmentDownloadRunnable segmentDownloadRunnable = (SegmentDownloadRunnable) arrayDeque2.removeFirst();
|
|
createDataSourceForDownloading = segmentDownloadRunnable.dataSource;
|
|
bArr = segmentDownloadRunnable.temporaryBuffer;
|
|
} else {
|
|
createDataSourceForDownloading = this.cacheDataSourceFactory.createDataSourceForDownloading();
|
|
bArr = new byte[131072];
|
|
}
|
|
SegmentDownloadRunnable segmentDownloadRunnable2 = new SegmentDownloadRunnable((Segment) arrayDeque.removeFirst(), createDataSourceForDownloading, progressNotifier, bArr);
|
|
addActiveRunnable(segmentDownloadRunnable2);
|
|
this.executor.execute(segmentDownloadRunnable2);
|
|
for (int size4 = this.activeRunnables.size() - 1; size4 >= 0; size4--) {
|
|
SegmentDownloadRunnable segmentDownloadRunnable3 = (SegmentDownloadRunnable) this.activeRunnables.get(size4);
|
|
if (arrayDeque.isEmpty() || segmentDownloadRunnable3.isDone()) {
|
|
try {
|
|
segmentDownloadRunnable3.get();
|
|
removeActiveRunnable(size4);
|
|
arrayDeque2.addLast(segmentDownloadRunnable3);
|
|
} catch (ExecutionException e) {
|
|
Throwable th = (Throwable) Assertions.checkNotNull(e.getCause());
|
|
if (th instanceof PriorityTaskManager.PriorityTooLowException) {
|
|
arrayDeque.addFirst(segmentDownloadRunnable3.segment);
|
|
removeActiveRunnable(size4);
|
|
arrayDeque2.addLast(segmentDownloadRunnable3);
|
|
} else {
|
|
if (th instanceof IOException) {
|
|
throw ((IOException) th);
|
|
}
|
|
Util.sneakyThrow(th);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
segmentDownloadRunnable2.blockUntilStarted();
|
|
}
|
|
while (true) {
|
|
if (i >= size) {
|
|
break;
|
|
}
|
|
}
|
|
} finally {
|
|
for (i = 0; i < this.activeRunnables.size(); i++) {
|
|
this.activeRunnables.get(i).cancel(true);
|
|
}
|
|
for (int size5 = this.activeRunnables.size() - 1; size5 >= 0; size5--) {
|
|
this.activeRunnables.get(size5).blockUntilFinished();
|
|
removeActiveRunnable(size5);
|
|
}
|
|
PriorityTaskManager priorityTaskManager3 = this.priorityTaskManager;
|
|
if (priorityTaskManager3 != null) {
|
|
priorityTaskManager3.remove(-1000);
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override // com.google.android.exoplayer2.offline.Downloader
|
|
public void cancel() {
|
|
synchronized (this.activeRunnables) {
|
|
this.isCanceled = true;
|
|
for (int i = 0; i < this.activeRunnables.size(); i++) {
|
|
this.activeRunnables.get(i).cancel(true);
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override // com.google.android.exoplayer2.offline.Downloader
|
|
public final void remove() {
|
|
CacheDataSource createDataSourceForRemovingDownload = this.cacheDataSourceFactory.createDataSourceForRemovingDownload();
|
|
try {
|
|
try {
|
|
List<Segment> segments = getSegments(createDataSourceForRemovingDownload, getManifest(createDataSourceForRemovingDownload, this.manifestDataSpec, true), true);
|
|
for (int i = 0; i < segments.size(); i++) {
|
|
this.cache.removeResource(this.cacheKeyFactory.buildCacheKey(segments.get(i).dataSpec));
|
|
}
|
|
} catch (InterruptedException unused) {
|
|
Thread.currentThread().interrupt();
|
|
} catch (Exception unused2) {
|
|
}
|
|
} finally {
|
|
this.cache.removeResource(this.cacheKeyFactory.buildCacheKey(this.manifestDataSpec));
|
|
}
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: protected */
|
|
public final M getManifest(final DataSource dataSource, final DataSpec dataSpec, boolean z) throws InterruptedException, IOException {
|
|
return (M) execute(new RunnableFutureTask<M, IOException>() { // from class: com.google.android.exoplayer2.offline.SegmentDownloader.1
|
|
/* JADX INFO: Access modifiers changed from: protected */
|
|
@Override // com.google.android.exoplayer2.util.RunnableFutureTask
|
|
public M doWork() throws IOException {
|
|
return (M) ParsingLoadable.load(dataSource, SegmentDownloader.this.manifestParser, dataSpec, 4);
|
|
}
|
|
}, z);
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: protected */
|
|
/* JADX WARN: Can't wrap try/catch for region: R(5:27|28|29|(2:34|(2:36|37)(3:38|39|40))(2:31|32)|33) */
|
|
/* JADX WARN: Code restructure failed: missing block: B:27:0x0042, code lost:
|
|
|
|
r4 = move-exception;
|
|
*/
|
|
/* JADX WARN: Code restructure failed: missing block: B:29:0x0043, code lost:
|
|
|
|
r0 = (java.lang.Throwable) com.google.android.exoplayer2.util.Assertions.checkNotNull(r4.getCause());
|
|
*/
|
|
/* JADX WARN: Code restructure failed: missing block: B:30:0x004f, code lost:
|
|
|
|
if ((r0 instanceof com.google.android.exoplayer2.util.PriorityTaskManager.PriorityTooLowException) == false) goto L27;
|
|
*/
|
|
/* JADX WARN: Code restructure failed: missing block: B:35:0x0054, code lost:
|
|
|
|
if ((r0 instanceof java.io.IOException) == false) goto L29;
|
|
*/
|
|
/* JADX WARN: Code restructure failed: missing block: B:36:0x0056, code lost:
|
|
|
|
com.google.android.exoplayer2.util.Util.sneakyThrow(r4);
|
|
*/
|
|
/* JADX WARN: Code restructure failed: missing block: B:40:0x0062, code lost:
|
|
|
|
throw ((java.io.IOException) r0);
|
|
*/
|
|
/* JADX WARN: Code restructure failed: missing block: B:41:0x0040, code lost:
|
|
|
|
r4 = move-exception;
|
|
*/
|
|
/* JADX WARN: Code restructure failed: missing block: B:42:0x0063, code lost:
|
|
|
|
r3.blockUntilFinished();
|
|
r2.removeActiveRunnable((com.google.android.exoplayer2.util.RunnableFutureTask<?, ?>) r3);
|
|
*/
|
|
/* JADX WARN: Code restructure failed: missing block: B:43:0x0069, code lost:
|
|
|
|
throw r4;
|
|
*/
|
|
/*
|
|
Code decompiled incorrectly, please refer to instructions dump.
|
|
To view partially-correct add '--show-bad-code' argument
|
|
*/
|
|
public final <T> T execute(com.google.android.exoplayer2.util.RunnableFutureTask<T, ?> r3, boolean r4) throws java.lang.InterruptedException, java.io.IOException {
|
|
/*
|
|
r2 = this;
|
|
if (r4 == 0) goto L20
|
|
r3.run()
|
|
java.lang.Object r2 = r3.get() // Catch: java.util.concurrent.ExecutionException -> La
|
|
return r2
|
|
La:
|
|
r4 = move-exception
|
|
java.lang.Throwable r0 = r4.getCause()
|
|
java.lang.Object r0 = com.google.android.exoplayer2.util.Assertions.checkNotNull(r0)
|
|
java.lang.Throwable r0 = (java.lang.Throwable) r0
|
|
boolean r1 = r0 instanceof java.io.IOException
|
|
if (r1 != 0) goto L1d
|
|
com.google.android.exoplayer2.util.Util.sneakyThrow(r4)
|
|
goto L20
|
|
L1d:
|
|
java.io.IOException r0 = (java.io.IOException) r0
|
|
throw r0
|
|
L20:
|
|
boolean r4 = r2.isCanceled
|
|
if (r4 != 0) goto L6a
|
|
com.google.android.exoplayer2.util.PriorityTaskManager r4 = r2.priorityTaskManager
|
|
if (r4 == 0) goto L2d
|
|
r0 = -1000(0xfffffffffffffc18, float:NaN)
|
|
r4.proceed(r0)
|
|
L2d:
|
|
r2.addActiveRunnable(r3)
|
|
java.util.concurrent.Executor r4 = r2.executor
|
|
r4.execute(r3)
|
|
java.lang.Object r4 = r3.get() // Catch: java.lang.Throwable -> L40 java.util.concurrent.ExecutionException -> L42
|
|
r3.blockUntilFinished()
|
|
r2.removeActiveRunnable(r3)
|
|
return r4
|
|
L40:
|
|
r4 = move-exception
|
|
goto L63
|
|
L42:
|
|
r4 = move-exception
|
|
java.lang.Throwable r0 = r4.getCause() // Catch: java.lang.Throwable -> L40
|
|
java.lang.Object r0 = com.google.android.exoplayer2.util.Assertions.checkNotNull(r0) // Catch: java.lang.Throwable -> L40
|
|
java.lang.Throwable r0 = (java.lang.Throwable) r0 // Catch: java.lang.Throwable -> L40
|
|
boolean r1 = r0 instanceof com.google.android.exoplayer2.util.PriorityTaskManager.PriorityTooLowException // Catch: java.lang.Throwable -> L40
|
|
if (r1 == 0) goto L52
|
|
goto L59
|
|
L52:
|
|
boolean r1 = r0 instanceof java.io.IOException // Catch: java.lang.Throwable -> L40
|
|
if (r1 != 0) goto L60
|
|
com.google.android.exoplayer2.util.Util.sneakyThrow(r4) // Catch: java.lang.Throwable -> L40
|
|
L59:
|
|
r3.blockUntilFinished()
|
|
r2.removeActiveRunnable(r3)
|
|
goto L20
|
|
L60:
|
|
java.io.IOException r0 = (java.io.IOException) r0 // Catch: java.lang.Throwable -> L40
|
|
throw r0 // Catch: java.lang.Throwable -> L40
|
|
L63:
|
|
r3.blockUntilFinished()
|
|
r2.removeActiveRunnable(r3)
|
|
throw r4
|
|
L6a:
|
|
java.lang.InterruptedException r2 = new java.lang.InterruptedException
|
|
r2.<init>()
|
|
throw r2
|
|
*/
|
|
throw new UnsupportedOperationException("Method not decompiled: com.google.android.exoplayer2.offline.SegmentDownloader.execute(com.google.android.exoplayer2.util.RunnableFutureTask, boolean):java.lang.Object");
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: protected */
|
|
public static DataSpec getCompressibleDataSpec(Uri uri) {
|
|
return new DataSpec.Builder().setUri(uri).setFlags(1).build();
|
|
}
|
|
|
|
private <T> void addActiveRunnable(RunnableFutureTask<T, ?> runnableFutureTask) throws InterruptedException {
|
|
synchronized (this.activeRunnables) {
|
|
if (this.isCanceled) {
|
|
throw new InterruptedException();
|
|
}
|
|
this.activeRunnables.add(runnableFutureTask);
|
|
}
|
|
}
|
|
|
|
private void removeActiveRunnable(RunnableFutureTask<?, ?> runnableFutureTask) {
|
|
synchronized (this.activeRunnables) {
|
|
this.activeRunnables.remove(runnableFutureTask);
|
|
}
|
|
}
|
|
|
|
private void removeActiveRunnable(int i) {
|
|
synchronized (this.activeRunnables) {
|
|
this.activeRunnables.remove(i);
|
|
}
|
|
}
|
|
|
|
private static void mergeSegments(List<Segment> list, CacheKeyFactory cacheKeyFactory, long j) {
|
|
HashMap hashMap = new HashMap();
|
|
int i = 0;
|
|
for (int i2 = 0; i2 < list.size(); i2++) {
|
|
Segment segment = list.get(i2);
|
|
String buildCacheKey = cacheKeyFactory.buildCacheKey(segment.dataSpec);
|
|
Integer num = (Integer) hashMap.get(buildCacheKey);
|
|
Segment segment2 = num == null ? null : list.get(num.intValue());
|
|
if (segment2 == null || segment.startTimeUs > segment2.startTimeUs + j || !canMergeSegments(segment2.dataSpec, segment.dataSpec)) {
|
|
hashMap.put(buildCacheKey, Integer.valueOf(i));
|
|
list.set(i, segment);
|
|
i++;
|
|
} else {
|
|
list.set(((Integer) Assertions.checkNotNull(num)).intValue(), new Segment(segment2.startTimeUs, segment2.dataSpec.subrange(0L, segment.dataSpec.length != -1 ? segment2.dataSpec.length + segment.dataSpec.length : -1L)));
|
|
}
|
|
}
|
|
Util.removeRange(list, i, list.size());
|
|
}
|
|
|
|
private static boolean canMergeSegments(DataSpec dataSpec, DataSpec dataSpec2) {
|
|
return dataSpec.uri.equals(dataSpec2.uri) && dataSpec.length != -1 && dataSpec.position + dataSpec.length == dataSpec2.position && Util.areEqual(dataSpec.key, dataSpec2.key) && dataSpec.flags == dataSpec2.flags && dataSpec.httpMethod == dataSpec2.httpMethod && dataSpec.httpRequestHeaders.equals(dataSpec2.httpRequestHeaders);
|
|
}
|
|
|
|
/* loaded from: classes2.dex */
|
|
private static final class SegmentDownloadRunnable extends RunnableFutureTask<Void, IOException> {
|
|
private final CacheWriter cacheWriter;
|
|
public final CacheDataSource dataSource;
|
|
private final ProgressNotifier progressNotifier;
|
|
public final Segment segment;
|
|
public final byte[] temporaryBuffer;
|
|
|
|
public SegmentDownloadRunnable(Segment segment, CacheDataSource cacheDataSource, ProgressNotifier progressNotifier, byte[] bArr) {
|
|
this.segment = segment;
|
|
this.dataSource = cacheDataSource;
|
|
this.progressNotifier = progressNotifier;
|
|
this.temporaryBuffer = bArr;
|
|
this.cacheWriter = new CacheWriter(cacheDataSource, segment.dataSpec, bArr, progressNotifier);
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: protected */
|
|
@Override // com.google.android.exoplayer2.util.RunnableFutureTask
|
|
public Void doWork() throws IOException {
|
|
this.cacheWriter.cache();
|
|
ProgressNotifier progressNotifier = this.progressNotifier;
|
|
if (progressNotifier == null) {
|
|
return null;
|
|
}
|
|
progressNotifier.onSegmentDownloaded();
|
|
return null;
|
|
}
|
|
|
|
@Override // com.google.android.exoplayer2.util.RunnableFutureTask
|
|
protected void cancelWork() {
|
|
this.cacheWriter.cancel();
|
|
}
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: private */
|
|
/* loaded from: classes2.dex */
|
|
public static final class ProgressNotifier implements CacheWriter.ProgressListener {
|
|
private long bytesDownloaded;
|
|
private final long contentLength;
|
|
private final Downloader.ProgressListener progressListener;
|
|
private int segmentsDownloaded;
|
|
private final int totalSegments;
|
|
|
|
private float getPercentDownloaded() {
|
|
float f;
|
|
float f2;
|
|
long j = this.contentLength;
|
|
if (j == -1 || j == 0) {
|
|
int i = this.totalSegments;
|
|
if (i == 0) {
|
|
return -1.0f;
|
|
}
|
|
f = this.segmentsDownloaded * 100.0f;
|
|
f2 = i;
|
|
} else {
|
|
f = ((float) this.bytesDownloaded) * 100.0f;
|
|
f2 = (float) j;
|
|
}
|
|
return f / f2;
|
|
}
|
|
|
|
public ProgressNotifier(Downloader.ProgressListener progressListener, long j, int i, long j2, int i2) {
|
|
this.progressListener = progressListener;
|
|
this.contentLength = j;
|
|
this.totalSegments = i;
|
|
this.bytesDownloaded = j2;
|
|
this.segmentsDownloaded = i2;
|
|
}
|
|
|
|
@Override // com.google.android.exoplayer2.upstream.cache.CacheWriter.ProgressListener
|
|
public void onProgress(long j, long j2, long j3) {
|
|
long j4 = this.bytesDownloaded + j3;
|
|
this.bytesDownloaded = j4;
|
|
this.progressListener.onProgress(this.contentLength, j4, getPercentDownloaded());
|
|
}
|
|
|
|
public void onSegmentDownloaded() {
|
|
this.segmentsDownloaded++;
|
|
this.progressListener.onProgress(this.contentLength, this.bytesDownloaded, getPercentDownloaded());
|
|
}
|
|
}
|
|
}
|