blob: 8b7c8838ab319afb2d7012222e1980e8a4f83c03 [file] [log] [blame]
RoboErik8ae0f342014-02-24 18:02:08 -08001/*
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 */
RoboErikbfa153b2014-02-13 14:22:42 -080016package com.android.onemedia;
17
18import android.content.Context;
19import android.content.Intent;
Daniel Sandler45f7ee82014-06-05 02:54:13 -040020import android.graphics.Bitmap;
21import android.media.MediaMetadata;
RoboErik42ea7ee2014-05-16 16:27:35 -070022import android.media.session.MediaSession;
23import android.media.session.MediaSessionManager;
RoboErik8ae0f342014-02-24 18:02:08 -080024import android.media.session.PlaybackState;
RoboErikbfa153b2014-02-13 14:22:42 -080025import android.os.Bundle;
RoboErik8b4bffc2014-07-10 13:48:01 -070026import android.os.RemoteException;
RoboErikc785a782014-07-14 13:40:43 -070027import android.os.SystemClock;
RoboErikbfa153b2014-02-13 14:22:42 -080028import android.util.Log;
29import android.view.KeyEvent;
30
31import com.android.onemedia.playback.LocalRenderer;
32import com.android.onemedia.playback.Renderer;
RoboErik07c70772014-03-20 13:33:52 -070033import com.android.onemedia.playback.RequestUtils;
34
35import java.util.ArrayList;
Jeff Brownff0215d2014-07-14 04:05:08 -070036import java.util.List;
RoboErikbfa153b2014-02-13 14:22:42 -080037
38public class PlayerSession {
RoboErik8ae0f342014-02-24 18:02:08 -080039 private static final String TAG = "PlayerSession";
RoboErikbfa153b2014-02-13 14:22:42 -080040
RoboErik42ea7ee2014-05-16 16:27:35 -070041 protected MediaSession mSession;
RoboErikbfa153b2014-02-13 14:22:42 -080042 protected Context mContext;
RoboErik07c70772014-03-20 13:33:52 -070043 protected Renderer mRenderer;
RoboErik42ea7ee2014-05-16 16:27:35 -070044 protected MediaSession.Callback mCallback;
RoboErik8ae0f342014-02-24 18:02:08 -080045 protected Renderer.Listener mRenderListener;
Daniel Sandler45f7ee82014-06-05 02:54:13 -040046 protected MediaMetadata.Builder mMetadataBuilder;
RoboErik8ae0f342014-02-24 18:02:08 -080047
48 protected PlaybackState mPlaybackState;
49 protected Listener mListener;
RoboErik07c70772014-03-20 13:33:52 -070050
51 private String mContent;
RoboErikbfa153b2014-02-13 14:22:42 -080052
53 public PlayerSession(Context context) {
54 mContext = context;
RoboErikbfa153b2014-02-13 14:22:42 -080055 mRenderer = new LocalRenderer(context, null);
RoboErik07c70772014-03-20 13:33:52 -070056 mCallback = new SessionCb();
RoboErikbfa153b2014-02-13 14:22:42 -080057 mRenderListener = new RenderListener();
RoboErikc785a782014-07-14 13:40:43 -070058 PlaybackState.Builder psBob = new PlaybackState.Builder();
59 psBob.setActions(PlaybackState.ACTION_PAUSE | PlaybackState.ACTION_PLAY);
60 mPlaybackState = psBob.build();
RoboErikbfa153b2014-02-13 14:22:42 -080061
62 mRenderer.registerListener(mRenderListener);
Daniel Sandler45f7ee82014-06-05 02:54:13 -040063
64 initMetadata();
RoboErikbfa153b2014-02-13 14:22:42 -080065 }
66
67 public void createSession() {
Jeff Brownff0215d2014-07-14 04:05:08 -070068 releaseSession();
69
RoboErik42ea7ee2014-05-16 16:27:35 -070070 MediaSessionManager man = (MediaSessionManager) mContext
RoboErikbfa153b2014-02-13 14:22:42 -080071 .getSystemService(Context.MEDIA_SESSION_SERVICE);
72 Log.d(TAG, "Creating session for package " + mContext.getBasePackageName());
Jeff Brownff0215d2014-07-14 04:05:08 -070073
RoboErik8b4bffc2014-07-10 13:48:01 -070074 mSession = new MediaSession(mContext, "OneMedia");
RoboErik477d1192014-08-06 13:43:22 -070075 mSession.setCallback(mCallback);
RoboErikc47fa842014-05-28 17:36:42 -070076 mSession.setPlaybackState(mPlaybackState);
RoboErik477d1192014-08-06 13:43:22 -070077 mSession.setFlags(MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS
78 | MediaSession.FLAG_HANDLES_MEDIA_BUTTONS);
RoboErika8f95142014-05-05 14:23:49 -070079 mSession.setActive(true);
Daniel Sandler45f7ee82014-06-05 02:54:13 -040080 updateMetadata();
RoboErikbfa153b2014-02-13 14:22:42 -080081 }
82
83 public void onDestroy() {
Jeff Brownff0215d2014-07-14 04:05:08 -070084 releaseSession();
RoboErikbfa153b2014-02-13 14:22:42 -080085 if (mRenderer != null) {
86 mRenderer.unregisterListener(mRenderListener);
87 mRenderer.onDestroy();
88 }
89 }
90
Jeff Brownff0215d2014-07-14 04:05:08 -070091 private void releaseSession() {
92 if (mSession != null) {
93 mSession.release();
94 mSession = null;
95 }
Jeff Brownff0215d2014-07-14 04:05:08 -070096 }
97
RoboErik8ae0f342014-02-24 18:02:08 -080098 public void setListener(Listener listener) {
99 mListener = listener;
100 }
101
Jeff Browndba34ba2014-06-24 20:46:03 -0700102 public MediaSession.Token getSessionToken() {
RoboErikbfa153b2014-02-13 14:22:42 -0800103 return mSession.getSessionToken();
104 }
105
106 public void setContent(Bundle request) {
107 mRenderer.setContent(request);
RoboErik07c70772014-03-20 13:33:52 -0700108 mContent = request.getString(RequestUtils.EXTRA_KEY_SOURCE);
RoboErikbfa153b2014-02-13 14:22:42 -0800109 }
110
111 public void setNextContent(Bundle request) {
112 mRenderer.setNextContent(request);
113 }
114
Daniel Sandler45f7ee82014-06-05 02:54:13 -0400115 public void setIcon(Bitmap icon) {
116 mMetadataBuilder.putBitmap(MediaMetadata.METADATA_KEY_DISPLAY_ICON, icon);
117 updateMetadata();
118 }
119
120 private void updateMetadata() {
121 // This is a mild abuse of metadata and shouldn't be duplicated in real
122 // code
123 if (mSession != null && mSession.isActive()) {
124 mSession.setMetadata(mMetadataBuilder.build());
125 }
126 }
127
RoboErik07c70772014-03-20 13:33:52 -0700128 private void updateState(int newState) {
RoboErik79fa4632014-05-27 16:49:09 -0700129 float rate = newState == PlaybackState.STATE_PLAYING ? 1 : 0;
RoboErikf1372422014-04-23 14:38:17 -0700130 long position = mRenderer == null ? -1 : mRenderer.getSeekPosition();
RoboErikc785a782014-07-14 13:40:43 -0700131 PlaybackState.Builder bob = new PlaybackState.Builder(mPlaybackState);
132 bob.setState(newState, position, rate, SystemClock.elapsedRealtime());
133 bob.setErrorMessage(null);
134 mPlaybackState = bob.build();
RoboErikc47fa842014-05-28 17:36:42 -0700135 mSession.setPlaybackState(mPlaybackState);
RoboErik07c70772014-03-20 13:33:52 -0700136 }
137
Daniel Sandler45f7ee82014-06-05 02:54:13 -0400138 private void initMetadata() {
139 mMetadataBuilder = new MediaMetadata.Builder();
140 mMetadataBuilder.putString(MediaMetadata.METADATA_KEY_DISPLAY_TITLE,
141 "OneMedia display title");
142 mMetadataBuilder.putString(MediaMetadata.METADATA_KEY_DISPLAY_SUBTITLE,
143 "OneMedia display subtitle");
144 }
145
RoboErik8ae0f342014-02-24 18:02:08 -0800146 public interface Listener {
147 public void onPlayStateChanged(PlaybackState state);
148 }
149
150 private class RenderListener implements Renderer.Listener {
RoboErikbfa153b2014-02-13 14:22:42 -0800151
152 @Override
153 public void onError(int type, int extra, Bundle extras, Throwable error) {
RoboErik8ae0f342014-02-24 18:02:08 -0800154 Log.d(TAG, "Sending onError with type " + type + " and extra " + extra);
RoboErikc785a782014-07-14 13:40:43 -0700155 PlaybackState.Builder bob = new PlaybackState.Builder(mPlaybackState);
156 bob.setState(PlaybackState.STATE_ERROR, -1, 0, 0);
RoboErik8ae0f342014-02-24 18:02:08 -0800157 if (error != null) {
RoboErikc785a782014-07-14 13:40:43 -0700158 bob.setErrorMessage(error.getLocalizedMessage());
RoboErik8ae0f342014-02-24 18:02:08 -0800159 }
RoboErikc785a782014-07-14 13:40:43 -0700160 mPlaybackState = bob.build();
RoboErikc47fa842014-05-28 17:36:42 -0700161 mSession.setPlaybackState(mPlaybackState);
RoboErik8ae0f342014-02-24 18:02:08 -0800162 if (mListener != null) {
163 mListener.onPlayStateChanged(mPlaybackState);
164 }
RoboErikbfa153b2014-02-13 14:22:42 -0800165 }
166
167 @Override
168 public void onStateChanged(int newState) {
RoboErikf1372422014-04-23 14:38:17 -0700169 long position = -1;
170 if (mRenderer != null) {
171 position = mRenderer.getSeekPosition();
172 }
RoboErikc785a782014-07-14 13:40:43 -0700173 int pbState;
174 float rate = 0;
175 String errorMsg = null;
RoboErik8ae0f342014-02-24 18:02:08 -0800176 switch (newState) {
177 case Renderer.STATE_ENDED:
178 case Renderer.STATE_STOPPED:
RoboErikc785a782014-07-14 13:40:43 -0700179 pbState = PlaybackState.STATE_STOPPED;
RoboErik8ae0f342014-02-24 18:02:08 -0800180 break;
181 case Renderer.STATE_INIT:
182 case Renderer.STATE_PREPARING:
RoboErikc785a782014-07-14 13:40:43 -0700183 pbState = PlaybackState.STATE_BUFFERING;
RoboErik8ae0f342014-02-24 18:02:08 -0800184 break;
185 case Renderer.STATE_ERROR:
RoboErikc785a782014-07-14 13:40:43 -0700186 pbState = PlaybackState.STATE_ERROR;
RoboErik8ae0f342014-02-24 18:02:08 -0800187 break;
188 case Renderer.STATE_PAUSED:
RoboErikc785a782014-07-14 13:40:43 -0700189 pbState = PlaybackState.STATE_PAUSED;
RoboErik8ae0f342014-02-24 18:02:08 -0800190 break;
191 case Renderer.STATE_PLAYING:
RoboErikc785a782014-07-14 13:40:43 -0700192 pbState = PlaybackState.STATE_PLAYING;
193 rate = 1;
RoboErik8ae0f342014-02-24 18:02:08 -0800194 break;
195 default:
RoboErikc785a782014-07-14 13:40:43 -0700196 pbState = PlaybackState.STATE_ERROR;
197 errorMsg = "unknown state";
RoboErik8ae0f342014-02-24 18:02:08 -0800198 break;
199 }
RoboErikc785a782014-07-14 13:40:43 -0700200 PlaybackState.Builder bob = new PlaybackState.Builder(mPlaybackState);
201 bob.setState(pbState, position, rate, SystemClock.elapsedRealtime());
202 bob.setErrorMessage(errorMsg);
203 mPlaybackState = bob.build();
RoboErikc47fa842014-05-28 17:36:42 -0700204 mSession.setPlaybackState(mPlaybackState);
RoboErik8ae0f342014-02-24 18:02:08 -0800205 if (mListener != null) {
206 mListener.onPlayStateChanged(mPlaybackState);
207 }
RoboErikbfa153b2014-02-13 14:22:42 -0800208 }
209
210 @Override
211 public void onBufferingUpdate(int percent) {
212 }
213
214 @Override
215 public void onFocusLost() {
RoboErik8ae0f342014-02-24 18:02:08 -0800216 Log.d(TAG, "Focus lost, changing state to " + Renderer.STATE_PAUSED);
RoboErikf1372422014-04-23 14:38:17 -0700217 long position = mRenderer == null ? -1 : mRenderer.getSeekPosition();
RoboErikc785a782014-07-14 13:40:43 -0700218 PlaybackState.Builder bob = new PlaybackState.Builder(mPlaybackState);
219 bob.setState(PlaybackState.STATE_PAUSED, position, 0, SystemClock.elapsedRealtime());
220 bob.setErrorMessage(null);
221 mPlaybackState = bob.build();
RoboErikc47fa842014-05-28 17:36:42 -0700222 mSession.setPlaybackState(mPlaybackState);
RoboErik8ae0f342014-02-24 18:02:08 -0800223 if (mListener != null) {
224 mListener.onPlayStateChanged(mPlaybackState);
225 }
RoboErikbfa153b2014-02-13 14:22:42 -0800226 }
227
228 @Override
229 public void onNextStarted() {
230 }
231
232 }
233
RoboErik42ea7ee2014-05-16 16:27:35 -0700234 private class SessionCb extends MediaSession.Callback {
RoboErikbfa153b2014-02-13 14:22:42 -0800235 @Override
RoboErik8ae0f342014-02-24 18:02:08 -0800236 public void onPlay() {
237 mRenderer.onPlay();
238 }
239
240 @Override
241 public void onPause() {
242 mRenderer.onPause();
243 }
244 }
RoboErikbfa153b2014-02-13 14:22:42 -0800245}