/* * Copyright (C) 2015 AChep@xda <artemchep@gmail.com> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. */ package com.achep.acdisplay.services.media; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.text.TextUtils; import com.achep.base.async.TaskQueueThread; import java.lang.ref.Reference; import java.lang.ref.WeakReference; /** * @author Artem Chepurnoy */ public class MediaControllerAsyncWrapper extends MediaController2 { private final Object monitor = new Object(); private final MediaController2 mMediaController; private T mThread; public MediaControllerAsyncWrapper(@NonNull MediaController2 mc) { super(mc.mContext); mMediaController = mc; } @Override public void registerListener(@NonNull MediaListener listener) { mMediaController.registerListener(listener); } @Override public void unregisterListener(@NonNull MediaListener listener) { mMediaController.unregisterListener(listener); } @Override public void onStart(Object... objects) { mMediaController.onStart(objects); synchronized (monitor) { // Init a new thread. mThread = new T(mMediaController); // mThread.start(); } } @Override public void onStop(Object... objects) { synchronized (monitor) { // Force stop the thread. // mThread.finish(true); } mMediaController.onStop(objects); } //-- THREADING ------------------------------------------------------------ private static class T extends TaskQueueThread<E> { private final Reference<MediaController2> mMediaControllerRef; public T(@NonNull MediaController2 mc) { mMediaControllerRef = new WeakReference<>(mc); } @Override protected void onHandleTask(E object) { MediaController2 mc = mMediaControllerRef.get(); if (mc == null) { mRunning = false; return; } if (TextUtils.equals(object.id, mc.getMetadata().id)) { object.run(mc); } } @Override public void sendTask(@NonNull E object) { onHandleTask(object); } @Override protected boolean isLost() { return false; } } /** * Represents one single event. */ private static abstract class E { @Nullable public final String id; public E(@Nullable String id) { this.id = id; } public abstract void run(@NonNull MediaController2 mc); } /** * An event to seek to song's specific position. * * @author Artem Chepurnoy */ private static class EventSeekTo extends E { public final long position; public EventSeekTo(@Nullable String id, long position) { super(id); this.position = position; } @Override public void run(@NonNull MediaController2 mc) { mc.seekTo(position); } } /** * An event to send a media action. * * @author Artem Chepurnoy */ private static class EventMediaAction extends E { public final int action; public EventMediaAction(@Nullable String id, int action) { super(id); this.action = action; } @Override public void run(@NonNull MediaController2 mc) { mc.sendMediaAction(action); } } //-- BASIC METHODS -------------------------------------------------------- /** * {@inheritDoc} */ @Override public void sendMediaAction(int action) { synchronized (monitor) { mThread.sendTask(new EventMediaAction( mMediaController.getMetadata().id, action)); } } /** * {@inheritDoc} */ @Override public void seekTo(long position) { synchronized (monitor) { mThread.sendTask(new EventSeekTo( mMediaController.getMetadata().id, position)); } } /** * {@inheritDoc} */ @Override public long getPlaybackBufferedPosition() { return mMediaController.getPlaybackBufferedPosition(); } /** * {@inheritDoc} */ @Override public long getPlaybackPosition() { return mMediaController.getPlaybackPosition(); } /** * {@inheritDoc} */ @NonNull @Override public Metadata getMetadata() { return mMediaController.getMetadata(); } /** * {@inheritDoc} */ @Override public int getPlaybackState() { return mMediaController.getPlaybackState(); } }