1 /* 2 * Copyright 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 17 package android.media.cts; 18 19 import android.media.AudioAttributes; 20 import android.media.DataSourceDesc; 21 import android.media.MediaPlayerBase; 22 import androidx.annotation.NonNull; 23 import android.util.ArrayMap; 24 25 import java.util.List; 26 import java.util.concurrent.CountDownLatch; 27 import java.util.concurrent.Executor; 28 29 /** 30 * A mock implementation of {@link MediaPlayerBase} for testing. 31 */ 32 public class MockPlayer extends MediaPlayerBase { 33 public final CountDownLatch mCountDownLatch; 34 35 public boolean mPlayCalled; 36 public boolean mPauseCalled; 37 public boolean mStopCalled; 38 public boolean mPrepareCalled; 39 public boolean mSeekToCalled; 40 public long mSeekPosition; 41 public long mCurrentPosition; 42 public long mBufferedPosition; 43 public @PlayerState int mLastPlayerState; 44 45 public ArrayMap<PlayerEventCallback, Executor> mCallbacks = new ArrayMap<>(); 46 47 private AudioAttributes mAudioAttributes; 48 49 public MockPlayer(int count) { 50 mCountDownLatch = (count > 0) ? new CountDownLatch(count) : null; 51 } 52 53 @Override 54 public void close() { 55 // no-op 56 } 57 58 @Override 59 public void reset() { 60 // no-op 61 } 62 63 @Override 64 public void play() { 65 mPlayCalled = true; 66 if (mCountDownLatch != null) { 67 mCountDownLatch.countDown(); 68 } 69 } 70 71 @Override 72 public void pause() { 73 mPauseCalled = true; 74 if (mCountDownLatch != null) { 75 mCountDownLatch.countDown(); 76 } 77 } 78 79 // TODO: Uncomment or remove 80 /* 81 @Override 82 public void stop() { 83 mStopCalled = true; 84 if (mCountDownLatch != null) { 85 mCountDownLatch.countDown(); 86 } 87 } 88 */ 89 90 @Override 91 public void prepare() { 92 mPrepareCalled = true; 93 if (mCountDownLatch != null) { 94 mCountDownLatch.countDown(); 95 } 96 } 97 98 @Override 99 public void seekTo(long pos) { 100 mSeekToCalled = true; 101 mSeekPosition = pos; 102 if (mCountDownLatch != null) { 103 mCountDownLatch.countDown(); 104 } 105 } 106 107 @Override 108 public void skipToNext() { 109 // No-op. This skipToNext() means 'skip to next item in the setNextDataSources()' 110 } 111 112 @Override 113 public int getPlayerState() { 114 return mLastPlayerState; 115 } 116 117 @Override 118 public long getCurrentPosition() { 119 return mCurrentPosition; 120 } 121 122 @Override 123 public long getBufferedPosition() { 124 return mBufferedPosition; 125 } 126 127 @Override 128 public int getBufferingState() { 129 // TODO: implement this 130 return -1; 131 } 132 133 @Override 134 public void registerPlayerEventCallback(@NonNull Executor executor, 135 @NonNull PlayerEventCallback callback) { 136 mCallbacks.put(callback, executor); 137 } 138 139 @Override 140 public void unregisterPlayerEventCallback(@NonNull PlayerEventCallback callback) { 141 mCallbacks.remove(callback); 142 } 143 144 public void notifyPlaybackState(final int state) { 145 mLastPlayerState = state; 146 for (int i = 0; i < mCallbacks.size(); i++) { 147 final PlayerEventCallback callback = mCallbacks.keyAt(i); 148 final Executor executor = mCallbacks.valueAt(i); 149 executor.execute(() -> callback.onPlayerStateChanged(this, state)); 150 } 151 } 152 153 public void notifyCurrentDataSourceChanged(DataSourceDesc dsd) { 154 for (int i = 0; i < mCallbacks.size(); i++) { 155 final PlayerEventCallback callback = mCallbacks.keyAt(i); 156 final Executor executor = mCallbacks.valueAt(i); 157 executor.execute(() -> callback.onCurrentDataSourceChanged(this, dsd)); 158 } 159 } 160 161 public void notifyMediaPrepared(DataSourceDesc dsd) { 162 for (int i = 0; i < mCallbacks.size(); i++) { 163 final PlayerEventCallback callback = mCallbacks.keyAt(i); 164 final Executor executor = mCallbacks.valueAt(i); 165 executor.execute(() -> callback.onMediaPrepared(this, dsd)); 166 } 167 } 168 169 public void notifyBufferingStateChanged(DataSourceDesc dsd, @BuffState int buffState) { 170 for (int i = 0; i < mCallbacks.size(); i++) { 171 final PlayerEventCallback callback = mCallbacks.keyAt(i); 172 final Executor executor = mCallbacks.valueAt(i); 173 executor.execute(() -> callback.onBufferingStateChanged(this, dsd, buffState)); 174 } 175 } 176 177 public void notifyError(int what) { 178 for (int i = 0; i < mCallbacks.size(); i++) { 179 final PlayerEventCallback callback = mCallbacks.keyAt(i); 180 final Executor executor = mCallbacks.valueAt(i); 181 // TODO: Uncomment or remove 182 //executor.execute(() -> callback.onError(null, what, 0)); 183 } 184 } 185 186 @Override 187 public void setAudioAttributes(AudioAttributes attributes) { 188 mAudioAttributes = attributes; 189 } 190 191 @Override 192 public AudioAttributes getAudioAttributes() { 193 return mAudioAttributes; 194 } 195 196 @Override 197 public void setDataSource(@NonNull DataSourceDesc dsd) { 198 // TODO: Implement this 199 } 200 201 @Override 202 public void setNextDataSource(@NonNull DataSourceDesc dsd) { 203 // TODO: Implement this 204 } 205 206 @Override 207 public void setNextDataSources(@NonNull List<DataSourceDesc> dsds) { 208 // TODO: Implement this 209 } 210 211 @Override 212 public DataSourceDesc getCurrentDataSource() { 213 // TODO: Implement this 214 return null; 215 } 216 217 @Override 218 public void loopCurrent(boolean loop) { 219 // TODO: implement this 220 } 221 222 @Override 223 public void setPlaybackSpeed(float speed) { 224 // TODO: implement this 225 } 226 227 @Override 228 public void setPlayerVolume(float volume) { 229 // TODO: implement this 230 } 231 232 @Override 233 public float getPlayerVolume() { 234 // TODO: implement this 235 return -1; 236 } 237 } 238