/***
Copyright (c) 2014 CommonsWare, LLC
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.commonsware.cwac.mediarouter.demo.remoteplayback;
import android.app.Activity;
import android.app.Fragment;
import android.net.Uri;
import android.os.Bundle;
import com.commonsware.cwac.mediarouter.media.MediaControlIntent;
import com.commonsware.cwac.mediarouter.media.MediaItemStatus;
import com.commonsware.cwac.mediarouter.media.MediaRouteSelector;
import com.commonsware.cwac.mediarouter.media.MediaRouter;
import com.commonsware.cwac.mediarouter.media.MediaSessionStatus;
import com.commonsware.cwac.mediarouter.media.RemotePlaybackClient;
import com.commonsware.cwac.mediarouter.media.RemotePlaybackClient.ItemActionCallback;
import com.commonsware.cwac.mediarouter.media.RemotePlaybackClient.SessionActionCallback;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ScrollView;
import android.widget.TextView;
import com.commonsware.cwac.mediarouter.app.MediaRouteActionProvider;
public class PlaybackFragment extends Fragment {
private MediaRouteSelector selector=null;
private MediaRouter router=null;
private TextView transcript=null;
private ScrollView scroll=null;
private RemotePlaybackClient client=null;
private boolean isPlaying=false;
private boolean isPaused=false;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
setHasOptionsMenu(true);
selector=
new MediaRouteSelector.Builder().addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)
.build();
}
@Override
public void onAttach(Activity host) {
super.onAttach(host);
router=MediaRouter.getInstance(host);
}
@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
scroll=
(ScrollView)inflater.inflate(R.layout.activity_main, container,
false);
transcript=(TextView)scroll.findViewById(R.id.transcript);
logToTranscript("Started");
return(scroll);
}
@Override
public void onResume() {
super.onResume();
router.addCallback(selector, cb,
MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY);
}
@Override
public void onPause() {
router.removeCallback(cb);
super.onPause();
}
@Override
public void onDestroy() {
disconnect();
super.onDestroy();
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.main, menu);
if (client != null) {
if (isPlaying) {
menu.findItem(R.id.stop).setVisible(true);
if (isPaused) {
menu.findItem(R.id.play).setVisible(true);
}
else {
menu.findItem(R.id.pause).setVisible(true);
}
}
else {
menu.findItem(R.id.play).setVisible(true);
}
}
MenuItem item=menu.findItem(R.id.route_provider);
MediaRouteActionProvider provider=
(MediaRouteActionProvider)item.getActionProvider();
provider.setRouteSelector(selector);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.play:
if (isPlaying && isPaused) {
resume();
}
else {
play();
}
return(true);
case R.id.stop:
stop();
return(true);
case R.id.pause:
pause();
return(true);
}
return(super.onOptionsItemSelected(item));
}
private void play() {
logToTranscript(getActivity().getString(R.string.play_requested));
ItemActionCallback playCB=new ItemActionCallback() {
@Override
public void onResult(Bundle data, String sessionId,
MediaSessionStatus sessionStatus,
String itemId, MediaItemStatus itemStatus) {
logToTranscript(getActivity().getString(R.string.playing));
isPlaying=true;
getActivity().invalidateOptionsMenu();
}
@Override
public void onError(String error, int code, Bundle data) {
logToTranscript(getActivity().getString(R.string.play_error)
+ error);
}
};
client.play(Uri.parse("http://misc.commonsware.com/ed_hd_512kb.mp4"),
"video/mp4", null, 0, null, playCB);
}
private void pause() {
logToTranscript(getActivity().getString(R.string.pause_requested));
PauseCallback pauseCB=new PauseCallback();
client.pause(null, pauseCB);
transcript.postDelayed(pauseCB, 1000);
}
private void resume() {
logToTranscript(getActivity().getString(R.string.resume_requested));
ResumeCallback resumeCB=new ResumeCallback();
client.resume(null, resumeCB);
transcript.postDelayed(resumeCB, 1000);
}
private void stop() {
logToTranscript(getActivity().getString(R.string.stop_requested));
StopCallback stopCB=new StopCallback();
client.stop(null, stopCB);
transcript.postDelayed(stopCB, 1000);
}
private void logToTranscript(String msg) {
if (client != null) {
String sessionId=client.getSessionId();
if (sessionId != null) {
msg="(" + sessionId + ") " + msg;
}
}
transcript.setText(transcript.getText().toString() + msg + "\n");
scroll.fullScroll(View.FOCUS_DOWN);
}
private void connect(MediaRouter.RouteInfo route) {
client=
new RemotePlaybackClient(getActivity().getApplication(), route);
if (client.isRemotePlaybackSupported()) {
logToTranscript(getActivity().getString(R.string.connected));
if (client.isSessionManagementSupported()) {
client.startSession(null, new SessionActionCallback() {
@Override
public void onResult(Bundle data, String sessionId,
MediaSessionStatus sessionStatus) {
logToTranscript(getActivity().getString(R.string.session_started));
getActivity().invalidateOptionsMenu();
}
@Override
public void onError(String error, int code, Bundle data) {
logToTranscript(getActivity().getString(R.string.session_failed));
}
});
}
else {
getActivity().invalidateOptionsMenu();
}
}
else {
logToTranscript(getActivity().getString(R.string.remote_playback_not_supported));
client=null;
}
}
private void disconnect() {
isPlaying=false;
isPaused=false;
if (client != null) {
logToTranscript(getActivity().getString(R.string.session_ending));
EndSessionCallback endCB=new EndSessionCallback();
client.endSession(null, endCB);
transcript.postDelayed(endCB, 1000);
}
}
private MediaRouter.Callback cb=new MediaRouter.Callback() {
@Override
public void onRouteSelected(MediaRouter router,
MediaRouter.RouteInfo route) {
logToTranscript(getActivity().getString(R.string.route_selected));
connect(route);
}
@Override
public void onRouteUnselected(MediaRouter router,
MediaRouter.RouteInfo route) {
logToTranscript(getActivity().getString(R.string.route_unselected));
disconnect();
}
};
class RunnableSessionActionCallback extends SessionActionCallback
implements Runnable {
@Override
public void onResult(Bundle data, String sessionId,
MediaSessionStatus sessionStatus) {
run();
}
@Override
public void run() {
transcript.removeCallbacks(this);
}
}
private class PauseCallback extends RunnableSessionActionCallback {
@Override
public void run() {
super.run();
isPaused=true;
getActivity().invalidateOptionsMenu();
logToTranscript(getActivity().getString(R.string.paused));
}
}
private class ResumeCallback extends RunnableSessionActionCallback {
@Override
public void run() {
super.run();
isPaused=false;
getActivity().invalidateOptionsMenu();
logToTranscript(getActivity().getString(R.string.resumed));
}
}
private class StopCallback extends RunnableSessionActionCallback {
@Override
public void run() {
super.run();
isPlaying=false;
isPaused=false;
getActivity().invalidateOptionsMenu();
logToTranscript(getActivity().getString(R.string.stopped));
}
}
private class EndSessionCallback extends
RunnableSessionActionCallback {
@Override
public void run() {
super.run();
client.release();
client=null;
if (getActivity() != null) {
getActivity().invalidateOptionsMenu();
logToTranscript(getActivity().getString(R.string.session_ended));
}
}
}
}