PlaybackControlsRow.java revision 60bb6af2e336072921f5d3c3861e86b3cc6241b3
1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 * in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the License 10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 * or implied. See the License for the specific language governing permissions and limitations under 12 * the License. 13 */ 14package android.support.v17.leanback.widget; 15 16import android.support.v17.leanback.R; 17import android.util.TypedValue; 18import android.content.Context; 19import android.content.res.TypedArray; 20import android.graphics.Bitmap; 21import android.graphics.BitmapFactory; 22import android.graphics.Canvas; 23import android.graphics.Color; 24import android.graphics.Paint; 25import android.graphics.PorterDuff; 26import android.graphics.PorterDuffColorFilter; 27import android.graphics.drawable.BitmapDrawable; 28import android.graphics.drawable.Drawable; 29import android.view.KeyEvent; 30 31/** 32 * A row of playback controls to be displayed by a {@link PlaybackControlsRowPresenter}. 33 * 34 * This row consists of some optional item detail, a series of primary actions, 35 * and an optional series of secondary actions. 36 * 37 * Controls are specified via an {@link ObjectAdapter} containing one or more 38 * {@link Action}s. 39 * 40 * Adapters should have their {@link PresenterSelector} set to an instance of 41 * {@link ControlButtonPresenterSelector}. 42 * 43 */ 44public class PlaybackControlsRow extends Row { 45 46 /** 47 * Base class for an action comprised of a series of icons. 48 */ 49 public static abstract class MultiAction extends Action { 50 private int mIndex; 51 private Drawable[] mDrawables; 52 private String[] mLabels; 53 private String[] mLabels2; 54 55 /** 56 * Constructor 57 * @param id The id of the Action. 58 */ 59 public MultiAction(int id) { 60 super(id); 61 } 62 63 /** 64 * Sets the array of drawables. The size of the array defines the range 65 * of valid indices for this action. 66 */ 67 public void setDrawables(Drawable[] drawables) { 68 mDrawables = drawables; 69 setIndex(0); 70 } 71 72 /** 73 * Sets the array of strings used as labels. The size of the array defines the range 74 * of valid indices for this action. The labels are used to define the accessibility 75 * content description unless secondary labels are provided. 76 */ 77 public void setLabels(String[] labels) { 78 mLabels = labels; 79 setIndex(0); 80 } 81 82 /** 83 * Sets the array of strings used as secondary labels. These labels are used 84 * in place of the primary labels for accessibility content description only. 85 */ 86 public void setSecondaryLabels(String[] labels) { 87 mLabels2 = labels; 88 setIndex(0); 89 } 90 91 /** 92 * Returns the number of actions. 93 */ 94 public int getActionCount() { 95 if (mDrawables != null) { 96 return mDrawables.length; 97 } 98 if (mLabels != null) { 99 return mLabels.length; 100 } 101 return 0; 102 } 103 104 /** 105 * Returns the drawable at the given index. 106 */ 107 public Drawable getDrawable(int index) { 108 return mDrawables == null ? null : mDrawables[index]; 109 } 110 111 /** 112 * Returns the label at the given index. 113 */ 114 public String getLabel(int index) { 115 return mLabels == null ? null : mLabels[index]; 116 } 117 118 /** 119 * Returns the secondary label at the given index. 120 */ 121 public String getSecondaryLabel(int index) { 122 return mLabels2 == null ? null : mLabels2[index]; 123 } 124 125 /** 126 * Increments the index, wrapping to zero once the end is reached. 127 */ 128 public void nextIndex() { 129 setIndex(mIndex < getActionCount() - 1 ? mIndex + 1 : 0); 130 } 131 132 /** 133 * Sets the current index. 134 */ 135 public void setIndex(int index) { 136 mIndex = index; 137 if (mDrawables != null) { 138 setIcon(mDrawables[mIndex]); 139 } 140 if (mLabels != null) { 141 setLabel1(mLabels[mIndex]); 142 } 143 if (mLabels2 != null) { 144 setLabel2(mLabels2[mIndex]); 145 } 146 } 147 148 /** 149 * Gets the current index. 150 */ 151 public int getIndex() { 152 return mIndex; 153 } 154 } 155 156 /** 157 * An action displaying icons for play and pause. 158 */ 159 public static class PlayPauseAction extends MultiAction { 160 /** 161 * Action index for the play icon. 162 */ 163 public static int PLAY = 0; 164 165 /** 166 * Action index for the pause icon. 167 */ 168 public static int PAUSE = 1; 169 170 /** 171 * Constructor 172 * @param context Context used for loading resources. 173 */ 174 public PlayPauseAction(Context context) { 175 super(R.id.lb_control_play_pause); 176 Drawable[] drawables = new Drawable[2]; 177 drawables[PLAY] = getStyledDrawable(context, 178 R.styleable.lbPlaybackControlsActionIcons_play); 179 drawables[PAUSE] = getStyledDrawable(context, 180 R.styleable.lbPlaybackControlsActionIcons_pause); 181 setDrawables(drawables); 182 183 String[] labels = new String[drawables.length]; 184 labels[PLAY] = context.getString(R.string.lb_playback_controls_play); 185 labels[PAUSE] = context.getString(R.string.lb_playback_controls_pause); 186 setLabels(labels); 187 addKeyCode(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE); 188 addKeyCode(KeyEvent.KEYCODE_MEDIA_PLAY); 189 addKeyCode(KeyEvent.KEYCODE_MEDIA_PAUSE); 190 } 191 } 192 193 /** 194 * An action displaying an icon for fast forward. 195 */ 196 public static class FastForwardAction extends MultiAction { 197 /** 198 * Constructor 199 * @param context Context used for loading resources. 200 */ 201 public FastForwardAction(Context context) { 202 this(context, 1); 203 } 204 205 /** 206 * Constructor 207 * @param context Context used for loading resources. 208 * @param numSpeeds Number of supported fast forward speeds. 209 */ 210 public FastForwardAction(Context context, int numSpeeds) { 211 super(R.id.lb_control_fast_forward); 212 213 if (numSpeeds < 1) { 214 throw new IllegalArgumentException("numSpeeds must be > 0"); 215 } 216 Drawable[] drawables = new Drawable[numSpeeds]; 217 drawables[0] = getStyledDrawable(context, 218 R.styleable.lbPlaybackControlsActionIcons_fast_forward); 219 setDrawables(drawables); 220 221 String[] labels = new String[getActionCount()]; 222 labels[0] = context.getString(R.string.lb_playback_controls_fast_forward); 223 224 String[] labels2 = new String[getActionCount()]; 225 labels2[0] = labels[0]; 226 227 for (int i = 1; i < numSpeeds; i++) { 228 int multiplier = i + 1; 229 labels[i] = context.getResources().getString( 230 R.string.lb_control_display_fast_forward_multiplier, multiplier); 231 labels2[i] = context.getResources().getString( 232 R.string.lb_playback_controls_fast_forward_multiplier, multiplier); 233 } 234 setLabels(labels); 235 setSecondaryLabels(labels2); 236 addKeyCode(KeyEvent.KEYCODE_MEDIA_FAST_FORWARD); 237 } 238 } 239 240 /** 241 * An action displaying an icon for rewind. 242 */ 243 public static class RewindAction extends MultiAction { 244 /** 245 * Constructor 246 * @param context Context used for loading resources. 247 */ 248 public RewindAction(Context context) { 249 this(context, 1); 250 } 251 252 /** 253 * Constructor 254 * @param context Context used for loading resources. 255 * @param numSpeeds Number of supported fast forward speeds. 256 */ 257 public RewindAction(Context context, int numSpeeds) { 258 super(R.id.lb_control_fast_rewind); 259 260 if (numSpeeds < 1) { 261 throw new IllegalArgumentException("numSpeeds must be > 0"); 262 } 263 Drawable[] drawables = new Drawable[numSpeeds]; 264 drawables[0] = getStyledDrawable(context, 265 R.styleable.lbPlaybackControlsActionIcons_rewind); 266 setDrawables(drawables); 267 268 String[] labels = new String[getActionCount()]; 269 labels[0] = context.getString(R.string.lb_playback_controls_rewind); 270 271 String[] labels2 = new String[getActionCount()]; 272 labels2[0] = labels[0]; 273 274 for (int i = 1; i < numSpeeds; i++) { 275 int multiplier = i + 1; 276 labels[i] = labels[i] = context.getResources().getString( 277 R.string.lb_control_display_rewind_multiplier, multiplier); 278 labels2[i] = context.getResources().getString( 279 R.string.lb_playback_controls_rewind_multiplier, multiplier); 280 } 281 setLabels(labels); 282 setSecondaryLabels(labels2); 283 addKeyCode(KeyEvent.KEYCODE_MEDIA_REWIND); 284 } 285 } 286 287 /** 288 * An action displaying an icon for skip next. 289 */ 290 public static class SkipNextAction extends Action { 291 /** 292 * Constructor 293 * @param context Context used for loading resources. 294 */ 295 public SkipNextAction(Context context) { 296 super(R.id.lb_control_skip_next); 297 setIcon(getStyledDrawable(context, 298 R.styleable.lbPlaybackControlsActionIcons_skip_next)); 299 setLabel1(context.getString(R.string.lb_playback_controls_skip_next)); 300 addKeyCode(KeyEvent.KEYCODE_MEDIA_NEXT); 301 } 302 } 303 304 /** 305 * An action displaying an icon for skip previous. 306 */ 307 public static class SkipPreviousAction extends Action { 308 /** 309 * Constructor 310 * @param context Context used for loading resources. 311 */ 312 public SkipPreviousAction(Context context) { 313 super(R.id.lb_control_skip_previous); 314 setIcon(getStyledDrawable(context, 315 R.styleable.lbPlaybackControlsActionIcons_skip_previous)); 316 setLabel1(context.getString(R.string.lb_playback_controls_skip_previous)); 317 addKeyCode(KeyEvent.KEYCODE_MEDIA_PREVIOUS); 318 } 319 } 320 321 /** 322 * An action displaying an icon for "more actions". 323 */ 324 public static class MoreActions extends Action { 325 /** 326 * Constructor 327 * @param context Context used for loading resources. 328 */ 329 public MoreActions(Context context) { 330 super(R.id.lb_control_more_actions); 331 setIcon(context.getResources().getDrawable(R.drawable.lb_ic_more)); 332 setLabel1(context.getString(R.string.lb_playback_controls_more_actions)); 333 } 334 } 335 336 /** 337 * A base class for displaying a thumbs action. 338 */ 339 public static abstract class ThumbsAction extends MultiAction { 340 /** 341 * Action index for the solid thumb icon. 342 */ 343 public static int SOLID = 0; 344 345 /** 346 * Action index for the outline thumb icon. 347 */ 348 public static int OUTLINE = 1; 349 350 /** 351 * Constructor 352 * @param context Context used for loading resources. 353 */ 354 public ThumbsAction(int id, Context context, int solidIconIndex, int outlineIconIndex) { 355 super(id); 356 Drawable[] drawables = new Drawable[2]; 357 drawables[SOLID] = getStyledDrawable(context, solidIconIndex); 358 drawables[OUTLINE] = getStyledDrawable(context, outlineIconIndex); 359 setDrawables(drawables); 360 } 361 } 362 363 /** 364 * An action displaying an icon for thumbs up. 365 */ 366 public static class ThumbsUpAction extends ThumbsAction { 367 public ThumbsUpAction(Context context) { 368 super(R.id.lb_control_thumbs_up, context, 369 R.styleable.lbPlaybackControlsActionIcons_thumb_up, 370 R.styleable.lbPlaybackControlsActionIcons_thumb_up_outline); 371 String[] labels = new String[getActionCount()]; 372 labels[SOLID] = context.getString(R.string.lb_playback_controls_thumb_up); 373 labels[OUTLINE] = context.getString(R.string.lb_playback_controls_thumb_up_outline); 374 setLabels(labels); 375 } 376 } 377 378 /** 379 * An action displaying an icon for thumbs down. 380 */ 381 public static class ThumbsDownAction extends ThumbsAction { 382 public ThumbsDownAction(Context context) { 383 super(R.id.lb_control_thumbs_down, context, 384 R.styleable.lbPlaybackControlsActionIcons_thumb_down, 385 R.styleable.lbPlaybackControlsActionIcons_thumb_down_outline); 386 String[] labels = new String[getActionCount()]; 387 labels[SOLID] = context.getString(R.string.lb_playback_controls_thumb_down); 388 labels[OUTLINE] = context.getString(R.string.lb_playback_controls_thumb_down_outline); 389 setLabels(labels); 390 } 391 } 392 393 /** 394 * An action for displaying three repeat states: none, one, or all. 395 */ 396 public static class RepeatAction extends MultiAction { 397 /** 398 * Action index for the repeat-none icon. 399 */ 400 public static int NONE = 0; 401 402 /** 403 * Action index for the repeat-all icon. 404 */ 405 public static int ALL = 1; 406 407 /** 408 * Action index for the repeat-one icon. 409 */ 410 public static int ONE = 2; 411 412 /** 413 * Constructor 414 * @param context Context used for loading resources. 415 */ 416 public RepeatAction(Context context) { 417 this(context, getColorFromTheme(context, 418 R.attr.playbackControlsIconHighlightColor)); 419 } 420 421 /** 422 * Constructor 423 * @param context Context used for loading resources 424 * @param highlightColor Color to display the repeat-all and repeat0one icons. 425 */ 426 public RepeatAction(Context context, int highlightColor) { 427 this(context, highlightColor, highlightColor); 428 } 429 430 /** 431 * Constructor 432 * @param context Context used for loading resources 433 * @param repeatAllColor Color to display the repeat-all icon. 434 * @param repeatOneColor Color to display the repeat-one icon. 435 */ 436 public RepeatAction(Context context, int repeatAllColor, int repeatOneColor) { 437 super(R.id.lb_control_repeat); 438 Drawable[] drawables = new Drawable[3]; 439 BitmapDrawable repeatDrawable = (BitmapDrawable) getStyledDrawable(context, 440 R.styleable.lbPlaybackControlsActionIcons_repeat); 441 BitmapDrawable repeatOneDrawable = (BitmapDrawable) getStyledDrawable(context, 442 R.styleable.lbPlaybackControlsActionIcons_repeat_one); 443 drawables[NONE] = repeatDrawable; 444 drawables[ALL] = new BitmapDrawable(context.getResources(), 445 createBitmap(repeatDrawable.getBitmap(), repeatAllColor)); 446 drawables[ONE] = new BitmapDrawable(context.getResources(), 447 createBitmap(repeatOneDrawable.getBitmap(), repeatOneColor)); 448 setDrawables(drawables); 449 450 String[] labels = new String[drawables.length]; 451 // Note, labels denote the action taken when clicked 452 labels[NONE] = context.getString(R.string.lb_playback_controls_repeat_all); 453 labels[ALL] = context.getString(R.string.lb_playback_controls_repeat_one); 454 labels[ONE] = context.getString(R.string.lb_playback_controls_repeat_none); 455 setLabels(labels); 456 } 457 } 458 459 /** 460 * An action for displaying a shuffle icon. 461 */ 462 public static class ShuffleAction extends MultiAction { 463 public static int OFF = 0; 464 public static int ON = 1; 465 466 /** 467 * Constructor 468 * @param context Context used for loading resources. 469 */ 470 public ShuffleAction(Context context) { 471 this(context, getColorFromTheme(context, 472 R.attr.playbackControlsIconHighlightColor)); 473 } 474 475 /** 476 * Constructor 477 * @param context Context used for loading resources. 478 * @param highlightColor Color for the highlighted icon state. 479 */ 480 public ShuffleAction(Context context, int highlightColor) { 481 super(R.id.lb_control_shuffle); 482 BitmapDrawable uncoloredDrawable = (BitmapDrawable) getStyledDrawable(context, 483 R.styleable.lbPlaybackControlsActionIcons_shuffle); 484 Drawable[] drawables = new Drawable[2]; 485 drawables[OFF] = uncoloredDrawable; 486 drawables[ON] = new BitmapDrawable(context.getResources(), 487 createBitmap(uncoloredDrawable.getBitmap(), highlightColor)); 488 setDrawables(drawables); 489 490 String[] labels = new String[drawables.length]; 491 labels[OFF] = context.getString(R.string.lb_playback_controls_shuffle_enable); 492 labels[ON] = context.getString(R.string.lb_playback_controls_shuffle_disable); 493 setLabels(labels); 494 } 495 } 496 497 /** 498 * An action for displaying a HQ (High Quality) icon. 499 */ 500 public static class HighQualityAction extends MultiAction { 501 public static int OFF = 0; 502 public static int ON = 1; 503 504 /** 505 * Constructor 506 * @param context Context used for loading resources. 507 */ 508 public HighQualityAction(Context context) { 509 this(context, getColorFromTheme(context, 510 R.attr.playbackControlsIconHighlightColor)); 511 } 512 513 /** 514 * Constructor 515 * @param context Context used for loading resources. 516 * @param highlightColor Color for the highlighted icon state. 517 */ 518 public HighQualityAction(Context context, int highlightColor) { 519 super(R.id.lb_control_high_quality); 520 BitmapDrawable uncoloredDrawable = (BitmapDrawable) getStyledDrawable(context, 521 R.styleable.lbPlaybackControlsActionIcons_high_quality); 522 Drawable[] drawables = new Drawable[2]; 523 drawables[OFF] = uncoloredDrawable; 524 drawables[ON] = new BitmapDrawable(context.getResources(), 525 createBitmap(uncoloredDrawable.getBitmap(), highlightColor)); 526 setDrawables(drawables); 527 528 String[] labels = new String[drawables.length]; 529 labels[OFF] = context.getString(R.string.lb_playback_controls_high_quality_enable); 530 labels[ON] = context.getString(R.string.lb_playback_controls_high_quality_disable); 531 setLabels(labels); 532 } 533 } 534 535 /** 536 * An action for displaying a CC (Closed Captioning) icon. 537 */ 538 public static class ClosedCaptioningAction extends MultiAction { 539 public static int OFF = 0; 540 public static int ON = 1; 541 542 /** 543 * Constructor 544 * @param context Context used for loading resources. 545 */ 546 public ClosedCaptioningAction(Context context) { 547 this(context, getColorFromTheme(context, 548 R.attr.playbackControlsIconHighlightColor)); 549 } 550 551 /** 552 * Constructor 553 * @param context Context used for loading resources. 554 * @param highlightColor Color for the highlighted icon state. 555 */ 556 public ClosedCaptioningAction(Context context, int highlightColor) { 557 super(R.id.lb_control_high_quality); 558 BitmapDrawable uncoloredDrawable = (BitmapDrawable) getStyledDrawable(context, 559 R.styleable.lbPlaybackControlsActionIcons_closed_captioning); 560 Drawable[] drawables = new Drawable[2]; 561 drawables[OFF] = uncoloredDrawable; 562 drawables[ON] = new BitmapDrawable(context.getResources(), 563 createBitmap(uncoloredDrawable.getBitmap(), highlightColor)); 564 setDrawables(drawables); 565 566 String[] labels = new String[drawables.length]; 567 labels[OFF] = context.getString(R.string.lb_playback_controls_closed_captioning_enable); 568 labels[ON] = context.getString(R.string.lb_playback_controls_closed_captioning_disable); 569 setLabels(labels); 570 } 571 } 572 573 private static Bitmap createBitmap(Bitmap bitmap, int color) { 574 Bitmap dst = bitmap.copy(bitmap.getConfig(), true); 575 Canvas canvas = new Canvas(dst); 576 Paint paint = new Paint(); 577 paint.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_ATOP)); 578 canvas.drawBitmap(bitmap, 0, 0, paint); 579 return dst; 580 } 581 582 private static int getColorFromTheme(Context context, int attributeResId) { 583 TypedValue outValue = new TypedValue(); 584 context.getTheme().resolveAttribute(attributeResId, outValue, true); 585 return outValue.data; 586 } 587 588 private static Drawable getStyledDrawable(Context context, int index) { 589 TypedValue outValue = new TypedValue(); 590 context.getTheme().resolveAttribute( 591 R.attr.playbackControlsActionIcons, outValue, false); 592 TypedArray array = context.getTheme().obtainStyledAttributes(outValue.data, 593 R.styleable.lbPlaybackControlsActionIcons); 594 Drawable drawable = array.getDrawable(index); 595 array.recycle(); 596 return drawable; 597 } 598 599 private Object mItem; 600 private Drawable mImageDrawable; 601 private ObjectAdapter mPrimaryActionsAdapter; 602 private ObjectAdapter mSecondaryActionsAdapter; 603 private int mTotalTimeMs; 604 private int mCurrentTimeMs; 605 private int mBufferedProgressMs; 606 private OnPlaybackStateChangedListener mListener; 607 608 /** 609 * Constructor for a PlaybackControlsRow that displays some details from 610 * the given item. 611 * 612 * @param item The main item for the row. 613 */ 614 public PlaybackControlsRow(Object item) { 615 mItem = item; 616 } 617 618 /** 619 * Constructor for a PlaybackControlsRow that has no item details. 620 */ 621 public PlaybackControlsRow() { 622 } 623 624 /** 625 * Gets the main item for the details page. 626 */ 627 public final Object getItem() { 628 return mItem; 629 } 630 631 /** 632 * Sets a {link @Drawable} image for this row. 633 * 634 * @param drawable The drawable to set. 635 */ 636 public final void setImageDrawable(Drawable drawable) { 637 mImageDrawable = drawable; 638 } 639 640 /** 641 * Sets a {@link Bitmap} for this row. 642 * 643 * @param context The context to retrieve display metrics from. 644 * @param bm The bitmap to set. 645 */ 646 public final void setImageBitmap(Context context, Bitmap bm) { 647 mImageDrawable = new BitmapDrawable(context.getResources(), bm); 648 } 649 650 /** 651 * Gets the image {@link Drawable} of this row. 652 * 653 * @return The overview's image drawable, or null if no drawable has been 654 * assigned. 655 */ 656 public final Drawable getImageDrawable() { 657 return mImageDrawable; 658 } 659 660 /** 661 * Sets the primary actions {@link ObjectAdapter}. 662 */ 663 public final void setPrimaryActionsAdapter(ObjectAdapter adapter) { 664 mPrimaryActionsAdapter = adapter; 665 } 666 667 /** 668 * Sets the secondary actions {@link ObjectAdapter}. 669 */ 670 public final void setSecondaryActionsAdapter(ObjectAdapter adapter) { 671 mSecondaryActionsAdapter = adapter; 672 } 673 674 /** 675 * Returns the primary actions {@link ObjectAdapter}. 676 */ 677 public final ObjectAdapter getPrimaryActionsAdapter() { 678 return mPrimaryActionsAdapter; 679 } 680 681 /** 682 * Returns the secondary actions {@link ObjectAdapter}. 683 */ 684 public final ObjectAdapter getSecondaryActionsAdapter() { 685 return mSecondaryActionsAdapter; 686 } 687 688 /** 689 * Sets the total time in milliseconds for the playback controls row. 690 */ 691 public void setTotalTime(int ms) { 692 mTotalTimeMs = ms; 693 } 694 695 /** 696 * Returns the total time in milliseconds for the playback controls row. 697 */ 698 public int getTotalTime() { 699 return mTotalTimeMs; 700 } 701 702 /** 703 * Sets the current time in milliseconds for the playback controls row. 704 * If this row is bound to a view, the view will automatically 705 * be updated to reflect the new value. 706 */ 707 public void setCurrentTime(int ms) { 708 if (mCurrentTimeMs != ms) { 709 mCurrentTimeMs = ms; 710 currentTimeChanged(); 711 } 712 } 713 714 /** 715 * Returns the current time in milliseconds for the playback controls row. 716 */ 717 public int getCurrentTime() { 718 return mCurrentTimeMs; 719 } 720 721 /** 722 * Sets the buffered progress for the playback controls row. 723 * If this row is bound to a view, the view will automatically 724 * be updated to reflect the new value. 725 */ 726 public void setBufferedProgress(int ms) { 727 if (mBufferedProgressMs != ms) { 728 mBufferedProgressMs = ms; 729 bufferedProgressChanged(); 730 } 731 } 732 733 /** 734 * Returns the buffered progress for the playback controls row. 735 */ 736 public int getBufferedProgress() { 737 return mBufferedProgressMs; 738 } 739 740 /** 741 * Returns the Action associated with the given keycode, or null if no associated action exists. 742 * Searches the primary adapter first, then the secondary adapter. 743 */ 744 public Action getActionForKeyCode(int keyCode) { 745 Action action = getActionForKeyCode(getPrimaryActionsAdapter(), keyCode); 746 if (action != null) { 747 return action; 748 } 749 return getActionForKeyCode(getSecondaryActionsAdapter(), keyCode); 750 } 751 752 /** 753 * Returns the Action associated with the given keycode, or null if no associated action exists. 754 */ 755 public Action getActionForKeyCode(ObjectAdapter adapter, int keyCode) { 756 if (adapter != mPrimaryActionsAdapter && adapter != mSecondaryActionsAdapter) { 757 throw new IllegalArgumentException("Invalid adapter"); 758 } 759 for (int i = 0; i < adapter.size(); i++) { 760 Action action = (Action) adapter.get(i); 761 if (action.respondsToKeyCode(keyCode)) { 762 return action; 763 } 764 } 765 return null; 766 } 767 768 interface OnPlaybackStateChangedListener { 769 public void onCurrentTimeChanged(int currentTimeMs); 770 public void onBufferedProgressChanged(int bufferedProgressMs); 771 } 772 773 /** 774 * Sets a listener to be called when the playback state changes. 775 */ 776 void setOnPlaybackStateChangedListener(OnPlaybackStateChangedListener listener) { 777 mListener = listener; 778 } 779 780 /** 781 * Returns the playback state listener. 782 */ 783 OnPlaybackStateChangedListener getOnPlaybackStateChangedListener() { 784 return mListener; 785 } 786 787 private void currentTimeChanged() { 788 if (mListener != null) { 789 mListener.onCurrentTimeChanged(mCurrentTimeMs); 790 } 791 } 792 793 private void bufferedProgressChanged() { 794 if (mListener != null) { 795 mListener.onBufferedProgressChanged(mBufferedProgressMs); 796 } 797 } 798} 799