1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.google.android.exoplayer2.upstream; 17 18 import static com.google.android.exoplayer2.util.Util.castNonNull; 19 20 import androidx.annotation.Nullable; 21 import java.util.ArrayList; 22 23 /** 24 * Base {@link DataSource} implementation to keep a list of {@link TransferListener}s. 25 * 26 * <p>Subclasses must call {@link #transferInitializing(DataSpec)}, {@link 27 * #transferStarted(DataSpec)}, {@link #bytesTransferred(int)}, and {@link #transferEnded()} to 28 * inform listeners of data transfers. 29 */ 30 public abstract class BaseDataSource implements DataSource { 31 32 private final boolean isNetwork; 33 private final ArrayList<TransferListener> listeners; 34 35 private int listenerCount; 36 @Nullable private DataSpec dataSpec; 37 38 /** 39 * Creates base data source. 40 * 41 * @param isNetwork Whether the data source loads data through a network. 42 */ BaseDataSource(boolean isNetwork)43 protected BaseDataSource(boolean isNetwork) { 44 this.isNetwork = isNetwork; 45 this.listeners = new ArrayList<>(/* initialCapacity= */ 1); 46 } 47 48 @Override addTransferListener(TransferListener transferListener)49 public final void addTransferListener(TransferListener transferListener) { 50 if (!listeners.contains(transferListener)) { 51 listeners.add(transferListener); 52 listenerCount++; 53 } 54 } 55 56 /** 57 * Notifies listeners that data transfer for the specified {@link DataSpec} is being initialized. 58 * 59 * @param dataSpec {@link DataSpec} describing the data for initializing transfer. 60 */ transferInitializing(DataSpec dataSpec)61 protected final void transferInitializing(DataSpec dataSpec) { 62 for (int i = 0; i < listenerCount; i++) { 63 listeners.get(i).onTransferInitializing(/* source= */ this, dataSpec, isNetwork); 64 } 65 } 66 67 /** 68 * Notifies listeners that data transfer for the specified {@link DataSpec} started. 69 * 70 * @param dataSpec {@link DataSpec} describing the data being transferred. 71 */ transferStarted(DataSpec dataSpec)72 protected final void transferStarted(DataSpec dataSpec) { 73 this.dataSpec = dataSpec; 74 for (int i = 0; i < listenerCount; i++) { 75 listeners.get(i).onTransferStart(/* source= */ this, dataSpec, isNetwork); 76 } 77 } 78 79 /** 80 * Notifies listeners that bytes were transferred. 81 * 82 * @param bytesTransferred The number of bytes transferred since the previous call to this method 83 * (or if the first call, since the transfer was started). 84 */ bytesTransferred(int bytesTransferred)85 protected final void bytesTransferred(int bytesTransferred) { 86 DataSpec dataSpec = castNonNull(this.dataSpec); 87 for (int i = 0; i < listenerCount; i++) { 88 listeners 89 .get(i) 90 .onBytesTransferred(/* source= */ this, dataSpec, isNetwork, bytesTransferred); 91 } 92 } 93 94 /** Notifies listeners that a transfer ended. */ transferEnded()95 protected final void transferEnded() { 96 DataSpec dataSpec = castNonNull(this.dataSpec); 97 for (int i = 0; i < listenerCount; i++) { 98 listeners.get(i).onTransferEnd(/* source= */ this, dataSpec, isNetwork); 99 } 100 this.dataSpec = null; 101 } 102 } 103