/* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.onemedia.playback; import android.content.Context; import android.media.MediaPlayer; import android.os.Bundle; import java.util.ArrayList; import java.util.List; /** * TODO: Insert description here. (generated by epastern) */ public abstract class Renderer { public static final String FEATURE_SET_CONTENT = "com.android.media.SET_CONTENT"; public static final String FEATURE_SET_NEXT_CONTENT = "com.android.media.SET_NEXT_CONTENT"; public static final String FEATURE_PLAY = "com.android.media.PLAY"; public static final String FEATURE_PAUSE = "com.android.media.PAUSE"; public static final String FEATURE_NEXT = "com.android.media.NEXT"; public static final String FEATURE_PREVIOUS = "com.android.media.PREVIOUS"; public static final String FEATURE_SEEK_TO = "com.android.media.SEEK_TO"; public static final String FEATURE_STOP = "com.android.media.STOP"; // TODO move states somewhere else public static final int STATE_ERROR = 0; /** * The state MediaPlayerManager starts in before any action has been * performed. */ public static final int STATE_INIT = 1 << 0; /** * Indicates the source has been set and it is being prepared/buffered * before starting playback. */ public static final int STATE_PREPARING = 1 << 1; /** * The media is ready and playback can be started. */ public static final int STATE_READY = 1 << 2; /** * The media is currently playing. */ public static final int STATE_PLAYING = 1 << 3; /** * The media is currently paused. */ public static final int STATE_PAUSED = 1 << 4; /** * The service has been stopped and cannot be started again until a new * source has been set. */ public static final int STATE_STOPPED = 1 << 5; /** * The playback has reached the end. It can be restarted by calling play(). */ public static final int STATE_ENDED = 1 << 6; // TODO decide on proper way of describing features protected List mFeatures = new ArrayList(); protected List mListeners = new ArrayList(); public Renderer(Context context, Bundle params) { onCreate(params); initFeatures(params); } abstract public void setContent(Bundle request); public void onCreate(Bundle params) { // Do nothing by default } public void setNextContent(Bundle request) { throw new UnsupportedOperationException("setNextContent() is not supported."); } public List getFeatures() { return mFeatures; } public boolean onPlay() { // TODO consider making these log warnings instead of crashes (or // Log.wtf) // throw new UnsupportedOperationException("play is not supported."); return false; } public boolean onPause() { // throw new UnsupportedOperationException("pause is not supported."); return false; } public boolean onNext() { // throw new UnsupportedOperationException("next is not supported."); return false; } public boolean onPrevious() { // throw new // UnsupportedOperationException("previous is not supported."); return false; } public boolean onStop() { // throw new UnsupportedOperationException("stop is not supported."); return false; } public boolean onSeekTo(int time) { // throw new UnsupportedOperationException("seekTo is not supported."); return false; } public long getSeekPosition() { // throw new // UnsupportedOperationException("getSeekPosition is not supported."); return -1; } public long getDuration() { // throw new // UnsupportedOperationException("getDuration is not supported."); return -1; } public int getPlayState() { // throw new // UnsupportedOperationException("getPlayState is not supported."); return 0; } public void onDestroy() { // Do nothing by default } public void registerListener(Listener listener) { if (!mListeners.contains(listener)) { mListeners.add(listener); } } public void unregisterListener(Listener listener) { mListeners.remove(listener); } protected void initFeatures(Bundle params) { mFeatures.add(FEATURE_SET_CONTENT); } protected void pushOnError(int type, int extra, Bundle extras, Throwable error) { for (Listener listener : mListeners) { listener.onError(type, extra, extras, error); } } protected void pushOnStateChanged(int newState) { for (Listener listener : mListeners) { listener.onStateChanged(newState); } } protected void pushOnBufferingUpdate(int percent) { for (Listener listener : mListeners) { listener.onBufferingUpdate(percent); } } protected void pushOnFocusLost() { for (Listener listener : mListeners) { listener.onFocusLost(); } } protected void pushOnNextStarted() { for (Listener listener : mListeners) { listener.onNextStarted(); } } public interface Listener { public static final int ERROR_LOAD_FAILED = 1770; public static final int ERROR_PREPARE_ERROR = 1771; public static final int ERROR_PLAYBACK_FAILED = 1772; /** * When an error occurs onError will be called but not onStateChanged. * The Manager will remain in the error state until * {@link #setContent()} is called again. */ public void onError(int type, int extra, Bundle extras, Throwable error); /** * onStateChanged will be called whenever the state of the manager * transitions except to an error state. */ public void onStateChanged(int newState); /** * This is a passthrough of * {@link MediaPlayer.OnBufferingUpdateListener}. */ public void onBufferingUpdate(int percent); /** * Called when audio focus is lost and it is not transient or ducking. */ public void onFocusLost(); /** * Called when the next item was started playing. Only called if a next * item has been set and the current item has ended. */ public void onNextStarted(); } }