165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko/* 265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * Copyright (C) 2016 The Android Open Source Project 365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * 465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * Licensed under the Apache License, Version 2.0 (the "License"); 565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * you may not use this file except in compliance with the License. 665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * You may obtain a copy of the License at 765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * 865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * http://www.apache.org/licenses/LICENSE-2.0 965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * 1065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * Unless required by applicable law or agreed to in writing, software 1165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * distributed under the License is distributed on an "AS IS" BASIS, 1265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * See the License for the specific language governing permissions and 1465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * limitations under the License 1565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko */ 1665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 17633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalkopackage com.android.tv.dvr.ui.playback; 1865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 1965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.app.Activity; 20d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport android.content.Intent; 2165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.graphics.Bitmap; 2265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.graphics.BitmapFactory; 2365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.media.MediaMetadata; 2465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.media.session.MediaController; 2565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.media.session.MediaSession; 2665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.media.session.PlaybackState; 2765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.media.tv.TvContract; 2865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.os.AsyncTask; 2965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.support.annotation.Nullable; 3065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.text.TextUtils; 3165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport com.android.tv.R; 32944779887775bd950cf1abf348d2df461593f6abLive Channels Teamimport com.android.tv.TvSingletons; 3365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport com.android.tv.data.ChannelDataManager; 340cc0713c1bf8027642987b750b80217569d2932aLive Channels Teamimport com.android.tv.data.api.Channel; 35633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalkoimport com.android.tv.dvr.DvrWatchedPositionManager; 36633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalkoimport com.android.tv.dvr.data.RecordedProgram; 3765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport com.android.tv.util.TimeShiftUtils; 38d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalkoimport com.android.tv.util.Utils; 390cc0713c1bf8027642987b750b80217569d2932aLive Channels Teamimport com.android.tv.util.images.ImageLoader; 4065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 41633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalkoclass DvrPlaybackMediaSessionHelper { 4265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko private static final String TAG = "DvrPlaybackMediaSessionHelper"; 4365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko private static final boolean DEBUG = false; 4465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 4565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko private int mNowPlayingCardWidth; 4665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko private int mNowPlayingCardHeight; 4765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko private int mSpeedLevel; 4865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko private long mProgramDurationMs; 4965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 5065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko private Activity mActivity; 5165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko private DvrPlayer mDvrPlayer; 5265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko private MediaSession mMediaSession; 5365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko private final DvrWatchedPositionManager mDvrWatchedPositionManager; 5465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko private final ChannelDataManager mChannelDataManager; 5565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 5695961816a768da387f0b5523cf4363ace2044089Nick Chalko public DvrPlaybackMediaSessionHelper( 5795961816a768da387f0b5523cf4363ace2044089Nick Chalko Activity activity, 5895961816a768da387f0b5523cf4363ace2044089Nick Chalko String mediaSessionTag, 5995961816a768da387f0b5523cf4363ace2044089Nick Chalko DvrPlayer dvrPlayer, 6095961816a768da387f0b5523cf4363ace2044089Nick Chalko DvrPlaybackOverlayFragment overlayFragment) { 6165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mActivity = activity; 6265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mDvrPlayer = dvrPlayer; 6365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mDvrWatchedPositionManager = 64944779887775bd950cf1abf348d2df461593f6abLive Channels Team TvSingletons.getSingletons(activity).getDvrWatchedPositionManager(); 65944779887775bd950cf1abf348d2df461593f6abLive Channels Team mChannelDataManager = TvSingletons.getSingletons(activity).getChannelDataManager(); 6695961816a768da387f0b5523cf4363ace2044089Nick Chalko mDvrPlayer.setCallback( 6795961816a768da387f0b5523cf4363ace2044089Nick Chalko new DvrPlayer.DvrPlayerCallback() { 6895961816a768da387f0b5523cf4363ace2044089Nick Chalko @Override 6995961816a768da387f0b5523cf4363ace2044089Nick Chalko public void onPlaybackStateChanged(int playbackState, int playbackSpeed) { 7095961816a768da387f0b5523cf4363ace2044089Nick Chalko updateMediaSessionPlaybackState(); 7195961816a768da387f0b5523cf4363ace2044089Nick Chalko } 7265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 7395961816a768da387f0b5523cf4363ace2044089Nick Chalko @Override 7495961816a768da387f0b5523cf4363ace2044089Nick Chalko public void onPlaybackPositionChanged(long positionMs) { 7595961816a768da387f0b5523cf4363ace2044089Nick Chalko updateMediaSessionPlaybackState(); 7695961816a768da387f0b5523cf4363ace2044089Nick Chalko if (mDvrPlayer.isPlaybackPrepared()) { 7795961816a768da387f0b5523cf4363ace2044089Nick Chalko mDvrWatchedPositionManager.setWatchedPosition( 7895961816a768da387f0b5523cf4363ace2044089Nick Chalko mDvrPlayer.getProgram().getId(), positionMs); 7995961816a768da387f0b5523cf4363ace2044089Nick Chalko } 8095961816a768da387f0b5523cf4363ace2044089Nick Chalko } 81d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko 8295961816a768da387f0b5523cf4363ace2044089Nick Chalko @Override 8395961816a768da387f0b5523cf4363ace2044089Nick Chalko public void onPlaybackEnded() { 8495961816a768da387f0b5523cf4363ace2044089Nick Chalko // TODO: Deal with watched over recordings in DVR library 8595961816a768da387f0b5523cf4363ace2044089Nick Chalko RecordedProgram nextEpisode = 8695961816a768da387f0b5523cf4363ace2044089Nick Chalko overlayFragment.getNextEpisode(mDvrPlayer.getProgram()); 8795961816a768da387f0b5523cf4363ace2044089Nick Chalko if (nextEpisode == null) { 8895961816a768da387f0b5523cf4363ace2044089Nick Chalko mDvrPlayer.reset(); 8995961816a768da387f0b5523cf4363ace2044089Nick Chalko mActivity.finish(); 9095961816a768da387f0b5523cf4363ace2044089Nick Chalko } else { 9195961816a768da387f0b5523cf4363ace2044089Nick Chalko Intent intent = new Intent(activity, DvrPlaybackActivity.class); 9295961816a768da387f0b5523cf4363ace2044089Nick Chalko intent.putExtra( 9395961816a768da387f0b5523cf4363ace2044089Nick Chalko Utils.EXTRA_KEY_RECORDED_PROGRAM_ID, nextEpisode.getId()); 9495961816a768da387f0b5523cf4363ace2044089Nick Chalko mActivity.startActivity(intent); 9595961816a768da387f0b5523cf4363ace2044089Nick Chalko } 9695961816a768da387f0b5523cf4363ace2044089Nick Chalko } 9795961816a768da387f0b5523cf4363ace2044089Nick Chalko }); 9865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko initializeMediaSession(mediaSessionTag); 9965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 10065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 10195961816a768da387f0b5523cf4363ace2044089Nick Chalko /** Stops DVR player and release media session. */ 10265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko public void release() { 10365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (mDvrPlayer != null) { 10465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mDvrPlayer.reset(); 10565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 10665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (mMediaSession != null) { 10765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mMediaSession.release(); 108633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko mMediaSession = null; 10965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 11065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 11165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 11295961816a768da387f0b5523cf4363ace2044089Nick Chalko /** Updates media session's playback state and speed. */ 11365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko public void updateMediaSessionPlaybackState() { 11495961816a768da387f0b5523cf4363ace2044089Nick Chalko mMediaSession.setPlaybackState( 11595961816a768da387f0b5523cf4363ace2044089Nick Chalko new PlaybackState.Builder() 11695961816a768da387f0b5523cf4363ace2044089Nick Chalko .setState( 11795961816a768da387f0b5523cf4363ace2044089Nick Chalko mDvrPlayer.getPlaybackState(), 11895961816a768da387f0b5523cf4363ace2044089Nick Chalko mDvrPlayer.getPlaybackPosition(), 11995961816a768da387f0b5523cf4363ace2044089Nick Chalko mSpeedLevel) 12095961816a768da387f0b5523cf4363ace2044089Nick Chalko .build()); 12165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 12265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 12365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko /** 12465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * Sets the recorded program for playback. 12565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * 12665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * @param program The recorded program to play. {@code null} to reset the DVR player. 12765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko */ 12865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko public void setupPlayback(RecordedProgram program, long seekPositionMs) { 12965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (program != null) { 13065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mDvrPlayer.setProgram(program, seekPositionMs); 13165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko setupMediaSession(program); 13265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } else { 13365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mDvrPlayer.reset(); 13465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mMediaSession.setActive(false); 13565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 13665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 13765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 13895961816a768da387f0b5523cf4363ace2044089Nick Chalko /** Returns the recorded program now playing. */ 13965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko public RecordedProgram getProgram() { 14065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return mDvrPlayer.getProgram(); 14165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 14265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 14395961816a768da387f0b5523cf4363ace2044089Nick Chalko /** Checks if the recorded program is the same as now playing one. */ 14465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko public boolean isCurrentProgram(RecordedProgram program) { 145d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko return program != null && program.equals(getProgram()); 14665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 14765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 14895961816a768da387f0b5523cf4363ace2044089Nick Chalko /** Returns playback state. */ 14965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko public int getPlaybackState() { 15065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return mDvrPlayer.getPlaybackState(); 15165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 15265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 15395961816a768da387f0b5523cf4363ace2044089Nick Chalko /** Returns the underlying DVR player. */ 15465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko public DvrPlayer getDvrPlayer() { 15565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return mDvrPlayer; 15665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 15765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 15865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko private void initializeMediaSession(String mediaSessionTag) { 15965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mMediaSession = new MediaSession(mActivity, mediaSessionTag); 16095961816a768da387f0b5523cf4363ace2044089Nick Chalko mMediaSession.setFlags( 16195961816a768da387f0b5523cf4363ace2044089Nick Chalko MediaSession.FLAG_HANDLES_MEDIA_BUTTONS 16295961816a768da387f0b5523cf4363ace2044089Nick Chalko | MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS); 16395961816a768da387f0b5523cf4363ace2044089Nick Chalko mNowPlayingCardWidth = 16495961816a768da387f0b5523cf4363ace2044089Nick Chalko mActivity.getResources().getDimensionPixelSize(R.dimen.notif_card_img_max_width); 16595961816a768da387f0b5523cf4363ace2044089Nick Chalko mNowPlayingCardHeight = 16695961816a768da387f0b5523cf4363ace2044089Nick Chalko mActivity.getResources().getDimensionPixelSize(R.dimen.notif_card_img_height); 16765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mMediaSession.setCallback(new MediaSessionCallback()); 16865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mActivity.setMediaController( 16965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko new MediaController(mActivity, mMediaSession.getSessionToken())); 17065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko updateMediaSessionPlaybackState(); 17165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 17265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 17365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko private void setupMediaSession(RecordedProgram program) { 17465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mProgramDurationMs = program.getDurationMillis(); 17565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko String cardTitleText = program.getTitle(); 17665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (TextUtils.isEmpty(cardTitleText)) { 17765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko Channel channel = mChannelDataManager.getChannel(program.getChannelId()); 17895961816a768da387f0b5523cf4363ace2044089Nick Chalko cardTitleText = 17995961816a768da387f0b5523cf4363ace2044089Nick Chalko (channel != null) 18095961816a768da387f0b5523cf4363ace2044089Nick Chalko ? channel.getDisplayName() 18195961816a768da387f0b5523cf4363ace2044089Nick Chalko : mActivity.getString(R.string.no_program_information); 18265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 18395961816a768da387f0b5523cf4363ace2044089Nick Chalko final MediaMetadata currentMetadata = 18495961816a768da387f0b5523cf4363ace2044089Nick Chalko updateMetadataTextInfo( 18595961816a768da387f0b5523cf4363ace2044089Nick Chalko program.getId(), 18695961816a768da387f0b5523cf4363ace2044089Nick Chalko cardTitleText, 18795961816a768da387f0b5523cf4363ace2044089Nick Chalko program.getDescription(), 18895961816a768da387f0b5523cf4363ace2044089Nick Chalko mProgramDurationMs); 18965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko String posterArtUri = program.getPosterArtUri(); 19065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (posterArtUri == null) { 19165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko posterArtUri = TvContract.buildChannelLogoUri(program.getChannelId()).toString(); 19265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 193633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko updatePosterArt(program, currentMetadata, null, posterArtUri); 19465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mMediaSession.setActive(true); 19565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 19665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 19795961816a768da387f0b5523cf4363ace2044089Nick Chalko private void updatePosterArt( 19895961816a768da387f0b5523cf4363ace2044089Nick Chalko RecordedProgram program, 19995961816a768da387f0b5523cf4363ace2044089Nick Chalko MediaMetadata currentMetadata, 20095961816a768da387f0b5523cf4363ace2044089Nick Chalko @Nullable Bitmap posterArt, 20195961816a768da387f0b5523cf4363ace2044089Nick Chalko @Nullable String posterArtUri) { 20265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (posterArt != null) { 203633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko updateMetadataImageInfo(program, currentMetadata, posterArt, 0); 20465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } else if (posterArtUri != null) { 20595961816a768da387f0b5523cf4363ace2044089Nick Chalko ImageLoader.loadBitmap( 20695961816a768da387f0b5523cf4363ace2044089Nick Chalko mActivity, 20795961816a768da387f0b5523cf4363ace2044089Nick Chalko posterArtUri, 20895961816a768da387f0b5523cf4363ace2044089Nick Chalko mNowPlayingCardWidth, 209633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko mNowPlayingCardHeight, 210633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko new ProgramPosterArtCallback(mActivity, program, currentMetadata)); 21165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } else { 212633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko updateMetadataImageInfo(program, currentMetadata, null, R.drawable.default_now_card); 21365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 21465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 21565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 21695961816a768da387f0b5523cf4363ace2044089Nick Chalko private class ProgramPosterArtCallback extends ImageLoader.ImageLoaderCallback<Activity> { 217633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko private final RecordedProgram mRecordedProgram; 218633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko private final MediaMetadata mCurrentMetadata; 21965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 22095961816a768da387f0b5523cf4363ace2044089Nick Chalko public ProgramPosterArtCallback( 22195961816a768da387f0b5523cf4363ace2044089Nick Chalko Activity activity, RecordedProgram program, MediaMetadata metadata) { 22265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko super(activity); 22365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mRecordedProgram = program; 224633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko mCurrentMetadata = metadata; 22565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 22665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 22765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko @Override 22865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko public void onBitmapLoaded(Activity activity, @Nullable Bitmap posterArt) { 22965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (isCurrentProgram(mRecordedProgram)) { 230633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko updatePosterArt(mRecordedProgram, mCurrentMetadata, posterArt, null); 23165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 23265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 23365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 23465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 23595961816a768da387f0b5523cf4363ace2044089Nick Chalko private MediaMetadata updateMetadataTextInfo( 23695961816a768da387f0b5523cf4363ace2044089Nick Chalko final long programId, final String title, final String subtitle, final long duration) { 237633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko MediaMetadata.Builder builder = new MediaMetadata.Builder(); 238633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko builder.putString(MediaMetadata.METADATA_KEY_MEDIA_ID, Long.toString(programId)) 239633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko .putString(MediaMetadata.METADATA_KEY_TITLE, title) 240633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko .putLong(MediaMetadata.METADATA_KEY_DURATION, duration); 241633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko if (subtitle != null) { 242633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko builder.putString(MediaMetadata.METADATA_KEY_DISPLAY_SUBTITLE, subtitle); 243633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko } 244633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko MediaMetadata metadata = builder.build(); 245633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko mMediaSession.setMetadata(metadata); 246633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko return metadata; 247633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko } 248633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko 24995961816a768da387f0b5523cf4363ace2044089Nick Chalko private void updateMetadataImageInfo( 25095961816a768da387f0b5523cf4363ace2044089Nick Chalko final RecordedProgram program, 25195961816a768da387f0b5523cf4363ace2044089Nick Chalko final MediaMetadata currentMetadata, 25295961816a768da387f0b5523cf4363ace2044089Nick Chalko final Bitmap posterArt, 25395961816a768da387f0b5523cf4363ace2044089Nick Chalko final int imageResId) { 254633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko if (mMediaSession != null && (posterArt != null || imageResId != 0)) { 255633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko MediaMetadata.Builder builder = new MediaMetadata.Builder(currentMetadata); 256633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko if (posterArt != null) { 257633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko builder.putBitmap(MediaMetadata.METADATA_KEY_ART, posterArt); 25865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mMediaSession.setMetadata(builder.build()); 259633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko } else { 260633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko new AsyncTask<Void, Void, Bitmap>() { 261633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko @Override 262633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko protected Bitmap doInBackground(Void... arg0) { 263633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko return BitmapFactory.decodeResource(mActivity.getResources(), imageResId); 264633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko } 265633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko 266633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko @Override 267633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko protected void onPostExecute(Bitmap programPosterArt) { 26895961816a768da387f0b5523cf4363ace2044089Nick Chalko if (mMediaSession != null 26995961816a768da387f0b5523cf4363ace2044089Nick Chalko && programPosterArt != null 270633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko && isCurrentProgram(program)) { 271633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko builder.putBitmap(MediaMetadata.METADATA_KEY_ART, programPosterArt); 272633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko mMediaSession.setMetadata(builder.build()); 273633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko } 274633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko } 275633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko }.execute(); 27665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 277633eb826b8c97731dfc5ef12c7bf78a63734275dNick Chalko } 27865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 27965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 28065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko // An event was triggered by MediaController.TransportControls and must be handled here. 28165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko // Here we update the media itself to act on the event that was triggered. 28265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko private class MediaSessionCallback extends MediaSession.Callback { 28365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko @Override 28465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko public void onPrepare() { 28565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (!mDvrPlayer.isPlaybackPrepared()) { 28665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mDvrPlayer.prepare(true); 28765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 28865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 28965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 29065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko @Override 29165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko public void onPlay() { 292d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (mDvrPlayer.isPlaybackPrepared()) { 293d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko mDvrPlayer.play(); 294d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 29565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 29665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 29765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko @Override 29865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko public void onPause() { 299d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (mDvrPlayer.isPlaybackPrepared()) { 300d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko mDvrPlayer.pause(); 301d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 30265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 30365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 30465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko @Override 30565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko public void onFastForward() { 306d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (!mDvrPlayer.isPlaybackPrepared()) { 307d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko return; 308d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 30965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (mDvrPlayer.getPlaybackState() == PlaybackState.STATE_FAST_FORWARDING) { 31065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (mSpeedLevel < TimeShiftUtils.MAX_SPEED_LEVEL) { 31165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mSpeedLevel++; 31265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } else { 31365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return; 31465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 31565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } else { 31665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mSpeedLevel = 0; 31765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 31865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mDvrPlayer.fastForward( 31965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko TimeShiftUtils.getPlaybackSpeed(mSpeedLevel, mProgramDurationMs)); 32065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 32165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 32265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko @Override 32365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko public void onRewind() { 324d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (!mDvrPlayer.isPlaybackPrepared()) { 325d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko return; 326d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 32765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (mDvrPlayer.getPlaybackState() == PlaybackState.STATE_REWINDING) { 32865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko if (mSpeedLevel < TimeShiftUtils.MAX_SPEED_LEVEL) { 32965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mSpeedLevel++; 33065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } else { 33165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko return; 33265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 33365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } else { 33465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mSpeedLevel = 0; 33565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 33665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko mDvrPlayer.rewind(TimeShiftUtils.getPlaybackSpeed(mSpeedLevel, mProgramDurationMs)); 33765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 33865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 33965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko @Override 34065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko public void onSeekTo(long positionMs) { 341d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko if (mDvrPlayer.isPlaybackPrepared()) { 342d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko mDvrPlayer.seekTo(positionMs); 343d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko } 34465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 34565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 34665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko} 347