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
191636d4634299cba990966c01dbb577275ab8273cJae Seoimport android.app.PendingIntent;
20ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.content.Context;
21ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.content.Intent;
22ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.content.IntentFilter;
23ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.content.IntentFilter.MalformedMimeTypeException;
245d429bc3a8195d6f37cf2f7da0935972950539b4RoboErikimport android.content.IntentSender;
25ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.content.res.Resources;
267578fad97dcd3b4b390652f37a30d805538980f5Chong Zhangimport android.media.AudioManager;
27ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.media.MediaRouter;
28ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.net.Uri;
29ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.os.Bundle;
30ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.support.v7.media.MediaControlIntent;
311636d4634299cba990966c01dbb577275ab8273cJae Seoimport android.support.v7.media.MediaRouteDescriptor;
32ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.support.v7.media.MediaRouteProvider;
3355e47d370890d3cbdab82857090c42df734ba276Jeff Brownimport android.support.v7.media.MediaRouteProviderDescriptor;
341636d4634299cba990966c01dbb577275ab8273cJae Seoimport android.support.v7.media.MediaRouter.ControlRequestCallback;
35a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhangimport android.support.v7.media.MediaSessionStatus;
36ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.util.Log;
371636d4634299cba990966c01dbb577275ab8273cJae Seo
381636d4634299cba990966c01dbb577275ab8273cJae Seoimport com.example.android.supportv7.R;
398e006e629800b4a2643416f97bca2711af728837Jeff Brown
4055e47d370890d3cbdab82857090c42df734ba276Jeff Brownimport java.util.ArrayList;
41bc89096eeed02fd163eaed46b88364486c76c4feJeff Brown
42ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown/**
43ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * Demonstrates how to create a custom media route provider.
44ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown *
45ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * @see SampleMediaRouteProviderService
46ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown */
47ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownfinal class SampleMediaRouteProvider extends MediaRouteProvider {
48ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    private static final String TAG = "SampleMediaRouteProvider";
49ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
50ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    private static final String FIXED_VOLUME_ROUTE_ID = "fixed";
51a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang    private static final String VARIABLE_VOLUME_BASIC_ROUTE_ID = "variable_basic";
52a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang    private static final String VARIABLE_VOLUME_QUEUING_ROUTE_ID = "variable_queuing";
53a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang    private static final String VARIABLE_VOLUME_SESSION_ROUTE_ID = "variable_session";
541636d4634299cba990966c01dbb577275ab8273cJae Seo
55ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    private static final int VOLUME_MAX = 10;
56ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
57ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    /**
58ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown     * A custom media control intent category for special requests that are
59ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown     * supported by this provider's routes.
60ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown     */
61ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    public static final String CATEGORY_SAMPLE_ROUTE =
6255e47d370890d3cbdab82857090c42df734ba276Jeff Brown            "com.example.android.supportv7.media.CATEGORY_SAMPLE_ROUTE";
63ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
64ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    /**
6570f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho     * A custom media control intent action to take a snapshot.
66ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown     * </p>
67ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown     *
6870f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho     * @see #EXTRA_SNAPSHOT
69ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown     */
7070f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho    public static final String ACTION_TAKE_SNAPSHOT =
7170f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho            "com.example.android.supportv7.media.action.TAKE_SNAPSHOT";
72cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang
73cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang    /**
7470f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho     * {@link #ACTION_TAKE_SNAPSHOT} result data: a bitmap containing a snapshot
75cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang     * of the currently playing media item
76cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang     */
7770f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho    public static final String EXTRA_SNAPSHOT =
7870f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho            "com.example.android.supportv7.media.extra.SNAPSHOT";
79ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
80a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang    private static final ArrayList<IntentFilter> CONTROL_FILTERS_BASIC;
81a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang    private static final ArrayList<IntentFilter> CONTROL_FILTERS_QUEUING;
82a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang    private static final ArrayList<IntentFilter> CONTROL_FILTERS_SESSION;
8357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
84ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    static {
8555e47d370890d3cbdab82857090c42df734ba276Jeff Brown        IntentFilter f1 = new IntentFilter();
8655e47d370890d3cbdab82857090c42df734ba276Jeff Brown        f1.addCategory(CATEGORY_SAMPLE_ROUTE);
8770f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho        f1.addAction(ACTION_TAKE_SNAPSHOT);
8855e47d370890d3cbdab82857090c42df734ba276Jeff Brown
8955e47d370890d3cbdab82857090c42df734ba276Jeff Brown        IntentFilter f2 = new IntentFilter();
9055e47d370890d3cbdab82857090c42df734ba276Jeff Brown        f2.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
9155e47d370890d3cbdab82857090c42df734ba276Jeff Brown        f2.addAction(MediaControlIntent.ACTION_PLAY);
9255e47d370890d3cbdab82857090c42df734ba276Jeff Brown        f2.addDataScheme("http");
9355e47d370890d3cbdab82857090c42df734ba276Jeff Brown        f2.addDataScheme("https");
9457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        f2.addDataScheme("rtsp");
9557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        f2.addDataScheme("file");
9655e47d370890d3cbdab82857090c42df734ba276Jeff Brown        addDataTypeUnchecked(f2, "video/*");
9755e47d370890d3cbdab82857090c42df734ba276Jeff Brown
9857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        IntentFilter f3 = new IntentFilter();
9957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        f3.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
10057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        f3.addAction(MediaControlIntent.ACTION_SEEK);
10157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        f3.addAction(MediaControlIntent.ACTION_GET_STATUS);
10257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        f3.addAction(MediaControlIntent.ACTION_PAUSE);
10357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        f3.addAction(MediaControlIntent.ACTION_RESUME);
10457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        f3.addAction(MediaControlIntent.ACTION_STOP);
10557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
10657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        IntentFilter f4 = new IntentFilter();
10757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        f4.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
10857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        f4.addAction(MediaControlIntent.ACTION_ENQUEUE);
10957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        f4.addDataScheme("http");
11057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        f4.addDataScheme("https");
11157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        f4.addDataScheme("rtsp");
11257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        f4.addDataScheme("file");
11357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        addDataTypeUnchecked(f4, "video/*");
11457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
11557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        IntentFilter f5 = new IntentFilter();
11657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        f5.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
11757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        f5.addAction(MediaControlIntent.ACTION_REMOVE);
11857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
119a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        IntentFilter f6 = new IntentFilter();
120a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        f6.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
121a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        f6.addAction(MediaControlIntent.ACTION_START_SESSION);
122a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        f6.addAction(MediaControlIntent.ACTION_GET_SESSION_STATUS);
123a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        f6.addAction(MediaControlIntent.ACTION_END_SESSION);
124a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang
125f515b3268334381e81f7a4eb8283a362b9a6f725Jae Seo        CONTROL_FILTERS_BASIC = new ArrayList<>();
126a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        CONTROL_FILTERS_BASIC.add(f1);
127a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        CONTROL_FILTERS_BASIC.add(f2);
128a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        CONTROL_FILTERS_BASIC.add(f3);
129a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang
130f515b3268334381e81f7a4eb8283a362b9a6f725Jae Seo        CONTROL_FILTERS_QUEUING = new ArrayList<>(CONTROL_FILTERS_BASIC);
131a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        CONTROL_FILTERS_QUEUING.add(f4);
132a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        CONTROL_FILTERS_QUEUING.add(f5);
133a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang
134f515b3268334381e81f7a4eb8283a362b9a6f725Jae Seo        CONTROL_FILTERS_SESSION = new ArrayList<>(CONTROL_FILTERS_QUEUING);
135a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        CONTROL_FILTERS_SESSION.add(f6);
136ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    }
137ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
138ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    private static void addDataTypeUnchecked(IntentFilter filter, String type) {
139ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        try {
140ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            filter.addDataType(type);
141ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        } catch (MalformedMimeTypeException ex) {
142ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            throw new RuntimeException(ex);
143ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        }
144ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    }
145ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
146ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    private int mVolume = 5;
147ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
148ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    public SampleMediaRouteProvider(Context context) {
149ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        super(context);
150ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
151ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        publishRoutes();
152ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    }
153ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
154ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    @Override
155ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    public RouteController onCreateRouteController(String routeId) {
156ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        return new SampleRouteController(routeId);
157ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    }
158ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
159ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    private void publishRoutes() {
160ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        Resources r = getContext().getResources();
1615d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik        Intent settingsIntent = new Intent(Intent.ACTION_MAIN);
1625d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik        settingsIntent.setClass(getContext(), SampleMediaRouteSettingsActivity.class);
1635d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik        IntentSender is = PendingIntent.getActivity(getContext(), 99, settingsIntent,
1645d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik                Intent.FLAG_ACTIVITY_NEW_TASK).getIntentSender();
165ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
16655e47d370890d3cbdab82857090c42df734ba276Jeff Brown        MediaRouteDescriptor routeDescriptor1 = new MediaRouteDescriptor.Builder(
167ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown                FIXED_VOLUME_ROUTE_ID,
16855e47d370890d3cbdab82857090c42df734ba276Jeff Brown                r.getString(R.string.fixed_volume_route_name))
169b28eb61b29c0d956a5e504716cdea9f31184a998Jeff Brown                .setDescription(r.getString(R.string.sample_route_description))
170a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                .addControlFilters(CONTROL_FILTERS_BASIC)
1717578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                .setPlaybackStream(AudioManager.STREAM_MUSIC)
17255e47d370890d3cbdab82857090c42df734ba276Jeff Brown                .setPlaybackType(MediaRouter.RouteInfo.PLAYBACK_TYPE_REMOTE)
17355e47d370890d3cbdab82857090c42df734ba276Jeff Brown                .setVolumeHandling(MediaRouter.RouteInfo.PLAYBACK_VOLUME_FIXED)
17455e47d370890d3cbdab82857090c42df734ba276Jeff Brown                .setVolume(VOLUME_MAX)
1755d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik                .setCanDisconnect(true)
1765d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik                .setSettingsActivity(is)
17755e47d370890d3cbdab82857090c42df734ba276Jeff Brown                .build();
17855e47d370890d3cbdab82857090c42df734ba276Jeff Brown
17955e47d370890d3cbdab82857090c42df734ba276Jeff Brown        MediaRouteDescriptor routeDescriptor2 = new MediaRouteDescriptor.Builder(
180a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                VARIABLE_VOLUME_BASIC_ROUTE_ID,
181a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                r.getString(R.string.variable_volume_basic_route_name))
182a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                .setDescription(r.getString(R.string.sample_route_description))
183a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                .addControlFilters(CONTROL_FILTERS_BASIC)
184a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                .setPlaybackStream(AudioManager.STREAM_MUSIC)
185a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                .setPlaybackType(MediaRouter.RouteInfo.PLAYBACK_TYPE_REMOTE)
186a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                .setVolumeHandling(MediaRouter.RouteInfo.PLAYBACK_VOLUME_VARIABLE)
187a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                .setVolumeMax(VOLUME_MAX)
188a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                .setVolume(mVolume)
1895d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik                .setSettingsActivity(is)
190a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                .build();
191a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang
192a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        MediaRouteDescriptor routeDescriptor3 = new MediaRouteDescriptor.Builder(
193a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                VARIABLE_VOLUME_QUEUING_ROUTE_ID,
194a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                r.getString(R.string.variable_volume_queuing_route_name))
195b28eb61b29c0d956a5e504716cdea9f31184a998Jeff Brown                .setDescription(r.getString(R.string.sample_route_description))
196a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                .addControlFilters(CONTROL_FILTERS_QUEUING)
197a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                .setPlaybackStream(AudioManager.STREAM_MUSIC)
198a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                .setPlaybackType(MediaRouter.RouteInfo.PLAYBACK_TYPE_REMOTE)
199a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                .setVolumeHandling(MediaRouter.RouteInfo.PLAYBACK_VOLUME_VARIABLE)
200a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                .setVolumeMax(VOLUME_MAX)
201a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                .setVolume(mVolume)
2025d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik                .setCanDisconnect(true)
203a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                .build();
204a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang
205b75af7ac526bff715c04ab79414700125f895663Sungsoo Lim        Uri iconUri = Uri.parse("android.resource://com.example.android.supportv7/"
206b75af7ac526bff715c04ab79414700125f895663Sungsoo Lim                + R.drawable.ic_android);
207a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        MediaRouteDescriptor routeDescriptor4 = new MediaRouteDescriptor.Builder(
208a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                VARIABLE_VOLUME_SESSION_ROUTE_ID,
209a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                r.getString(R.string.variable_volume_session_route_name))
210a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                .setDescription(r.getString(R.string.sample_route_description))
211a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                .addControlFilters(CONTROL_FILTERS_SESSION)
2127578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                .setPlaybackStream(AudioManager.STREAM_MUSIC)
21355e47d370890d3cbdab82857090c42df734ba276Jeff Brown                .setPlaybackType(MediaRouter.RouteInfo.PLAYBACK_TYPE_REMOTE)
21455e47d370890d3cbdab82857090c42df734ba276Jeff Brown                .setVolumeHandling(MediaRouter.RouteInfo.PLAYBACK_VOLUME_VARIABLE)
21555e47d370890d3cbdab82857090c42df734ba276Jeff Brown                .setVolumeMax(VOLUME_MAX)
21655e47d370890d3cbdab82857090c42df734ba276Jeff Brown                .setVolume(mVolume)
21776d965dc41863b33f887db33d283cb7f1523f60dJae Seo                .setIconUri(iconUri)
21876d965dc41863b33f887db33d283cb7f1523f60dJae Seo                .build();
21976d965dc41863b33f887db33d283cb7f1523f60dJae Seo
2201636d4634299cba990966c01dbb577275ab8273cJae Seo        MediaRouteProviderDescriptor providerDescriptor = new MediaRouteProviderDescriptor.Builder()
22155e47d370890d3cbdab82857090c42df734ba276Jeff Brown                .addRoute(routeDescriptor1)
22255e47d370890d3cbdab82857090c42df734ba276Jeff Brown                .addRoute(routeDescriptor2)
223a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                .addRoute(routeDescriptor3)
224a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                .addRoute(routeDescriptor4)
22555e47d370890d3cbdab82857090c42df734ba276Jeff Brown                .build();
226ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        setDescriptor(providerDescriptor);
227ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    }
228ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
229ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    private final class SampleRouteController extends MediaRouteProvider.RouteController {
230ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        private final String mRouteId;
231a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        private final SessionManager mSessionManager = new SessionManager("mrp");
232a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        private final Player mPlayer;
233a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        private PendingIntent mSessionReceiver;
234ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
235ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        public SampleRouteController(String routeId) {
236ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            mRouteId = routeId;
2379a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik            mPlayer = Player.create(getContext(), null, null);
238a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            mSessionManager.setPlayer(mPlayer);
239a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            mSessionManager.setCallback(new SessionManager.Callback() {
2408e006e629800b4a2643416f97bca2711af728837Jeff Brown                @Override
241a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                public void onStatusChanged() {
2428e006e629800b4a2643416f97bca2711af728837Jeff Brown                }
2438e006e629800b4a2643416f97bca2711af728837Jeff Brown
2448e006e629800b4a2643416f97bca2711af728837Jeff Brown                @Override
245a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                public void onItemChanged(PlaylistItem item) {
246a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    handleStatusChange(item);
2478e006e629800b4a2643416f97bca2711af728837Jeff Brown                }
2488e006e629800b4a2643416f97bca2711af728837Jeff Brown            });
249cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang            setVolumeInternal(mVolume);
250ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            Log.d(TAG, mRouteId + ": Controller created");
251ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        }
252ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
253ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        @Override
254bc89096eeed02fd163eaed46b88364486c76c4feJeff Brown        public void onRelease() {
255ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            Log.d(TAG, mRouteId + ": Controller released");
256a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            mPlayer.release();
257ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        }
258ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
259ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        @Override
260bc89096eeed02fd163eaed46b88364486c76c4feJeff Brown        public void onSelect() {
261ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            Log.d(TAG, mRouteId + ": Selected");
262a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            mPlayer.connect(null);
263ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        }
264ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
265ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        @Override
266bc89096eeed02fd163eaed46b88364486c76c4feJeff Brown        public void onUnselect() {
267ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            Log.d(TAG, mRouteId + ": Unselected");
268a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            mPlayer.release();
269ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        }
270ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
271ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        @Override
272bc89096eeed02fd163eaed46b88364486c76c4feJeff Brown        public void onSetVolume(int volume) {
273ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            Log.d(TAG, mRouteId + ": Set volume to " + volume);
274a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            if (!mRouteId.equals(FIXED_VOLUME_ROUTE_ID)) {
275ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown                setVolumeInternal(volume);
276ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            }
277ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        }
278ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
279ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        @Override
280bc89096eeed02fd163eaed46b88364486c76c4feJeff Brown        public void onUpdateVolume(int delta) {
281ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            Log.d(TAG, mRouteId + ": Update volume by " + delta);
282a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            if (!mRouteId.equals(FIXED_VOLUME_ROUTE_ID)) {
283ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown                setVolumeInternal(mVolume + delta);
284ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            }
285ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        }
286ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
287ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        @Override
288bc89096eeed02fd163eaed46b88364486c76c4feJeff Brown        public boolean onControlRequest(Intent intent, ControlRequestCallback callback) {
289ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            Log.d(TAG, mRouteId + ": Received control request " + intent);
29057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            String action = intent.getAction();
29157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            if (intent.hasCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)) {
29257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                boolean success = false;
29357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                if (action.equals(MediaControlIntent.ACTION_PLAY)) {
29457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    success = handlePlay(intent, callback);
29557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                } else if (action.equals(MediaControlIntent.ACTION_ENQUEUE)) {
29657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    success = handleEnqueue(intent, callback);
29757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                } else if (action.equals(MediaControlIntent.ACTION_REMOVE)) {
29857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    success = handleRemove(intent, callback);
29957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                } else if (action.equals(MediaControlIntent.ACTION_SEEK)) {
30057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    success = handleSeek(intent, callback);
30157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                } else if (action.equals(MediaControlIntent.ACTION_GET_STATUS)) {
30257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    success = handleGetStatus(intent, callback);
30357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                } else if (action.equals(MediaControlIntent.ACTION_PAUSE)) {
30457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    success = handlePause(intent, callback);
30557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                } else if (action.equals(MediaControlIntent.ACTION_RESUME)) {
30657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    success = handleResume(intent, callback);
30757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                } else if (action.equals(MediaControlIntent.ACTION_STOP)) {
30857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    success = handleStop(intent, callback);
309a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                } else if (action.equals(MediaControlIntent.ACTION_START_SESSION)) {
310a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    success = handleStartSession(intent, callback);
311a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                } else if (action.equals(MediaControlIntent.ACTION_GET_SESSION_STATUS)) {
312a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    success = handleGetSessionStatus(intent, callback);
313a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                } else if (action.equals(MediaControlIntent.ACTION_END_SESSION)) {
314a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    success = handleEndSession(intent, callback);
315ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown                }
31657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                Log.d(TAG, mSessionManager.toString());
31757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                return success;
318ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            }
319ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown
32070f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho            if (callback != null && action.equals(ACTION_TAKE_SNAPSHOT)
321ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown                    && intent.hasCategory(CATEGORY_SAMPLE_ROUTE)) {
32270f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho                if (mSessionManager.getCurrentItem() != null) {
32370f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho                    Bundle data = new Bundle();
32470f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho                    data.putParcelable(EXTRA_SNAPSHOT, mPlayer.getSnapshot());
325fcb6a9d1caaf43ae41f859ebb58a4483b12475a1Jeff Brown                    callback.onResult(data);
32670f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho                } else {
32770f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho                    callback.onError("Failed to take a snapshot", null);
328ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown                }
329ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown                return true;
330ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            }
331ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown            return false;
332ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown        }
33357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
33457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        private void setVolumeInternal(int volume) {
33557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            if (volume >= 0 && volume <= VOLUME_MAX) {
33657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                mVolume = volume;
33757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                Log.d(TAG, mRouteId + ": New volume is " + mVolume);
3387578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                AudioManager audioManager =
3397578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                        (AudioManager)getContext().getSystemService(Context.AUDIO_SERVICE);
3407578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang                audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, volume, 0);
34157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                publishRoutes();
34257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
34357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
34457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
34557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        private boolean handlePlay(Intent intent, ControlRequestCallback callback) {
34657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            String sid = intent.getStringExtra(MediaControlIntent.EXTRA_SESSION_ID);
347a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            if (sid != null && !sid.equals(mSessionManager.getSessionId())) {
348a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                Log.d(TAG, "handlePlay fails because of bad sid="+sid);
349a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                return false;
35057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
351a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            if (mSessionManager.hasSession()) {
352a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                mSessionManager.stop();
353a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            }
354a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            return handleEnqueue(intent, callback);
35557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
35657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
35757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        private boolean handleEnqueue(Intent intent, ControlRequestCallback callback) {
358a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            String sid = intent.getStringExtra(MediaControlIntent.EXTRA_SESSION_ID);
359a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            if (sid != null && !sid.equals(mSessionManager.getSessionId())) {
360a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                Log.d(TAG, "handleEnqueue fails because of bad sid="+sid);
36157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                return false;
36257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
36357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
364a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            Uri uri = intent.getData();
365a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            if (uri == null) {
366a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                Log.d(TAG, "handleEnqueue fails because of bad uri="+uri);
367a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                return false;
368a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            }
36957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
37057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            boolean enqueue = intent.getAction().equals(MediaControlIntent.ACTION_ENQUEUE);
371a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            String mime = intent.getType();
37257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            long pos = intent.getLongExtra(MediaControlIntent.EXTRA_ITEM_CONTENT_POSITION, 0);
37357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            Bundle metadata = intent.getBundleExtra(MediaControlIntent.EXTRA_ITEM_METADATA);
37457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            Bundle headers = intent.getBundleExtra(MediaControlIntent.EXTRA_ITEM_HTTP_HEADERS);
37557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            PendingIntent receiver = (PendingIntent)intent.getParcelableExtra(
37657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    MediaControlIntent.EXTRA_ITEM_STATUS_UPDATE_RECEIVER);
37757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
37857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            Log.d(TAG, mRouteId + ": Received " + (enqueue?"enqueue":"play") + " request"
37957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    + ", uri=" + uri
380a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    + ", mime=" + mime
38157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    + ", sid=" + sid
38257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    + ", pos=" + pos
38357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    + ", metadata=" + metadata
38457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    + ", headers=" + headers
38557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    + ", receiver=" + receiver);
38670f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho            PlaylistItem item = mSessionManager.add(null, uri, mime, receiver);
38757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            if (callback != null) {
38857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                if (item != null) {
38957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    Bundle result = new Bundle();
39057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    result.putString(MediaControlIntent.EXTRA_SESSION_ID, item.getSessionId());
39157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    result.putString(MediaControlIntent.EXTRA_ITEM_ID, item.getItemId());
39257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    result.putBundle(MediaControlIntent.EXTRA_ITEM_STATUS,
39357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                            item.getStatus().asBundle());
39457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    callback.onResult(result);
39557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                } else {
39657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    callback.onError("Failed to open " + uri.toString(), null);
39757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                }
39857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
39957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            return true;
40057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
40157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
40257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        private boolean handleRemove(Intent intent, ControlRequestCallback callback) {
40357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            String sid = intent.getStringExtra(MediaControlIntent.EXTRA_SESSION_ID);
404a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            if (sid == null || !sid.equals(mSessionManager.getSessionId())) {
405a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                return false;
406a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            }
407a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang
40857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            String iid = intent.getStringExtra(MediaControlIntent.EXTRA_ITEM_ID);
409a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            PlaylistItem item = mSessionManager.remove(iid);
41057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            if (callback != null) {
41157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                if (item != null) {
41257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    Bundle result = new Bundle();
41357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    result.putBundle(MediaControlIntent.EXTRA_ITEM_STATUS,
41457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                            item.getStatus().asBundle());
41557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    callback.onResult(result);
41657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                } else {
41757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    callback.onError("Failed to remove" +
41857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                            ", sid=" + sid + ", iid=" + iid, null);
41957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                }
42057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
42157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            return (item != null);
42257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
42357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
42457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        private boolean handleSeek(Intent intent, ControlRequestCallback callback) {
42557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            String sid = intent.getStringExtra(MediaControlIntent.EXTRA_SESSION_ID);
426a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            if (sid == null || !sid.equals(mSessionManager.getSessionId())) {
427a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                return false;
428a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            }
429a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang
43057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            String iid = intent.getStringExtra(MediaControlIntent.EXTRA_ITEM_ID);
43157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            long pos = intent.getLongExtra(MediaControlIntent.EXTRA_ITEM_CONTENT_POSITION, 0);
43257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            Log.d(TAG, mRouteId + ": Received seek request, pos=" + pos);
433a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            PlaylistItem item = mSessionManager.seek(iid, pos);
43457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            if (callback != null) {
43557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                if (item != null) {
43657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    Bundle result = new Bundle();
43757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    result.putBundle(MediaControlIntent.EXTRA_ITEM_STATUS,
43857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                            item.getStatus().asBundle());
43957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    callback.onResult(result);
44057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                } else {
44157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    callback.onError("Failed to seek" +
44257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                            ", sid=" + sid + ", iid=" + iid + ", pos=" + pos, null);
44357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                }
44457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
44557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            return (item != null);
44657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
44757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
44857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        private boolean handleGetStatus(Intent intent, ControlRequestCallback callback) {
44957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            String sid = intent.getStringExtra(MediaControlIntent.EXTRA_SESSION_ID);
45057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            String iid = intent.getStringExtra(MediaControlIntent.EXTRA_ITEM_ID);
451a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            Log.d(TAG, mRouteId + ": Received getStatus request, sid=" + sid + ", iid=" + iid);
452a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            PlaylistItem item = mSessionManager.getStatus(iid);
45357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            if (callback != null) {
45457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                if (item != null) {
45557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    Bundle result = new Bundle();
45657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    result.putBundle(MediaControlIntent.EXTRA_ITEM_STATUS,
45757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                            item.getStatus().asBundle());
45857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    callback.onResult(result);
45957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                } else {
46057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    callback.onError("Failed to get status" +
46157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                            ", sid=" + sid + ", iid=" + iid, null);
46257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                }
46357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
46457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            return (item != null);
46557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
46657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
46757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        private boolean handlePause(Intent intent, ControlRequestCallback callback) {
46857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            String sid = intent.getStringExtra(MediaControlIntent.EXTRA_SESSION_ID);
469a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            boolean success = (sid != null) && sid.equals(mSessionManager.getSessionId());
470a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            mSessionManager.pause();
47157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            if (callback != null) {
47257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                if (success) {
473a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    callback.onResult(new Bundle());
474a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    handleSessionStatusChange(sid);
47557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                } else {
47657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    callback.onError("Failed to pause, sid=" + sid, null);
47757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                }
47857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
47957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            return success;
48057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
48157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
48257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        private boolean handleResume(Intent intent, ControlRequestCallback callback) {
48357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            String sid = intent.getStringExtra(MediaControlIntent.EXTRA_SESSION_ID);
484a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            boolean success = (sid != null) && sid.equals(mSessionManager.getSessionId());
485a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            mSessionManager.resume();
48657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            if (callback != null) {
48757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                if (success) {
488a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    callback.onResult(new Bundle());
489a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    handleSessionStatusChange(sid);
49057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                } else {
49157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    callback.onError("Failed to resume, sid=" + sid, null);
49257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                }
49357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
49457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            return success;
49557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
49657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
49757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        private boolean handleStop(Intent intent, ControlRequestCallback callback) {
49857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            String sid = intent.getStringExtra(MediaControlIntent.EXTRA_SESSION_ID);
499a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            boolean success = (sid != null) && sid.equals(mSessionManager.getSessionId());
500a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            mSessionManager.stop();
50157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            if (callback != null) {
50257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                if (success) {
503a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    callback.onResult(new Bundle());
504a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    handleSessionStatusChange(sid);
50557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                } else {
50657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    callback.onError("Failed to stop, sid=" + sid, null);
50757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                }
50857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
50957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            return success;
51057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
51157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
512a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        private boolean handleStartSession(Intent intent, ControlRequestCallback callback) {
513a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            String sid = mSessionManager.startSession();
514a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            Log.d(TAG, "StartSession returns sessionId "+sid);
515a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            if (callback != null) {
516a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                if (sid != null) {
517a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    Bundle result = new Bundle();
518a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    result.putString(MediaControlIntent.EXTRA_SESSION_ID, sid);
519a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    result.putBundle(MediaControlIntent.EXTRA_SESSION_STATUS,
520a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                            mSessionManager.getSessionStatus(sid).asBundle());
521a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    callback.onResult(result);
522a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    mSessionReceiver = (PendingIntent)intent.getParcelableExtra(
523a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                            MediaControlIntent.EXTRA_SESSION_STATUS_UPDATE_RECEIVER);
524a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    handleSessionStatusChange(sid);
525a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                } else {
526a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    callback.onError("Failed to start session.", null);
527a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                }
528a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            }
529a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            return (sid != null);
530a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        }
531a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang
532a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        private boolean handleGetSessionStatus(Intent intent, ControlRequestCallback callback) {
533a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            String sid = intent.getStringExtra(MediaControlIntent.EXTRA_SESSION_ID);
534a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang
535a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            MediaSessionStatus sessionStatus = mSessionManager.getSessionStatus(sid);
536a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            if (callback != null) {
537a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                if (sessionStatus != null) {
538a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    Bundle result = new Bundle();
539a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    result.putBundle(MediaControlIntent.EXTRA_SESSION_STATUS,
540a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                            mSessionManager.getSessionStatus(sid).asBundle());
541a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    callback.onResult(result);
542a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                } else {
543a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    callback.onError("Failed to get session status, sid=" + sid, null);
544a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                }
54557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
546a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            return (sessionStatus != null);
54757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
54857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
549a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        private boolean handleEndSession(Intent intent, ControlRequestCallback callback) {
550a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            String sid = intent.getStringExtra(MediaControlIntent.EXTRA_SESSION_ID);
551a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            boolean success = (sid != null) && sid.equals(mSessionManager.getSessionId())
552a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    && mSessionManager.endSession();
553a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            if (callback != null) {
554a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                if (success) {
555a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    Bundle result = new Bundle();
556a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    MediaSessionStatus sessionStatus = new MediaSessionStatus.Builder(
557a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                            MediaSessionStatus.SESSION_STATE_ENDED).build();
558a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    result.putBundle(MediaControlIntent.EXTRA_SESSION_STATUS, sessionStatus.asBundle());
559a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    callback.onResult(result);
560a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    handleSessionStatusChange(sid);
561a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    mSessionReceiver = null;
562a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                } else {
563a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    callback.onError("Failed to end session, sid=" + sid, null);
564a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                }
565a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            }
566a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            return success;
567a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        }
568a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang
569a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        private void handleStatusChange(PlaylistItem item) {
57057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            if (item == null) {
57157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                item = mSessionManager.getCurrentItem();
57257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
57357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            if (item != null) {
57457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                PendingIntent receiver = item.getUpdateReceiver();
57557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                if (receiver != null) {
57657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    Intent intent = new Intent();
57757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    intent.putExtra(MediaControlIntent.EXTRA_SESSION_ID, item.getSessionId());
57857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    intent.putExtra(MediaControlIntent.EXTRA_ITEM_ID, item.getItemId());
57957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    intent.putExtra(MediaControlIntent.EXTRA_ITEM_STATUS,
58057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                            item.getStatus().asBundle());
58157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    try {
58257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                        receiver.send(getContext(), 0, intent);
58357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                        Log.d(TAG, mRouteId + ": Sending status update from provider");
58457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    } catch (PendingIntent.CanceledException e) {
58557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                        Log.d(TAG, mRouteId + ": Failed to send status update!");
58657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                    }
58757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang                }
58857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
58957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
59057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang
591a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang        private void handleSessionStatusChange(String sid) {
592a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang            if (mSessionReceiver != null) {
593a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                Intent intent = new Intent();
594a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                intent.putExtra(MediaControlIntent.EXTRA_SESSION_ID, sid);
595a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                intent.putExtra(MediaControlIntent.EXTRA_SESSION_STATUS,
596a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                        mSessionManager.getSessionStatus(sid).asBundle());
597a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                try {
598a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    mSessionReceiver.send(getContext(), 0, intent);
599a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    Log.d(TAG, mRouteId + ": Sending session status update from provider");
600a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                } catch (PendingIntent.CanceledException e) {
601a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                    Log.d(TAG, mRouteId + ": Failed to send session status update!");
602a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang                }
60357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang            }
60457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang        }
605ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown    }
606e0189a39290c82f8bc1a37e6a52e959159c9a482Jae Seo}
607