PlaybackControlsRow.java revision 46443cb5b092f1d9156342645088eead9da026f6
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, getIconHighlightColor(context)); 418 } 419 420 /** 421 * Constructor 422 * @param context Context used for loading resources 423 * @param highlightColor Color to display the repeat-all and repeat0one icons. 424 */ 425 public RepeatAction(Context context, int highlightColor) { 426 this(context, highlightColor, highlightColor); 427 } 428 429 /** 430 * Constructor 431 * @param context Context used for loading resources 432 * @param repeatAllColor Color to display the repeat-all icon. 433 * @param repeatOneColor Color to display the repeat-one icon. 434 */ 435 public RepeatAction(Context context, int repeatAllColor, int repeatOneColor) { 436 super(R.id.lb_control_repeat); 437 Drawable[] drawables = new Drawable[3]; 438 BitmapDrawable repeatDrawable = (BitmapDrawable) getStyledDrawable(context, 439 R.styleable.lbPlaybackControlsActionIcons_repeat); 440 BitmapDrawable repeatOneDrawable = (BitmapDrawable) getStyledDrawable(context, 441 R.styleable.lbPlaybackControlsActionIcons_repeat_one); 442 drawables[NONE] = repeatDrawable; 443 drawables[ALL] = repeatDrawable == null ? null 444 : new BitmapDrawable(context.getResources(), 445 createBitmap(repeatDrawable.getBitmap(), repeatAllColor)); 446 drawables[ONE] = repeatOneDrawable == null ? null 447 : new BitmapDrawable(context.getResources(), 448 createBitmap(repeatOneDrawable.getBitmap(), repeatOneColor)); 449 setDrawables(drawables); 450 451 String[] labels = new String[drawables.length]; 452 // Note, labels denote the action taken when clicked 453 labels[NONE] = context.getString(R.string.lb_playback_controls_repeat_all); 454 labels[ALL] = context.getString(R.string.lb_playback_controls_repeat_one); 455 labels[ONE] = context.getString(R.string.lb_playback_controls_repeat_none); 456 setLabels(labels); 457 } 458 } 459 460 /** 461 * An action for displaying a shuffle icon. 462 */ 463 public static class ShuffleAction extends MultiAction { 464 public static int OFF = 0; 465 public static int ON = 1; 466 467 /** 468 * Constructor 469 * @param context Context used for loading resources. 470 */ 471 public ShuffleAction(Context context) { 472 this(context, getIconHighlightColor(context)); 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, getIconHighlightColor(context)); 510 } 511 512 /** 513 * Constructor 514 * @param context Context used for loading resources. 515 * @param highlightColor Color for the highlighted icon state. 516 */ 517 public HighQualityAction(Context context, int highlightColor) { 518 super(R.id.lb_control_high_quality); 519 BitmapDrawable uncoloredDrawable = (BitmapDrawable) getStyledDrawable(context, 520 R.styleable.lbPlaybackControlsActionIcons_high_quality); 521 Drawable[] drawables = new Drawable[2]; 522 drawables[OFF] = uncoloredDrawable; 523 drawables[ON] = new BitmapDrawable(context.getResources(), 524 createBitmap(uncoloredDrawable.getBitmap(), highlightColor)); 525 setDrawables(drawables); 526 527 String[] labels = new String[drawables.length]; 528 labels[OFF] = context.getString(R.string.lb_playback_controls_high_quality_enable); 529 labels[ON] = context.getString(R.string.lb_playback_controls_high_quality_disable); 530 setLabels(labels); 531 } 532 } 533 534 /** 535 * An action for displaying a CC (Closed Captioning) icon. 536 */ 537 public static class ClosedCaptioningAction extends MultiAction { 538 public static int OFF = 0; 539 public static int ON = 1; 540 541 /** 542 * Constructor 543 * @param context Context used for loading resources. 544 */ 545 public ClosedCaptioningAction(Context context) { 546 this(context, getIconHighlightColor(context)); 547 } 548 549 /** 550 * Constructor 551 * @param context Context used for loading resources. 552 * @param highlightColor Color for the highlighted icon state. 553 */ 554 public ClosedCaptioningAction(Context context, int highlightColor) { 555 super(R.id.lb_control_high_quality); 556 BitmapDrawable uncoloredDrawable = (BitmapDrawable) getStyledDrawable(context, 557 R.styleable.lbPlaybackControlsActionIcons_closed_captioning); 558 Drawable[] drawables = new Drawable[2]; 559 drawables[OFF] = uncoloredDrawable; 560 drawables[ON] = new BitmapDrawable(context.getResources(), 561 createBitmap(uncoloredDrawable.getBitmap(), highlightColor)); 562 setDrawables(drawables); 563 564 String[] labels = new String[drawables.length]; 565 labels[OFF] = context.getString(R.string.lb_playback_controls_closed_captioning_enable); 566 labels[ON] = context.getString(R.string.lb_playback_controls_closed_captioning_disable); 567 setLabels(labels); 568 } 569 } 570 571 private static Bitmap createBitmap(Bitmap bitmap, int color) { 572 Bitmap dst = bitmap.copy(bitmap.getConfig(), true); 573 Canvas canvas = new Canvas(dst); 574 Paint paint = new Paint(); 575 paint.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_ATOP)); 576 canvas.drawBitmap(bitmap, 0, 0, paint); 577 return dst; 578 } 579 580 private static int getIconHighlightColor(Context context) { 581 TypedValue outValue = new TypedValue(); 582 if (context.getTheme().resolveAttribute(R.attr.playbackControlsIconHighlightColor, 583 outValue, true)) { 584 return outValue.data; 585 } 586 return context.getResources().getColor(R.color.lb_playback_icon_highlight_no_theme); 587 } 588 589 private static Drawable getStyledDrawable(Context context, int index) { 590 TypedValue outValue = new TypedValue(); 591 if (!context.getTheme().resolveAttribute( 592 R.attr.playbackControlsActionIcons, outValue, false)) { 593 return null; 594 } 595 TypedArray array = context.getTheme().obtainStyledAttributes(outValue.data, 596 R.styleable.lbPlaybackControlsActionIcons); 597 Drawable drawable = array.getDrawable(index); 598 array.recycle(); 599 return drawable; 600 } 601 602 private Object mItem; 603 private Drawable mImageDrawable; 604 private ObjectAdapter mPrimaryActionsAdapter; 605 private ObjectAdapter mSecondaryActionsAdapter; 606 private int mTotalTimeMs; 607 private int mCurrentTimeMs; 608 private int mBufferedProgressMs; 609 private OnPlaybackStateChangedListener mListener; 610 611 /** 612 * Constructor for a PlaybackControlsRow that displays some details from 613 * the given item. 614 * 615 * @param item The main item for the row. 616 */ 617 public PlaybackControlsRow(Object item) { 618 mItem = item; 619 } 620 621 /** 622 * Constructor for a PlaybackControlsRow that has no item details. 623 */ 624 public PlaybackControlsRow() { 625 } 626 627 /** 628 * Gets the main item for the details page. 629 */ 630 public final Object getItem() { 631 return mItem; 632 } 633 634 /** 635 * Sets a {link @Drawable} image for this row. 636 * 637 * @param drawable The drawable to set. 638 */ 639 public final void setImageDrawable(Drawable drawable) { 640 mImageDrawable = drawable; 641 } 642 643 /** 644 * Sets a {@link Bitmap} for this row. 645 * 646 * @param context The context to retrieve display metrics from. 647 * @param bm The bitmap to set. 648 */ 649 public final void setImageBitmap(Context context, Bitmap bm) { 650 mImageDrawable = new BitmapDrawable(context.getResources(), bm); 651 } 652 653 /** 654 * Gets the image {@link Drawable} of this row. 655 * 656 * @return The overview's image drawable, or null if no drawable has been 657 * assigned. 658 */ 659 public final Drawable getImageDrawable() { 660 return mImageDrawable; 661 } 662 663 /** 664 * Sets the primary actions {@link ObjectAdapter}. 665 */ 666 public final void setPrimaryActionsAdapter(ObjectAdapter adapter) { 667 mPrimaryActionsAdapter = adapter; 668 } 669 670 /** 671 * Sets the secondary actions {@link ObjectAdapter}. 672 */ 673 public final void setSecondaryActionsAdapter(ObjectAdapter adapter) { 674 mSecondaryActionsAdapter = adapter; 675 } 676 677 /** 678 * Returns the primary actions {@link ObjectAdapter}. 679 */ 680 public final ObjectAdapter getPrimaryActionsAdapter() { 681 return mPrimaryActionsAdapter; 682 } 683 684 /** 685 * Returns the secondary actions {@link ObjectAdapter}. 686 */ 687 public final ObjectAdapter getSecondaryActionsAdapter() { 688 return mSecondaryActionsAdapter; 689 } 690 691 /** 692 * Sets the total time in milliseconds for the playback controls row. 693 */ 694 public void setTotalTime(int ms) { 695 mTotalTimeMs = ms; 696 } 697 698 /** 699 * Returns the total time in milliseconds for the playback controls row. 700 */ 701 public int getTotalTime() { 702 return mTotalTimeMs; 703 } 704 705 /** 706 * Sets the current time in milliseconds for the playback controls row. 707 * If this row is bound to a view, the view will automatically 708 * be updated to reflect the new value. 709 */ 710 public void setCurrentTime(int ms) { 711 if (mCurrentTimeMs != ms) { 712 mCurrentTimeMs = ms; 713 currentTimeChanged(); 714 } 715 } 716 717 /** 718 * Returns the current time in milliseconds for the playback controls row. 719 */ 720 public int getCurrentTime() { 721 return mCurrentTimeMs; 722 } 723 724 /** 725 * Sets the buffered progress for the playback controls row. 726 * If this row is bound to a view, the view will automatically 727 * be updated to reflect the new value. 728 */ 729 public void setBufferedProgress(int ms) { 730 if (mBufferedProgressMs != ms) { 731 mBufferedProgressMs = ms; 732 bufferedProgressChanged(); 733 } 734 } 735 736 /** 737 * Returns the buffered progress for the playback controls row. 738 */ 739 public int getBufferedProgress() { 740 return mBufferedProgressMs; 741 } 742 743 /** 744 * Returns the Action associated with the given keycode, or null if no associated action exists. 745 * Searches the primary adapter first, then the secondary adapter. 746 */ 747 public Action getActionForKeyCode(int keyCode) { 748 Action action = getActionForKeyCode(getPrimaryActionsAdapter(), keyCode); 749 if (action != null) { 750 return action; 751 } 752 return getActionForKeyCode(getSecondaryActionsAdapter(), keyCode); 753 } 754 755 /** 756 * Returns the Action associated with the given keycode, or null if no associated action exists. 757 */ 758 public Action getActionForKeyCode(ObjectAdapter adapter, int keyCode) { 759 if (adapter != mPrimaryActionsAdapter && adapter != mSecondaryActionsAdapter) { 760 throw new IllegalArgumentException("Invalid adapter"); 761 } 762 for (int i = 0; i < adapter.size(); i++) { 763 Action action = (Action) adapter.get(i); 764 if (action.respondsToKeyCode(keyCode)) { 765 return action; 766 } 767 } 768 return null; 769 } 770 771 interface OnPlaybackStateChangedListener { 772 public void onCurrentTimeChanged(int currentTimeMs); 773 public void onBufferedProgressChanged(int bufferedProgressMs); 774 } 775 776 /** 777 * Sets a listener to be called when the playback state changes. 778 */ 779 void setOnPlaybackStateChangedListener(OnPlaybackStateChangedListener listener) { 780 mListener = listener; 781 } 782 783 /** 784 * Returns the playback state listener. 785 */ 786 OnPlaybackStateChangedListener getOnPlaybackStateChangedListener() { 787 return mListener; 788 } 789 790 private void currentTimeChanged() { 791 if (mListener != null) { 792 mListener.onCurrentTimeChanged(mCurrentTimeMs); 793 } 794 } 795 796 private void bufferedProgressChanged() { 797 if (mListener != null) { 798 mListener.onBufferedProgressChanged(mBufferedProgressMs); 799 } 800 } 801} 802