SampleMediaRouteProvider.java revision 57456222f52fbfc1dcfb1b99030aad6acc02ad23
1ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown/* 2ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * Copyright (C) 2013 The Android Open Source Project 3ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * 4ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * Licensed under the Apache License, Version 2.0 (the "License"); 5ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * you may not use this file except in compliance with the License. 6ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * You may obtain a copy of the License at 7ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * 8ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * http://www.apache.org/licenses/LICENSE-2.0 9ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * 10ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * Unless required by applicable law or agreed to in writing, software 11ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * distributed under the License is distributed on an "AS IS" BASIS, 12ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * See the License for the specific language governing permissions and 14ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * limitations under the License. 15ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown */ 16ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 17ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownpackage com.example.android.supportv7.media; 18ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 19ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport com.example.android.supportv7.R; 20ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 21ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.content.Context; 22ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.content.Intent; 23ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.content.IntentFilter; 24ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.content.IntentFilter.MalformedMimeTypeException; 25ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.content.res.Resources; 26ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.media.MediaRouter; 27ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.net.Uri; 28ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.os.Bundle; 2957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.app.PendingIntent; 30ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.support.v7.media.MediaControlIntent; 31fcb6a9d1caaf43ae41f859ebb58a4483b12475a1Jeff Brownimport android.support.v7.media.MediaItemStatus; 32ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.support.v7.media.MediaRouteProvider; 33ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.support.v7.media.MediaRouter.ControlRequestCallback; 3455e47d370890d3cbdab82857090c42df734ba276Jeff Brownimport android.support.v7.media.MediaRouteProviderDescriptor; 3555e47d370890d3cbdab82857090c42df734ba276Jeff Brownimport android.support.v7.media.MediaRouteDescriptor; 36ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.util.Log; 37ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.widget.Toast; 3857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.view.Gravity; 3955e47d370890d3cbdab82857090c42df734ba276Jeff Brownimport java.util.ArrayList; 40bc89096eeed02fd163eaed46b88364486c76c4feJeff Brown 41ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown/** 42ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * Demonstrates how to create a custom media route provider. 43ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * 44ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * @see SampleMediaRouteProviderService 45ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown */ 46ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownfinal class SampleMediaRouteProvider extends MediaRouteProvider { 47ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown private static final String TAG = "SampleMediaRouteProvider"; 48ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 49ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown private static final String FIXED_VOLUME_ROUTE_ID = "fixed"; 50ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown private static final String VARIABLE_VOLUME_ROUTE_ID = "variable"; 51ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown private static final int VOLUME_MAX = 10; 52ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 53ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown /** 54ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * A custom media control intent category for special requests that are 55ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * supported by this provider's routes. 56ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown */ 57ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown public static final String CATEGORY_SAMPLE_ROUTE = 5855e47d370890d3cbdab82857090c42df734ba276Jeff Brown "com.example.android.supportv7.media.CATEGORY_SAMPLE_ROUTE"; 59ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 60ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown /** 61ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * A custom media control intent action for special requests that are 62ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * supported by this provider's routes. 63ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * <p> 64ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * This particular request is designed to return a bundle of not very 65ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * interesting statistics for demonstration purposes. 66ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * </p> 67ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * 68ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * @see #DATA_PLAYBACK_COUNT 69ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown */ 70ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown public static final String ACTION_GET_STATISTICS = 7155e47d370890d3cbdab82857090c42df734ba276Jeff Brown "com.example.android.supportv7.media.ACTION_GET_STATISTICS"; 72ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 73ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown /** 74ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * {@link #ACTION_GET_STATISTICS} result data: Number of times the 75ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * playback action was invoked. 76ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown */ 77ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown public static final String DATA_PLAYBACK_COUNT = 7855e47d370890d3cbdab82857090c42df734ba276Jeff Brown "com.example.android.supportv7.media.EXTRA_PLAYBACK_COUNT"; 79ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 8057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang /* 8157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang * Set ENABLE_QUEUEING to true to test queuing on MRP. This will make 8257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang * MRP expose the following two experimental hidden APIs: 8357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang * ACTION_ENQUEUE 8457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang * ACTION_REMOVE 8557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang */ 8657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public static final boolean ENABLE_QUEUEING = false; 8757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 8855e47d370890d3cbdab82857090c42df734ba276Jeff Brown private static final ArrayList<IntentFilter> CONTROL_FILTERS; 89ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown static { 9055e47d370890d3cbdab82857090c42df734ba276Jeff Brown IntentFilter f1 = new IntentFilter(); 9155e47d370890d3cbdab82857090c42df734ba276Jeff Brown f1.addCategory(CATEGORY_SAMPLE_ROUTE); 9255e47d370890d3cbdab82857090c42df734ba276Jeff Brown f1.addAction(ACTION_GET_STATISTICS); 9355e47d370890d3cbdab82857090c42df734ba276Jeff Brown 9455e47d370890d3cbdab82857090c42df734ba276Jeff Brown IntentFilter f2 = new IntentFilter(); 9555e47d370890d3cbdab82857090c42df734ba276Jeff Brown f2.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK); 9655e47d370890d3cbdab82857090c42df734ba276Jeff Brown f2.addAction(MediaControlIntent.ACTION_PLAY); 9755e47d370890d3cbdab82857090c42df734ba276Jeff Brown f2.addDataScheme("http"); 9855e47d370890d3cbdab82857090c42df734ba276Jeff Brown f2.addDataScheme("https"); 9957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang f2.addDataScheme("rtsp"); 10057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang f2.addDataScheme("file"); 10155e47d370890d3cbdab82857090c42df734ba276Jeff Brown addDataTypeUnchecked(f2, "video/*"); 10255e47d370890d3cbdab82857090c42df734ba276Jeff Brown 10357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang IntentFilter f3 = new IntentFilter(); 10457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang f3.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK); 10557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang f3.addAction(MediaControlIntent.ACTION_SEEK); 10657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang f3.addAction(MediaControlIntent.ACTION_GET_STATUS); 10757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang f3.addAction(MediaControlIntent.ACTION_PAUSE); 10857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang f3.addAction(MediaControlIntent.ACTION_RESUME); 10957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang f3.addAction(MediaControlIntent.ACTION_STOP); 11057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 11157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang IntentFilter f4 = new IntentFilter(); 11257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang f4.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK); 11357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang f4.addAction(MediaControlIntent.ACTION_ENQUEUE); 11457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang f4.addDataScheme("http"); 11557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang f4.addDataScheme("https"); 11657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang f4.addDataScheme("rtsp"); 11757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang f4.addDataScheme("file"); 11857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang addDataTypeUnchecked(f4, "video/*"); 11957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 12057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang IntentFilter f5 = new IntentFilter(); 12157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang f5.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK); 12257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang f5.addAction(MediaControlIntent.ACTION_REMOVE); 12357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 12455e47d370890d3cbdab82857090c42df734ba276Jeff Brown CONTROL_FILTERS = new ArrayList<IntentFilter>(); 12555e47d370890d3cbdab82857090c42df734ba276Jeff Brown CONTROL_FILTERS.add(f1); 12655e47d370890d3cbdab82857090c42df734ba276Jeff Brown CONTROL_FILTERS.add(f2); 12757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang CONTROL_FILTERS.add(f3); 12857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (ENABLE_QUEUEING) { 12957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang CONTROL_FILTERS.add(f4); 13057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang CONTROL_FILTERS.add(f5); 13157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 132ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 133ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 134ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown private static void addDataTypeUnchecked(IntentFilter filter, String type) { 135ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown try { 136ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown filter.addDataType(type); 137ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } catch (MalformedMimeTypeException ex) { 138ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown throw new RuntimeException(ex); 139ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 140ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 141ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 142ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown private int mVolume = 5; 14357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private int mEnqueueCount; 144ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 145ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown public SampleMediaRouteProvider(Context context) { 146ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown super(context); 147ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 148ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown publishRoutes(); 149ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 150ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 151ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown @Override 152ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown public RouteController onCreateRouteController(String routeId) { 153ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown return new SampleRouteController(routeId); 154ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 155ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 156ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown private void publishRoutes() { 157ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown Resources r = getContext().getResources(); 158ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 15955e47d370890d3cbdab82857090c42df734ba276Jeff Brown MediaRouteDescriptor routeDescriptor1 = new MediaRouteDescriptor.Builder( 160ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown FIXED_VOLUME_ROUTE_ID, 16155e47d370890d3cbdab82857090c42df734ba276Jeff Brown r.getString(R.string.fixed_volume_route_name)) 162b28eb61b29c0d956a5e504716cdea9f31184a998Jeff Brown .setDescription(r.getString(R.string.sample_route_description)) 16355e47d370890d3cbdab82857090c42df734ba276Jeff Brown .addControlFilters(CONTROL_FILTERS) 16455e47d370890d3cbdab82857090c42df734ba276Jeff Brown .setPlaybackType(MediaRouter.RouteInfo.PLAYBACK_TYPE_REMOTE) 16555e47d370890d3cbdab82857090c42df734ba276Jeff Brown .setVolumeHandling(MediaRouter.RouteInfo.PLAYBACK_VOLUME_FIXED) 16655e47d370890d3cbdab82857090c42df734ba276Jeff Brown .setVolume(VOLUME_MAX) 16755e47d370890d3cbdab82857090c42df734ba276Jeff Brown .build(); 16855e47d370890d3cbdab82857090c42df734ba276Jeff Brown 16955e47d370890d3cbdab82857090c42df734ba276Jeff Brown MediaRouteDescriptor routeDescriptor2 = new MediaRouteDescriptor.Builder( 170ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown VARIABLE_VOLUME_ROUTE_ID, 17155e47d370890d3cbdab82857090c42df734ba276Jeff Brown r.getString(R.string.variable_volume_route_name)) 172b28eb61b29c0d956a5e504716cdea9f31184a998Jeff Brown .setDescription(r.getString(R.string.sample_route_description)) 17355e47d370890d3cbdab82857090c42df734ba276Jeff Brown .addControlFilters(CONTROL_FILTERS) 17455e47d370890d3cbdab82857090c42df734ba276Jeff Brown .setPlaybackType(MediaRouter.RouteInfo.PLAYBACK_TYPE_REMOTE) 17555e47d370890d3cbdab82857090c42df734ba276Jeff Brown .setVolumeHandling(MediaRouter.RouteInfo.PLAYBACK_VOLUME_VARIABLE) 17655e47d370890d3cbdab82857090c42df734ba276Jeff Brown .setVolumeMax(VOLUME_MAX) 17755e47d370890d3cbdab82857090c42df734ba276Jeff Brown .setVolume(mVolume) 17855e47d370890d3cbdab82857090c42df734ba276Jeff Brown .build(); 17955e47d370890d3cbdab82857090c42df734ba276Jeff Brown 18055e47d370890d3cbdab82857090c42df734ba276Jeff Brown MediaRouteProviderDescriptor providerDescriptor = 18155e47d370890d3cbdab82857090c42df734ba276Jeff Brown new MediaRouteProviderDescriptor.Builder() 18255e47d370890d3cbdab82857090c42df734ba276Jeff Brown .addRoute(routeDescriptor1) 18355e47d370890d3cbdab82857090c42df734ba276Jeff Brown .addRoute(routeDescriptor2) 18455e47d370890d3cbdab82857090c42df734ba276Jeff Brown .build(); 185ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown setDescriptor(providerDescriptor); 186ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 187ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 18857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private void showToast(String msg) { 18957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Toast toast = Toast.makeText(getContext(), 19057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang "[provider] " + msg, Toast.LENGTH_LONG); 19157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang toast.setGravity(Gravity.TOP, 0, 100); 19257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang toast.show(); 193bc89096eeed02fd163eaed46b88364486c76c4feJeff Brown } 194bc89096eeed02fd163eaed46b88364486c76c4feJeff Brown 195ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown private final class SampleRouteController extends MediaRouteProvider.RouteController { 196ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown private final String mRouteId; 19757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // Create an overlay display window (used for simulating the remote playback only) 19857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private final OverlayDisplayWindow mOverlay = new OverlayDisplayWindow(getContext(), 19957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang getContext().getResources().getString(R.string.sample_media_route_provider_remote), 20057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 1024, 768, Gravity.CENTER); 20157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private final MediaPlayerWrapper mMediaPlayer = new MediaPlayerWrapper(getContext()); 20257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private final MediaSessionManager mSessionManager = new MediaSessionManager(); 203ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 204ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown public SampleRouteController(String routeId) { 205ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown mRouteId = routeId; 20657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mSessionManager.setCallback(mMediaPlayer); 20757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mOverlay.setOverlayWindowListener(mMediaPlayer); 20857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mMediaPlayer.setCallback(new MediaPlayerCallback()); 209ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown Log.d(TAG, mRouteId + ": Controller created"); 210ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 211ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 212ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown @Override 213bc89096eeed02fd163eaed46b88364486c76c4feJeff Brown public void onRelease() { 214ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown Log.d(TAG, mRouteId + ": Controller released"); 21557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mMediaPlayer.release(); 216ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 217ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 218ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown @Override 219bc89096eeed02fd163eaed46b88364486c76c4feJeff Brown public void onSelect() { 220ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown Log.d(TAG, mRouteId + ": Selected"); 22157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mOverlay.show(); 222ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 223ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 224ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown @Override 225bc89096eeed02fd163eaed46b88364486c76c4feJeff Brown public void onUnselect() { 226ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown Log.d(TAG, mRouteId + ": Unselected"); 22757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mMediaPlayer.onStop(); 22857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mOverlay.dismiss(); 229ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 230ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 231ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown @Override 232bc89096eeed02fd163eaed46b88364486c76c4feJeff Brown public void onSetVolume(int volume) { 233ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown Log.d(TAG, mRouteId + ": Set volume to " + volume); 234ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown if (mRouteId.equals(VARIABLE_VOLUME_ROUTE_ID)) { 235ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown setVolumeInternal(volume); 236ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 237ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 238ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 239ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown @Override 240bc89096eeed02fd163eaed46b88364486c76c4feJeff Brown public void onUpdateVolume(int delta) { 241ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown Log.d(TAG, mRouteId + ": Update volume by " + delta); 242ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown if (mRouteId.equals(VARIABLE_VOLUME_ROUTE_ID)) { 243ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown setVolumeInternal(mVolume + delta); 244ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 245ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 246ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 247ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown @Override 248bc89096eeed02fd163eaed46b88364486c76c4feJeff Brown public boolean onControlRequest(Intent intent, ControlRequestCallback callback) { 249ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown Log.d(TAG, mRouteId + ": Received control request " + intent); 25057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang String action = intent.getAction(); 25157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (intent.hasCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)) { 25257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang boolean success = false; 25357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (action.equals(MediaControlIntent.ACTION_PLAY)) { 25457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang success = handlePlay(intent, callback); 25557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else if (action.equals(MediaControlIntent.ACTION_ENQUEUE)) { 25657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang success = handleEnqueue(intent, callback); 25757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else if (action.equals(MediaControlIntent.ACTION_REMOVE)) { 25857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang success = handleRemove(intent, callback); 25957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else if (action.equals(MediaControlIntent.ACTION_SEEK)) { 26057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang success = handleSeek(intent, callback); 26157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else if (action.equals(MediaControlIntent.ACTION_GET_STATUS)) { 26257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang success = handleGetStatus(intent, callback); 26357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else if (action.equals(MediaControlIntent.ACTION_PAUSE)) { 26457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang success = handlePause(intent, callback); 26557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else if (action.equals(MediaControlIntent.ACTION_RESUME)) { 26657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang success = handleResume(intent, callback); 26757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else if (action.equals(MediaControlIntent.ACTION_STOP)) { 26857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang success = handleStop(intent, callback); 269ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 27057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, mSessionManager.toString()); 27157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang return success; 272ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 273ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 27457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (action.equals(ACTION_GET_STATISTICS) 275ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown && intent.hasCategory(CATEGORY_SAMPLE_ROUTE)) { 276ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown Bundle data = new Bundle(); 27757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang data.putInt(DATA_PLAYBACK_COUNT, mEnqueueCount); 278ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown if (callback != null) { 279fcb6a9d1caaf43ae41f859ebb58a4483b12475a1Jeff Brown callback.onResult(data); 280ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 281ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown return true; 282ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 283ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown return false; 284ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 28557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 28657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private void setVolumeInternal(int volume) { 28757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (volume >= 0 && volume <= VOLUME_MAX) { 28857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mVolume = volume; 28957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, mRouteId + ": New volume is " + mVolume); 29057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang publishRoutes(); 29157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 29257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 29357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 29457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private boolean handlePlay(Intent intent, ControlRequestCallback callback) { 29557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang String sid = intent.getStringExtra(MediaControlIntent.EXTRA_SESSION_ID); 29657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (sid == null || mSessionManager.stop(sid)) { 29757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "handleEnqueue"); 29857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang return handleEnqueue(intent, callback); 29957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 30057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang return false; 30157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 30257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 30357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private boolean handleEnqueue(Intent intent, ControlRequestCallback callback) { 30457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (intent.getData() == null) { 30557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang return false; 30657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 30757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 30857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mEnqueueCount +=1; 30957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 31057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang boolean enqueue = intent.getAction().equals(MediaControlIntent.ACTION_ENQUEUE); 31157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Uri uri = intent.getData(); 31257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang String sid = intent.getStringExtra(MediaControlIntent.EXTRA_SESSION_ID); 31357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang long pos = intent.getLongExtra(MediaControlIntent.EXTRA_ITEM_CONTENT_POSITION, 0); 31457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Bundle metadata = intent.getBundleExtra(MediaControlIntent.EXTRA_ITEM_METADATA); 31557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Bundle headers = intent.getBundleExtra(MediaControlIntent.EXTRA_ITEM_HTTP_HEADERS); 31657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang PendingIntent receiver = (PendingIntent)intent.getParcelableExtra( 31757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang MediaControlIntent.EXTRA_ITEM_STATUS_UPDATE_RECEIVER); 31857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 31957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, mRouteId + ": Received " + (enqueue?"enqueue":"play") + " request" 32057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang + ", uri=" + uri 32157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang + ", sid=" + sid 32257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang + ", pos=" + pos 32357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang + ", metadata=" + metadata 32457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang + ", headers=" + headers 32557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang + ", receiver=" + receiver); 32657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang MediaQueueItem item = mSessionManager.enqueue(sid, uri, receiver); 32757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (callback != null) { 32857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (item != null) { 32957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Bundle result = new Bundle(); 33057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang result.putString(MediaControlIntent.EXTRA_SESSION_ID, item.getSessionId()); 33157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang result.putString(MediaControlIntent.EXTRA_ITEM_ID, item.getItemId()); 33257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang result.putBundle(MediaControlIntent.EXTRA_ITEM_STATUS, 33357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang item.getStatus().asBundle()); 33457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang callback.onResult(result); 33557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else { 33657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang callback.onError("Failed to open " + uri.toString(), null); 33757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 33857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 33957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang return true; 34057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 34157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 34257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private boolean handleRemove(Intent intent, ControlRequestCallback callback) { 34357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang String sid = intent.getStringExtra(MediaControlIntent.EXTRA_SESSION_ID); 34457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang String iid = intent.getStringExtra(MediaControlIntent.EXTRA_ITEM_ID); 34557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang MediaQueueItem item = mSessionManager.remove(sid, iid); 34657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (callback != null) { 34757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (item != null) { 34857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Bundle result = new Bundle(); 34957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang result.putBundle(MediaControlIntent.EXTRA_ITEM_STATUS, 35057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang item.getStatus().asBundle()); 35157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang callback.onResult(result); 35257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else { 35357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang callback.onError("Failed to remove" + 35457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang ", sid=" + sid + ", iid=" + iid, null); 35557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 35657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 35757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang return (item != null); 35857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 35957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 36057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private boolean handleSeek(Intent intent, ControlRequestCallback callback) { 36157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang String sid = intent.getStringExtra(MediaControlIntent.EXTRA_SESSION_ID); 36257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang String iid = intent.getStringExtra(MediaControlIntent.EXTRA_ITEM_ID); 36357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang long pos = intent.getLongExtra(MediaControlIntent.EXTRA_ITEM_CONTENT_POSITION, 0); 36457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, mRouteId + ": Received seek request, pos=" + pos); 36557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang MediaQueueItem item = mSessionManager.seek(sid, iid, pos); 36657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (callback != null) { 36757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (item != null) { 36857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Bundle result = new Bundle(); 36957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang result.putBundle(MediaControlIntent.EXTRA_ITEM_STATUS, 37057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang item.getStatus().asBundle()); 37157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang callback.onResult(result); 37257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else { 37357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang callback.onError("Failed to seek" + 37457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang ", sid=" + sid + ", iid=" + iid + ", pos=" + pos, null); 37557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 37657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 37757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang return (item != null); 37857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 37957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 38057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private boolean handleGetStatus(Intent intent, ControlRequestCallback callback) { 38157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang String sid = intent.getStringExtra(MediaControlIntent.EXTRA_SESSION_ID); 38257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang String iid = intent.getStringExtra(MediaControlIntent.EXTRA_ITEM_ID); 38357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang MediaQueueItem item = mSessionManager.getStatus(sid, iid); 38457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (callback != null) { 38557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (item != null) { 38657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Bundle result = new Bundle(); 38757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang result.putBundle(MediaControlIntent.EXTRA_ITEM_STATUS, 38857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang item.getStatus().asBundle()); 38957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang callback.onResult(result); 39057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else { 39157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang callback.onError("Failed to get status" + 39257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang ", sid=" + sid + ", iid=" + iid, null); 39357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 39457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 39557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang return (item != null); 39657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 39757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 39857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private boolean handlePause(Intent intent, ControlRequestCallback callback) { 39957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang String sid = intent.getStringExtra(MediaControlIntent.EXTRA_SESSION_ID); 40057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang boolean success = mSessionManager.pause(sid); 40157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (callback != null) { 40257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (success) { 40357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang callback.onResult(null); 40457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else { 40557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang callback.onError("Failed to pause, sid=" + sid, null); 40657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 40757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 40857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang return success; 40957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 41057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 41157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private boolean handleResume(Intent intent, ControlRequestCallback callback) { 41257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang String sid = intent.getStringExtra(MediaControlIntent.EXTRA_SESSION_ID); 41357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang boolean success = mSessionManager.resume(sid); 41457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (callback != null) { 41557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (success) { 41657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang callback.onResult(null); 41757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else { 41857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang callback.onError("Failed to resume, sid=" + sid, null); 41957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 42057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 42157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang return success; 42257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 42357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 42457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private boolean handleStop(Intent intent, ControlRequestCallback callback) { 42557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang String sid = intent.getStringExtra(MediaControlIntent.EXTRA_SESSION_ID); 42657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang boolean success = mSessionManager.stop(sid); 42757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (callback != null) { 42857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (success) { 42957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang callback.onResult(null); 43057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else { 43157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang callback.onError("Failed to stop, sid=" + sid, null); 43257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 43357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 43457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang return success; 43557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 43657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 43757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private void handleFinish(boolean error) { 43857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang MediaQueueItem item = mSessionManager.finish(error); 43957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (item != null) { 44057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang handleStatusChange(item); 44157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 44257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 44357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 44457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private void handleStatusChange(MediaQueueItem item) { 44557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (item == null) { 44657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang item = mSessionManager.getCurrentItem(); 44757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 44857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (item != null) { 44957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang PendingIntent receiver = item.getUpdateReceiver(); 45057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (receiver != null) { 45157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Intent intent = new Intent(); 45257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang intent.putExtra(MediaControlIntent.EXTRA_SESSION_ID, item.getSessionId()); 45357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang intent.putExtra(MediaControlIntent.EXTRA_ITEM_ID, item.getItemId()); 45457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang intent.putExtra(MediaControlIntent.EXTRA_ITEM_STATUS, 45557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang item.getStatus().asBundle()); 45657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang try { 45757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang receiver.send(getContext(), 0, intent); 45857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, mRouteId + ": Sending status update from provider"); 45957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } catch (PendingIntent.CanceledException e) { 46057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, mRouteId + ": Failed to send status update!"); 46157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 46257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 46357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 46457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 46557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 46657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private final class MediaPlayerCallback extends MediaPlayerWrapper.Callback { 46757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 46857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onError() { 46957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang handleFinish(true); 47057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 47157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 47257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 47357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onCompletion() { 47457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang handleFinish(false); 47557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 47657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 47757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 47857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onStatusChanged() { 47957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang handleStatusChange(null); 48057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 48157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 48257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 48357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onSizeChanged(int width, int height) { 48457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mOverlay.updateAspectRatio(width, height); 48557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 48657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 487ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 488ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown}