1/*
2 * Copyright (C) 2014 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 */
16package com.android.onemedia.playback;
17
18import android.content.Context;
19import android.media.MediaPlayer;
20import android.os.Bundle;
21
22import java.util.ArrayList;
23import java.util.List;
24
25/**
26 * TODO: Insert description here. (generated by epastern)
27 */
28public abstract class Renderer {
29    public static final String FEATURE_SET_CONTENT = "com.android.media.SET_CONTENT";
30    public static final String FEATURE_SET_NEXT_CONTENT = "com.android.media.SET_NEXT_CONTENT";
31    public static final String FEATURE_PLAY = "com.android.media.PLAY";
32    public static final String FEATURE_PAUSE = "com.android.media.PAUSE";
33    public static final String FEATURE_NEXT = "com.android.media.NEXT";
34    public static final String FEATURE_PREVIOUS = "com.android.media.PREVIOUS";
35    public static final String FEATURE_SEEK_TO = "com.android.media.SEEK_TO";
36    public static final String FEATURE_STOP = "com.android.media.STOP";
37    // TODO move states somewhere else
38    public static final int STATE_ERROR = 0;
39    /**
40     * The state MediaPlayerManager starts in before any action has been
41     * performed.
42     */
43    public static final int STATE_INIT = 1 << 0;
44    /**
45     * Indicates the source has been set and it is being prepared/buffered
46     * before starting playback.
47     */
48    public static final int STATE_PREPARING = 1 << 1;
49    /**
50     * The media is ready and playback can be started.
51     */
52    public static final int STATE_READY = 1 << 2;
53    /**
54     * The media is currently playing.
55     */
56    public static final int STATE_PLAYING = 1 << 3;
57    /**
58     * The media is currently paused.
59     */
60    public static final int STATE_PAUSED = 1 << 4;
61    /**
62     * The service has been stopped and cannot be started again until a new
63     * source has been set.
64     */
65    public static final int STATE_STOPPED = 1 << 5;
66    /**
67     * The playback has reached the end. It can be restarted by calling play().
68     */
69    public static final int STATE_ENDED = 1 << 6;
70
71    // TODO decide on proper way of describing features
72    protected List<String> mFeatures = new ArrayList<String>();
73    protected List<Listener> mListeners = new ArrayList<Listener>();
74
75    public Renderer(Context context, Bundle params) {
76        onCreate(params);
77        initFeatures(params);
78    }
79
80    abstract public void setContent(Bundle request);
81
82    public void onCreate(Bundle params) {
83        // Do nothing by default
84    }
85
86    public void setNextContent(Bundle request) {
87        throw new UnsupportedOperationException("setNextContent() is not supported.");
88    }
89
90    public List<String> getFeatures() {
91        return mFeatures;
92    }
93
94    public boolean onPlay() {
95        // TODO consider making these log warnings instead of crashes (or
96        // Log.wtf)
97        // throw new UnsupportedOperationException("play is not supported.");
98        return false;
99    }
100
101    public boolean onPause() {
102        // throw new UnsupportedOperationException("pause is not supported.");
103        return false;
104    }
105
106    public boolean onNext() {
107        // throw new UnsupportedOperationException("next is not supported.");
108        return false;
109    }
110
111    public boolean onPrevious() {
112        // throw new
113        // UnsupportedOperationException("previous is not supported.");
114        return false;
115    }
116
117    public boolean onStop() {
118        // throw new UnsupportedOperationException("stop is not supported.");
119        return false;
120    }
121
122    public boolean onSeekTo(int time) {
123        // throw new UnsupportedOperationException("seekTo is not supported.");
124        return false;
125    }
126
127    public long getSeekPosition() {
128        // throw new
129        // UnsupportedOperationException("getSeekPosition is not supported.");
130        return -1;
131    }
132
133    public long getDuration() {
134        // throw new
135        // UnsupportedOperationException("getDuration is not supported.");
136        return -1;
137    }
138
139    public int getPlayState() {
140        // throw new
141        // UnsupportedOperationException("getPlayState is not supported.");
142        return 0;
143    }
144
145    public void onDestroy() {
146        // Do nothing by default
147    }
148
149    public void registerListener(Listener listener) {
150        if (!mListeners.contains(listener)) {
151            mListeners.add(listener);
152        }
153    }
154
155    public void unregisterListener(Listener listener) {
156        mListeners.remove(listener);
157    }
158
159    protected void initFeatures(Bundle params) {
160        mFeatures.add(FEATURE_SET_CONTENT);
161    }
162
163    protected void pushOnError(int type, int extra, Bundle extras, Throwable error) {
164        for (Listener listener : mListeners) {
165            listener.onError(type, extra, extras, error);
166        }
167    }
168
169    protected void pushOnStateChanged(int newState) {
170        for (Listener listener : mListeners) {
171            listener.onStateChanged(newState);
172        }
173    }
174
175    protected void pushOnBufferingUpdate(int percent) {
176        for (Listener listener : mListeners) {
177            listener.onBufferingUpdate(percent);
178        }
179    }
180
181    protected void pushOnFocusLost() {
182        for (Listener listener : mListeners) {
183            listener.onFocusLost();
184        }
185    }
186
187    protected void pushOnNextStarted() {
188        for (Listener listener : mListeners) {
189            listener.onNextStarted();
190        }
191    }
192
193    public interface Listener {
194        public static final int ERROR_LOAD_FAILED = 1770;
195        public static final int ERROR_PREPARE_ERROR = 1771;
196        public static final int ERROR_PLAYBACK_FAILED = 1772;
197
198        /**
199         * When an error occurs onError will be called but not onStateChanged.
200         * The Manager will remain in the error state until
201         * {@link #setContent()} is called again.
202         */
203        public void onError(int type, int extra, Bundle extras,
204                Throwable error);
205
206        /**
207         * onStateChanged will be called whenever the state of the manager
208         * transitions except to an error state.
209         */
210        public void onStateChanged(int newState);
211
212        /**
213         * This is a passthrough of
214         * {@link MediaPlayer.OnBufferingUpdateListener}.
215         */
216        public void onBufferingUpdate(int percent);
217
218        /**
219         * Called when audio focus is lost and it is not transient or ducking.
220         */
221        public void onFocusLost();
222
223        /**
224         * Called when the next item was started playing. Only called if a next
225         * item has been set and the current item has ended.
226         */
227        public void onNextStarted();
228    }
229}
230