blob: 739e3ba73cab1bce68389598c2afbe61d889a056 [file] [log] [blame]
Alexander Lucas97842ff2014-03-07 14:56:55 -08001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.example.android.mediarouter.provider;
18
19import android.app.PendingIntent;
20import android.content.Context;
21import android.content.Intent;
22import android.content.IntentFilter;
23import android.content.IntentFilter.MalformedMimeTypeException;
24import android.content.res.Resources;
25import android.media.AudioManager;
26import android.media.MediaRouter;
27import android.net.Uri;
28import android.os.Bundle;
29import android.support.v7.media.MediaControlIntent;
30import android.support.v7.media.MediaRouteDescriptor;
31import android.support.v7.media.MediaRouteProvider;
32import android.support.v7.media.MediaRouteProviderDescriptor;
33import android.support.v7.media.MediaRouter.ControlRequestCallback;
34import android.support.v7.media.MediaSessionStatus;
35import android.util.Log;
36
37import com.example.android.mediarouter.player.Player;
38import com.example.android.mediarouter.player.PlaylistItem;
39import com.example.android.mediarouter.R;
40import com.example.android.mediarouter.player.SessionManager;
41
42import java.util.ArrayList;
43
44/**
45 * Demonstrates how to create a custom media route provider.
46 *
47 * @see SampleMediaRouteProviderService
48 */
49public final class SampleMediaRouteProvider extends MediaRouteProvider {
50 private static final String TAG = "SampleMediaRouteProvider";
51
52 private static final String FIXED_VOLUME_ROUTE_ID = "fixed";
53 private static final String VARIABLE_VOLUME_BASIC_ROUTE_ID = "variable_basic";
54 private static final String VARIABLE_VOLUME_QUEUING_ROUTE_ID = "variable_queuing";
55 private static final String VARIABLE_VOLUME_SESSION_ROUTE_ID = "variable_session";
56 private static final int VOLUME_MAX = 10;
57
58 /**
59 * A custom media control intent category for special requests that are
60 * supported by this provider's routes.
61 */
62 public static final String CATEGORY_SAMPLE_ROUTE =
63 "com.example.android.mediarouteprovider.CATEGORY_SAMPLE_ROUTE";
64
65 /**
66 * A custom media control intent action for special requests that are
67 * supported by this provider's routes.
68 * <p>
69 * This particular request is designed to return a bundle of not very
70 * interesting statistics for demonstration purposes.
71 * </p>
72 *
73 * @see #DATA_PLAYBACK_COUNT
74 */
75 public static final String ACTION_GET_STATISTICS =
76 "com.example.android.mediarouteprovider.ACTION_GET_STATISTICS";
77
78 /**
79 * {@link #ACTION_GET_STATISTICS} result data: Number of times the
80 * playback action was invoked.
81 */
82 public static final String DATA_PLAYBACK_COUNT =
83 "com.example.android.mediarouteprovider.EXTRA_PLAYBACK_COUNT";
84
85 private static final ArrayList<IntentFilter> CONTROL_FILTERS_BASIC;
86 private static final ArrayList<IntentFilter> CONTROL_FILTERS_QUEUING;
87 private static final ArrayList<IntentFilter> CONTROL_FILTERS_SESSION;
88
89 static {
90 IntentFilter f1 = new IntentFilter();
91 f1.addCategory(CATEGORY_SAMPLE_ROUTE);
92 f1.addAction(ACTION_GET_STATISTICS);
93
94 IntentFilter f2 = new IntentFilter();
95 f2.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
96 f2.addAction(MediaControlIntent.ACTION_PLAY);
97 f2.addDataScheme("http");
98 f2.addDataScheme("https");
99 f2.addDataScheme("rtsp");
100 f2.addDataScheme("file");
101 addDataTypeUnchecked(f2, "video/*");
102
103 IntentFilter f3 = new IntentFilter();
104 f3.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
105 f3.addAction(MediaControlIntent.ACTION_SEEK);
106 f3.addAction(MediaControlIntent.ACTION_GET_STATUS);
107 f3.addAction(MediaControlIntent.ACTION_PAUSE);
108 f3.addAction(MediaControlIntent.ACTION_RESUME);
109 f3.addAction(MediaControlIntent.ACTION_STOP);
110
111 IntentFilter f4 = new IntentFilter();
112 f4.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
113 f4.addAction(MediaControlIntent.ACTION_ENQUEUE);
114 f4.addDataScheme("http");
115 f4.addDataScheme("https");
116 f4.addDataScheme("rtsp");
117 f4.addDataScheme("file");
118 addDataTypeUnchecked(f4, "video/*");
119
120 IntentFilter f5 = new IntentFilter();
121 f5.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
122 f5.addAction(MediaControlIntent.ACTION_REMOVE);
123
124 IntentFilter f6 = new IntentFilter();
125 f6.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
126 f6.addAction(MediaControlIntent.ACTION_START_SESSION);
127 f6.addAction(MediaControlIntent.ACTION_GET_SESSION_STATUS);
128 f6.addAction(MediaControlIntent.ACTION_END_SESSION);
129
130 CONTROL_FILTERS_BASIC = new ArrayList<IntentFilter>();
131 CONTROL_FILTERS_BASIC.add(f1);
132 CONTROL_FILTERS_BASIC.add(f2);
133 CONTROL_FILTERS_BASIC.add(f3);
134
135 CONTROL_FILTERS_QUEUING =
136 new ArrayList<IntentFilter>(CONTROL_FILTERS_BASIC);
137 CONTROL_FILTERS_QUEUING.add(f4);
138 CONTROL_FILTERS_QUEUING.add(f5);
139
140 CONTROL_FILTERS_SESSION =
141 new ArrayList<IntentFilter>(CONTROL_FILTERS_QUEUING);
142 CONTROL_FILTERS_SESSION.add(f6);
143 }
144
145 private static void addDataTypeUnchecked(IntentFilter filter, String type) {
146 try {
147 filter.addDataType(type);
148 } catch (MalformedMimeTypeException ex) {
149 throw new RuntimeException(ex);
150 }
151 }
152
153 private int mVolume = 5;
154 private int mEnqueueCount;
155
156 public SampleMediaRouteProvider(Context context) {
157 super(context);
158
159 publishRoutes();
160 }
161
162 @Override
163 public RouteController onCreateRouteController(String routeId) {
164 return new SampleRouteController(routeId);
165 }
166
167 private void publishRoutes() {
168 Resources r = getContext().getResources();
169
170 MediaRouteDescriptor routeDescriptor1 = new MediaRouteDescriptor.Builder(
171 FIXED_VOLUME_ROUTE_ID,
172 r.getString(R.string.fixed_volume_route_name))
173 .setDescription(r.getString(R.string.sample_route_description))
174 .addControlFilters(CONTROL_FILTERS_BASIC)
175 .setPlaybackStream(AudioManager.STREAM_MUSIC)
176 .setPlaybackType(MediaRouter.RouteInfo.PLAYBACK_TYPE_REMOTE)
177 .setVolumeHandling(MediaRouter.RouteInfo.PLAYBACK_VOLUME_FIXED)
178 .setVolume(VOLUME_MAX)
179 .build();
180
181 MediaRouteDescriptor routeDescriptor2 = new MediaRouteDescriptor.Builder(
182 VARIABLE_VOLUME_BASIC_ROUTE_ID,
183 r.getString(R.string.variable_volume_basic_route_name))
184 .setDescription(r.getString(R.string.sample_route_description))
185 .addControlFilters(CONTROL_FILTERS_BASIC)
186 .setPlaybackStream(AudioManager.STREAM_MUSIC)
187 .setPlaybackType(MediaRouter.RouteInfo.PLAYBACK_TYPE_REMOTE)
188 .setVolumeHandling(MediaRouter.RouteInfo.PLAYBACK_VOLUME_VARIABLE)
189 .setVolumeMax(VOLUME_MAX)
190 .setVolume(mVolume)
191 .build();
192
193 MediaRouteDescriptor routeDescriptor3 = new MediaRouteDescriptor.Builder(
194 VARIABLE_VOLUME_QUEUING_ROUTE_ID,
195 r.getString(R.string.variable_volume_queuing_route_name))
196 .setDescription(r.getString(R.string.sample_route_description))
197 .addControlFilters(CONTROL_FILTERS_QUEUING)
198 .setPlaybackStream(AudioManager.STREAM_MUSIC)
199 .setPlaybackType(MediaRouter.RouteInfo.PLAYBACK_TYPE_REMOTE)
200 .setVolumeHandling(MediaRouter.RouteInfo.PLAYBACK_VOLUME_VARIABLE)
201 .setVolumeMax(VOLUME_MAX)
202 .setVolume(mVolume)
203 .build();
204
205 MediaRouteDescriptor routeDescriptor4 = new MediaRouteDescriptor.Builder(
206 VARIABLE_VOLUME_SESSION_ROUTE_ID,
207 r.getString(R.string.variable_volume_session_route_name))
208 .setDescription(r.getString(R.string.sample_route_description))
209 .addControlFilters(CONTROL_FILTERS_SESSION)
210 .setPlaybackStream(AudioManager.STREAM_MUSIC)
211 .setPlaybackType(MediaRouter.RouteInfo.PLAYBACK_TYPE_REMOTE)
212 .setVolumeHandling(MediaRouter.RouteInfo.PLAYBACK_VOLUME_VARIABLE)
213 .setVolumeMax(VOLUME_MAX)
214 .setVolume(mVolume)
215 .build();
216
217 MediaRouteProviderDescriptor providerDescriptor =
218 new MediaRouteProviderDescriptor.Builder()
219 .addRoute(routeDescriptor1)
220 .addRoute(routeDescriptor2)
221 .addRoute(routeDescriptor3)
222 .addRoute(routeDescriptor4)
223 .build();
224 setDescriptor(providerDescriptor);
225 }
226
227 private final class SampleRouteController extends MediaRouteProvider.RouteController {
228 private final String mRouteId;
229 private final SessionManager mSessionManager = new SessionManager("mrp");
230 private final Player mPlayer;
231 private PendingIntent mSessionReceiver;
232
233 public SampleRouteController(String routeId) {
234 mRouteId = routeId;
235 mPlayer = Player.create(getContext(), null);
236 mSessionManager.setPlayer(mPlayer);
237 mSessionManager.setCallback(new SessionManager.Callback() {
238 @Override
239 public void onStatusChanged() {
240 }
241
242 @Override
243 public void onItemChanged(PlaylistItem item) {
244 handleStatusChange(item);
245 }
246 });
247 Log.d(TAG, mRouteId + ": Controller created");
248 }
249
250 @Override
251 public void onRelease() {
252 Log.d(TAG, mRouteId + ": Controller released");
253 mPlayer.release();
254 }
255
256 @Override
257 public void onSelect() {
258 Log.d(TAG, mRouteId + ": Selected");
259 mPlayer.connect(null);
260 }
261
262 @Override
263 public void onUnselect() {
264 Log.d(TAG, mRouteId + ": Unselected");
265 mPlayer.release();
266 }
267
268 @Override
269 public void onSetVolume(int volume) {
270 Log.d(TAG, mRouteId + ": Set volume to " + volume);
271 if (!mRouteId.equals(FIXED_VOLUME_ROUTE_ID)) {
272 setVolumeInternal(volume);
273 }
274 }
275
276 @Override
277 public void onUpdateVolume(int delta) {
278 Log.d(TAG, mRouteId + ": Update volume by " + delta);
279 if (!mRouteId.equals(FIXED_VOLUME_ROUTE_ID)) {
280 setVolumeInternal(mVolume + delta);
281 }
282 }
283
284 @Override
285 public boolean onControlRequest(Intent intent, ControlRequestCallback callback) {
286 Log.d(TAG, mRouteId + ": Received control request " + intent);
287 String action = intent.getAction();
288 if (intent.hasCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)) {
289 boolean success = false;
290 if (action.equals(MediaControlIntent.ACTION_PLAY)) {
291 success = handlePlay(intent, callback);
292 } else if (action.equals(MediaControlIntent.ACTION_ENQUEUE)) {
293 success = handleEnqueue(intent, callback);
294 } else if (action.equals(MediaControlIntent.ACTION_REMOVE)) {
295 success = handleRemove(intent, callback);
296 } else if (action.equals(MediaControlIntent.ACTION_SEEK)) {
297 success = handleSeek(intent, callback);
298 } else if (action.equals(MediaControlIntent.ACTION_GET_STATUS)) {
299 success = handleGetStatus(intent, callback);
300 } else if (action.equals(MediaControlIntent.ACTION_PAUSE)) {
301 success = handlePause(intent, callback);
302 } else if (action.equals(MediaControlIntent.ACTION_RESUME)) {
303 success = handleResume(intent, callback);
304 } else if (action.equals(MediaControlIntent.ACTION_STOP)) {
305 success = handleStop(intent, callback);
306 } else if (action.equals(MediaControlIntent.ACTION_START_SESSION)) {
307 success = handleStartSession(intent, callback);
308 } else if (action.equals(MediaControlIntent.ACTION_GET_SESSION_STATUS)) {
309 success = handleGetSessionStatus(intent, callback);
310 } else if (action.equals(MediaControlIntent.ACTION_END_SESSION)) {
311 success = handleEndSession(intent, callback);
312 }
313 Log.d(TAG, mSessionManager.toString());
314 return success;
315 }
316
317 if (action.equals(ACTION_GET_STATISTICS)
318 && intent.hasCategory(CATEGORY_SAMPLE_ROUTE)) {
319 Bundle data = new Bundle();
320 data.putInt(DATA_PLAYBACK_COUNT, mEnqueueCount);
321 if (callback != null) {
322 callback.onResult(data);
323 }
324 return true;
325 }
326 return false;
327 }
328
329 private void setVolumeInternal(int volume) {
330 if (volume >= 0 && volume <= VOLUME_MAX) {
331 mVolume = volume;
332 Log.d(TAG, mRouteId + ": New volume is " + mVolume);
333 AudioManager audioManager =
334 (AudioManager)getContext().getSystemService(Context.AUDIO_SERVICE);
335 audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, volume, 0);
336 publishRoutes();
337 }
338 }
339
340 private boolean handlePlay(Intent intent, ControlRequestCallback callback) {
341 String sid = intent.getStringExtra(MediaControlIntent.EXTRA_SESSION_ID);
342 if (sid != null && !sid.equals(mSessionManager.getSessionId())) {
343 Log.d(TAG, "handlePlay fails because of bad sid="+sid);
344 return false;
345 }
346 if (mSessionManager.hasSession()) {
347 mSessionManager.stop();
348 }
349 return handleEnqueue(intent, callback);
350 }
351
352 private boolean handleEnqueue(Intent intent, ControlRequestCallback callback) {
353 String sid = intent.getStringExtra(MediaControlIntent.EXTRA_SESSION_ID);
354 if (sid != null && !sid.equals(mSessionManager.getSessionId())) {
355 Log.d(TAG, "handleEnqueue fails because of bad sid="+sid);
356 return false;
357 }
358
359 Uri uri = intent.getData();
360 if (uri == null) {
361 Log.d(TAG, "handleEnqueue fails because of bad uri="+uri);
362 return false;
363 }
364
365 boolean enqueue = intent.getAction().equals(MediaControlIntent.ACTION_ENQUEUE);
366 String mime = intent.getType();
367 long pos = intent.getLongExtra(MediaControlIntent.EXTRA_ITEM_CONTENT_POSITION, 0);
368 Bundle metadata = intent.getBundleExtra(MediaControlIntent.EXTRA_ITEM_METADATA);
369 Bundle headers = intent.getBundleExtra(MediaControlIntent.EXTRA_ITEM_HTTP_HEADERS);
370 PendingIntent receiver = (PendingIntent)intent.getParcelableExtra(
371 MediaControlIntent.EXTRA_ITEM_STATUS_UPDATE_RECEIVER);
372
373 Log.d(TAG, mRouteId + ": Received " + (enqueue?"enqueue":"play") + " request"
374 + ", uri=" + uri
375 + ", mime=" + mime
376 + ", sid=" + sid
377 + ", pos=" + pos
378 + ", metadata=" + metadata
379 + ", headers=" + headers
380 + ", receiver=" + receiver);
381 PlaylistItem item = mSessionManager.add(uri, mime, receiver);
382 if (callback != null) {
383 if (item != null) {
384 Bundle result = new Bundle();
385 result.putString(MediaControlIntent.EXTRA_SESSION_ID, item.getSessionId());
386 result.putString(MediaControlIntent.EXTRA_ITEM_ID, item.getItemId());
387 result.putBundle(MediaControlIntent.EXTRA_ITEM_STATUS,
388 item.getStatus().asBundle());
389 callback.onResult(result);
390 } else {
391 callback.onError("Failed to open " + uri.toString(), null);
392 }
393 }
394 mEnqueueCount +=1;
395 return true;
396 }
397
398 private boolean handleRemove(Intent intent, ControlRequestCallback callback) {
399 String sid = intent.getStringExtra(MediaControlIntent.EXTRA_SESSION_ID);
400 if (sid == null || !sid.equals(mSessionManager.getSessionId())) {
401 return false;
402 }
403
404 String iid = intent.getStringExtra(MediaControlIntent.EXTRA_ITEM_ID);
405 PlaylistItem item = mSessionManager.remove(iid);
406 if (callback != null) {
407 if (item != null) {
408 Bundle result = new Bundle();
409 result.putBundle(MediaControlIntent.EXTRA_ITEM_STATUS,
410 item.getStatus().asBundle());
411 callback.onResult(result);
412 } else {
413 callback.onError("Failed to remove" +
414 ", sid=" + sid + ", iid=" + iid, null);
415 }
416 }
417 return (item != null);
418 }
419
420 private boolean handleSeek(Intent intent, ControlRequestCallback callback) {
421 String sid = intent.getStringExtra(MediaControlIntent.EXTRA_SESSION_ID);
422 if (sid == null || !sid.equals(mSessionManager.getSessionId())) {
423 return false;
424 }
425
426 String iid = intent.getStringExtra(MediaControlIntent.EXTRA_ITEM_ID);
427 long pos = intent.getLongExtra(MediaControlIntent.EXTRA_ITEM_CONTENT_POSITION, 0);
428 Log.d(TAG, mRouteId + ": Received seek request, pos=" + pos);
429 PlaylistItem item = mSessionManager.seek(iid, pos);
430 if (callback != null) {
431 if (item != null) {
432 Bundle result = new Bundle();
433 result.putBundle(MediaControlIntent.EXTRA_ITEM_STATUS,
434 item.getStatus().asBundle());
435 callback.onResult(result);
436 } else {
437 callback.onError("Failed to seek" +
438 ", sid=" + sid + ", iid=" + iid + ", pos=" + pos, null);
439 }
440 }
441 return (item != null);
442 }
443
444 private boolean handleGetStatus(Intent intent, ControlRequestCallback callback) {
445 String sid = intent.getStringExtra(MediaControlIntent.EXTRA_SESSION_ID);
446 String iid = intent.getStringExtra(MediaControlIntent.EXTRA_ITEM_ID);
447 Log.d(TAG, mRouteId + ": Received getStatus request, sid=" + sid + ", iid=" + iid);
448 PlaylistItem item = mSessionManager.getStatus(iid);
449 if (callback != null) {
450 if (item != null) {
451 Bundle result = new Bundle();
452 result.putBundle(MediaControlIntent.EXTRA_ITEM_STATUS,
453 item.getStatus().asBundle());
454 callback.onResult(result);
455 } else {
456 callback.onError("Failed to get status" +
457 ", sid=" + sid + ", iid=" + iid, null);
458 }
459 }
460 return (item != null);
461 }
462
463 private boolean handlePause(Intent intent, ControlRequestCallback callback) {
464 String sid = intent.getStringExtra(MediaControlIntent.EXTRA_SESSION_ID);
465 boolean success = (sid != null) && sid.equals(mSessionManager.getSessionId());
466 mSessionManager.pause();
467 if (callback != null) {
468 if (success) {
469 callback.onResult(new Bundle());
470 handleSessionStatusChange(sid);
471 } else {
472 callback.onError("Failed to pause, sid=" + sid, null);
473 }
474 }
475 return success;
476 }
477
478 private boolean handleResume(Intent intent, ControlRequestCallback callback) {
479 String sid = intent.getStringExtra(MediaControlIntent.EXTRA_SESSION_ID);
480 boolean success = (sid != null) && sid.equals(mSessionManager.getSessionId());
481 mSessionManager.resume();
482 if (callback != null) {
483 if (success) {
484 callback.onResult(new Bundle());
485 handleSessionStatusChange(sid);
486 } else {
487 callback.onError("Failed to resume, sid=" + sid, null);
488 }
489 }
490 return success;
491 }
492
493 private boolean handleStop(Intent intent, ControlRequestCallback callback) {
494 String sid = intent.getStringExtra(MediaControlIntent.EXTRA_SESSION_ID);
495 boolean success = (sid != null) && sid.equals(mSessionManager.getSessionId());
496 mSessionManager.stop();
497 if (callback != null) {
498 if (success) {
499 callback.onResult(new Bundle());
500 handleSessionStatusChange(sid);
501 } else {
502 callback.onError("Failed to stop, sid=" + sid, null);
503 }
504 }
505 return success;
506 }
507
508 private boolean handleStartSession(Intent intent, ControlRequestCallback callback) {
509 String sid = mSessionManager.startSession();
510 Log.d(TAG, "StartSession returns sessionId "+sid);
511 if (callback != null) {
512 if (sid != null) {
513 Bundle result = new Bundle();
514 result.putString(MediaControlIntent.EXTRA_SESSION_ID, sid);
515 result.putBundle(MediaControlIntent.EXTRA_SESSION_STATUS,
516 mSessionManager.getSessionStatus(sid).asBundle());
517 callback.onResult(result);
518 mSessionReceiver = (PendingIntent)intent.getParcelableExtra(
519 MediaControlIntent.EXTRA_SESSION_STATUS_UPDATE_RECEIVER);
520 handleSessionStatusChange(sid);
521 } else {
522 callback.onError("Failed to start session.", null);
523 }
524 }
525 return (sid != null);
526 }
527
528 private boolean handleGetSessionStatus(Intent intent, ControlRequestCallback callback) {
529 String sid = intent.getStringExtra(MediaControlIntent.EXTRA_SESSION_ID);
530
531 MediaSessionStatus sessionStatus = mSessionManager.getSessionStatus(sid);
532 if (callback != null) {
533 if (sessionStatus != null) {
534 Bundle result = new Bundle();
535 result.putBundle(MediaControlIntent.EXTRA_SESSION_STATUS,
536 mSessionManager.getSessionStatus(sid).asBundle());
537 callback.onResult(result);
538 } else {
539 callback.onError("Failed to get session status, sid=" + sid, null);
540 }
541 }
542 return (sessionStatus != null);
543 }
544
545 private boolean handleEndSession(Intent intent, ControlRequestCallback callback) {
546 String sid = intent.getStringExtra(MediaControlIntent.EXTRA_SESSION_ID);
547 boolean success = (sid != null) && sid.equals(mSessionManager.getSessionId())
548 && mSessionManager.endSession();
549 if (callback != null) {
550 if (success) {
551 Bundle result = new Bundle();
552 MediaSessionStatus sessionStatus = new MediaSessionStatus.Builder(
553 MediaSessionStatus.SESSION_STATE_ENDED).build();
554 result.putBundle(MediaControlIntent.EXTRA_SESSION_STATUS, sessionStatus.asBundle());
555 callback.onResult(result);
556 handleSessionStatusChange(sid);
557 mSessionReceiver = null;
558 } else {
559 callback.onError("Failed to end session, sid=" + sid, null);
560 }
561 }
562 return success;
563 }
564
565 private void handleStatusChange(PlaylistItem item) {
566 if (item == null) {
567 item = mSessionManager.getCurrentItem();
568 }
569 if (item != null) {
570 PendingIntent receiver = item.getUpdateReceiver();
571 if (receiver != null) {
572 Intent intent = new Intent();
573 intent.putExtra(MediaControlIntent.EXTRA_SESSION_ID, item.getSessionId());
574 intent.putExtra(MediaControlIntent.EXTRA_ITEM_ID, item.getItemId());
575 intent.putExtra(MediaControlIntent.EXTRA_ITEM_STATUS,
576 item.getStatus().asBundle());
577 try {
578 receiver.send(getContext(), 0, intent);
579 Log.d(TAG, mRouteId + ": Sending status update from provider");
580 } catch (PendingIntent.CanceledException e) {
581 Log.d(TAG, mRouteId + ": Failed to send status update!");
582 }
583 }
584 }
585 }
586
587 private void handleSessionStatusChange(String sid) {
588 if (mSessionReceiver != null) {
589 Intent intent = new Intent();
590 intent.putExtra(MediaControlIntent.EXTRA_SESSION_ID, sid);
591 intent.putExtra(MediaControlIntent.EXTRA_SESSION_STATUS,
592 mSessionManager.getSessionStatus(sid).asBundle());
593 try {
594 mSessionReceiver.send(getContext(), 0, intent);
595 Log.d(TAG, mRouteId + ": Sending session status update from provider");
596 } catch (PendingIntent.CanceledException e) {
597 Log.d(TAG, mRouteId + ": Failed to send session status update!");
598 }
599 }
600 }
601 }
602}