19730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson/*
29730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson * Copyright (C) 2011 The Android Open Source Project
39730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson *
49730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson * Licensed under the Apache License, Version 2.0 (the "License");
59730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson * you may not use this file except in compliance with the License.
69730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson * You may obtain a copy of the License at
79730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson *
89730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson *      http://www.apache.org/licenses/LICENSE-2.0
99730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson *
109730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson * Unless required by applicable law or agreed to in writing, software
119730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson * distributed under the License is distributed on an "AS IS" BASIS,
129730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson * See the License for the specific language governing permissions and
149730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson * limitations under the License.
159730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson */
169730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
179730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudsonpackage com.android.ex.variablespeed;
189730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
199730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudsonimport android.media.MediaPlayer;
209730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
219730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudsonimport java.util.concurrent.BlockingQueue;
229730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudsonimport java.util.concurrent.LinkedBlockingQueue;
239730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudsonimport java.util.concurrent.TimeUnit;
249730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudsonimport java.util.concurrent.TimeoutException;
259730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
269730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudsonimport javax.annotation.concurrent.ThreadSafe;
279730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
289730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson/** Implementation of {@link MediaPlayer.OnCompletionListener} that we can wait for in tests. */
299730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson@ThreadSafe
309730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudsonpublic class AwaitableErrorListener implements MediaPlayer.OnErrorListener {
319730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    private final BlockingQueue<Object> mQueue = new LinkedBlockingQueue<Object>();
329730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    private volatile boolean mOnErrorReturnValue = true;
339730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
349730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    @Override
359730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    public boolean onError(MediaPlayer mp, int what, int extra) {
369730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        addAnObjectToTheQueue();
379730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        return mOnErrorReturnValue;
389730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
399730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
409730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    public void setOnErrorReturnValue(boolean value) {
419730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        mOnErrorReturnValue = value;
429730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
439730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
449730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    private void addAnObjectToTheQueue() {
459730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        try {
469730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson            mQueue.put(new Object());
479730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        } catch (InterruptedException e) {
489730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson            // This should not happen in practice, the queue is unbounded so this method will not
499730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson            // block.
509730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson            // If this thread is using interrupt to shut down, preserve interrupt status and return.
519730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson            Thread.currentThread().interrupt();
529730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        }
539730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
549730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
559730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    public void awaitOneCallback(long timeout, TimeUnit unit) throws InterruptedException,
569730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson            TimeoutException {
579730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        if (mQueue.poll(timeout, unit) == null) {
589730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson            throw new TimeoutException();
599730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        }
609730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
619730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
629730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    public void assertNoMoreCallbacks() {
639730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        if (mQueue.peek() != null) {
649730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson            throw new IllegalStateException("there was an unexpected callback on the queue");
659730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson        }
669730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    }
679730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson}
68