o Removes mParcel from TimedText class. o Converts native parcel into java parcel object directly without copying to an intermediate byte array. o JNIMediaPlayerListener::notify checks for Java exceptions, logs them, and clears the exception state. related-to-bug: 6405934 Change-Id: I8b82d3cd5b9b3ef8cad27e805202a0e445a88a45
735 lines
24 KiB
Java
735 lines
24 KiB
Java
/*
|
|
* Copyright (C) 2011 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package android.media;
|
|
|
|
import android.graphics.Rect;
|
|
import android.os.Parcel;
|
|
import android.util.Log;
|
|
import java.util.HashMap;
|
|
import java.util.Set;
|
|
import java.util.List;
|
|
import java.util.ArrayList;
|
|
|
|
/**
|
|
* Class to hold the timed text's metadata, including:
|
|
* <ul>
|
|
* <li> The characters for rendering</li>
|
|
* <li> The rendering position for the timed text</li>
|
|
* </ul>
|
|
*
|
|
* <p> To render the timed text, applications need to do the following:
|
|
*
|
|
* <ul>
|
|
* <li> Implement the {@link MediaPlayer.OnTimedTextListener} interface</li>
|
|
* <li> Register the {@link MediaPlayer.OnTimedTextListener} callback on a MediaPlayer object that is used for playback</li>
|
|
* <li> When a onTimedText callback is received, do the following:
|
|
* <ul>
|
|
* <li> call {@link #getText} to get the characters for rendering</li>
|
|
* <li> call {@link #getBounds} to get the text rendering area/region</li>
|
|
* </ul>
|
|
* </li>
|
|
* </ul>
|
|
*
|
|
* @see android.media.MediaPlayer
|
|
*/
|
|
public final class TimedText
|
|
{
|
|
private static final int FIRST_PUBLIC_KEY = 1;
|
|
|
|
// These keys must be in sync with the keys in TextDescription.h
|
|
private static final int KEY_DISPLAY_FLAGS = 1; // int
|
|
private static final int KEY_STYLE_FLAGS = 2; // int
|
|
private static final int KEY_BACKGROUND_COLOR_RGBA = 3; // int
|
|
private static final int KEY_HIGHLIGHT_COLOR_RGBA = 4; // int
|
|
private static final int KEY_SCROLL_DELAY = 5; // int
|
|
private static final int KEY_WRAP_TEXT = 6; // int
|
|
private static final int KEY_START_TIME = 7; // int
|
|
private static final int KEY_STRUCT_BLINKING_TEXT_LIST = 8; // List<CharPos>
|
|
private static final int KEY_STRUCT_FONT_LIST = 9; // List<Font>
|
|
private static final int KEY_STRUCT_HIGHLIGHT_LIST = 10; // List<CharPos>
|
|
private static final int KEY_STRUCT_HYPER_TEXT_LIST = 11; // List<HyperText>
|
|
private static final int KEY_STRUCT_KARAOKE_LIST = 12; // List<Karaoke>
|
|
private static final int KEY_STRUCT_STYLE_LIST = 13; // List<Style>
|
|
private static final int KEY_STRUCT_TEXT_POS = 14; // TextPos
|
|
private static final int KEY_STRUCT_JUSTIFICATION = 15; // Justification
|
|
private static final int KEY_STRUCT_TEXT = 16; // Text
|
|
|
|
private static final int LAST_PUBLIC_KEY = 16;
|
|
|
|
private static final int FIRST_PRIVATE_KEY = 101;
|
|
|
|
// The following keys are used between TimedText.java and
|
|
// TextDescription.cpp in order to parce the Parcel.
|
|
private static final int KEY_GLOBAL_SETTING = 101;
|
|
private static final int KEY_LOCAL_SETTING = 102;
|
|
private static final int KEY_START_CHAR = 103;
|
|
private static final int KEY_END_CHAR = 104;
|
|
private static final int KEY_FONT_ID = 105;
|
|
private static final int KEY_FONT_SIZE = 106;
|
|
private static final int KEY_TEXT_COLOR_RGBA = 107;
|
|
|
|
private static final int LAST_PRIVATE_KEY = 107;
|
|
|
|
private static final String TAG = "TimedText";
|
|
|
|
private final HashMap<Integer, Object> mKeyObjectMap =
|
|
new HashMap<Integer, Object>();
|
|
|
|
private int mDisplayFlags = -1;
|
|
private int mBackgroundColorRGBA = -1;
|
|
private int mHighlightColorRGBA = -1;
|
|
private int mScrollDelay = -1;
|
|
private int mWrapText = -1;
|
|
|
|
private List<CharPos> mBlinkingPosList = null;
|
|
private List<CharPos> mHighlightPosList = null;
|
|
private List<Karaoke> mKaraokeList = null;
|
|
private List<Font> mFontList = null;
|
|
private List<Style> mStyleList = null;
|
|
private List<HyperText> mHyperTextList = null;
|
|
|
|
private Rect mTextBounds = null;
|
|
private String mTextChars = null;
|
|
|
|
private Justification mJustification;
|
|
|
|
/**
|
|
* Helper class to hold the start char offset and end char offset
|
|
* for Blinking Text or Highlight Text. endChar is the end offset
|
|
* of the text (startChar + number of characters to be highlighted
|
|
* or blinked). The member variables in this class are read-only.
|
|
* {@hide}
|
|
*/
|
|
public static final class CharPos {
|
|
/**
|
|
* The offset of the start character
|
|
*/
|
|
public final int startChar;
|
|
|
|
/**
|
|
* The offset of the end character
|
|
*/
|
|
public final int endChar;
|
|
|
|
/**
|
|
* Constuctor
|
|
* @param startChar the offset of the start character.
|
|
* @param endChar the offset of the end character.
|
|
*/
|
|
public CharPos(int startChar, int endChar) {
|
|
this.startChar = startChar;
|
|
this.endChar = endChar;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Helper class to hold the justification for text display in the text box.
|
|
* The member variables in this class are read-only.
|
|
* {@hide}
|
|
*/
|
|
public static final class Justification {
|
|
/**
|
|
* horizontal justification 0: left, 1: centered, -1: right
|
|
*/
|
|
public final int horizontalJustification;
|
|
|
|
/**
|
|
* vertical justification 0: top, 1: centered, -1: bottom
|
|
*/
|
|
public final int verticalJustification;
|
|
|
|
/**
|
|
* Constructor
|
|
* @param horizontal the horizontal justification of the text.
|
|
* @param vertical the vertical justification of the text.
|
|
*/
|
|
public Justification(int horizontal, int vertical) {
|
|
this.horizontalJustification = horizontal;
|
|
this.verticalJustification = vertical;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Helper class to hold the style information to display the text.
|
|
* The member variables in this class are read-only.
|
|
* {@hide}
|
|
*/
|
|
public static final class Style {
|
|
/**
|
|
* The offset of the start character which applys this style
|
|
*/
|
|
public final int startChar;
|
|
|
|
/**
|
|
* The offset of the end character which applys this style
|
|
*/
|
|
public final int endChar;
|
|
|
|
/**
|
|
* ID of the font. This ID will be used to choose the font
|
|
* to be used from the font list.
|
|
*/
|
|
public final int fontID;
|
|
|
|
/**
|
|
* True if the characters should be bold
|
|
*/
|
|
public final boolean isBold;
|
|
|
|
/**
|
|
* True if the characters should be italic
|
|
*/
|
|
public final boolean isItalic;
|
|
|
|
/**
|
|
* True if the characters should be underlined
|
|
*/
|
|
public final boolean isUnderlined;
|
|
|
|
/**
|
|
* The size of the font
|
|
*/
|
|
public final int fontSize;
|
|
|
|
/**
|
|
* To specify the RGBA color: 8 bits each of red, green, blue,
|
|
* and an alpha(transparency) value
|
|
*/
|
|
public final int colorRGBA;
|
|
|
|
/**
|
|
* Constructor
|
|
* @param startChar the offset of the start character which applys this style
|
|
* @param endChar the offset of the end character which applys this style
|
|
* @param fontId the ID of the font.
|
|
* @param isBold whether the characters should be bold.
|
|
* @param isItalic whether the characters should be italic.
|
|
* @param isUnderlined whether the characters should be underlined.
|
|
* @param fontSize the size of the font.
|
|
* @param colorRGBA red, green, blue, and alpha value for color.
|
|
*/
|
|
public Style(int startChar, int endChar, int fontId,
|
|
boolean isBold, boolean isItalic, boolean isUnderlined,
|
|
int fontSize, int colorRGBA) {
|
|
this.startChar = startChar;
|
|
this.endChar = endChar;
|
|
this.fontID = fontId;
|
|
this.isBold = isBold;
|
|
this.isItalic = isItalic;
|
|
this.isUnderlined = isUnderlined;
|
|
this.fontSize = fontSize;
|
|
this.colorRGBA = colorRGBA;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Helper class to hold the font ID and name.
|
|
* The member variables in this class are read-only.
|
|
* {@hide}
|
|
*/
|
|
public static final class Font {
|
|
/**
|
|
* The font ID
|
|
*/
|
|
public final int ID;
|
|
|
|
/**
|
|
* The font name
|
|
*/
|
|
public final String name;
|
|
|
|
/**
|
|
* Constructor
|
|
* @param id the font ID.
|
|
* @param name the font name.
|
|
*/
|
|
public Font(int id, String name) {
|
|
this.ID = id;
|
|
this.name = name;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Helper class to hold the karaoke information.
|
|
* The member variables in this class are read-only.
|
|
* {@hide}
|
|
*/
|
|
public static final class Karaoke {
|
|
/**
|
|
* The start time (in milliseconds) to highlight the characters
|
|
* specified by startChar and endChar.
|
|
*/
|
|
public final int startTimeMs;
|
|
|
|
/**
|
|
* The end time (in milliseconds) to highlight the characters
|
|
* specified by startChar and endChar.
|
|
*/
|
|
public final int endTimeMs;
|
|
|
|
/**
|
|
* The offset of the start character to be highlighted
|
|
*/
|
|
public final int startChar;
|
|
|
|
/**
|
|
* The offset of the end character to be highlighted
|
|
*/
|
|
public final int endChar;
|
|
|
|
/**
|
|
* Constructor
|
|
* @param startTimeMs the start time (in milliseconds) to highlight
|
|
* the characters between startChar and endChar.
|
|
* @param endTimeMs the end time (in milliseconds) to highlight
|
|
* the characters between startChar and endChar.
|
|
* @param startChar the offset of the start character to be highlighted.
|
|
* @param endChar the offset of the end character to be highlighted.
|
|
*/
|
|
public Karaoke(int startTimeMs, int endTimeMs, int startChar, int endChar) {
|
|
this.startTimeMs = startTimeMs;
|
|
this.endTimeMs = endTimeMs;
|
|
this.startChar = startChar;
|
|
this.endChar = endChar;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Helper class to hold the hyper text information.
|
|
* The member variables in this class are read-only.
|
|
* {@hide}
|
|
*/
|
|
public static final class HyperText {
|
|
/**
|
|
* The offset of the start character
|
|
*/
|
|
public final int startChar;
|
|
|
|
/**
|
|
* The offset of the end character
|
|
*/
|
|
public final int endChar;
|
|
|
|
/**
|
|
* The linked-to URL
|
|
*/
|
|
public final String URL;
|
|
|
|
/**
|
|
* The "alt" string for user display
|
|
*/
|
|
public final String altString;
|
|
|
|
|
|
/**
|
|
* Constructor
|
|
* @param startChar the offset of the start character.
|
|
* @param endChar the offset of the end character.
|
|
* @param url the linked-to URL.
|
|
* @param alt the "alt" string for display.
|
|
*/
|
|
public HyperText(int startChar, int endChar, String url, String alt) {
|
|
this.startChar = startChar;
|
|
this.endChar = endChar;
|
|
this.URL = url;
|
|
this.altString = alt;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param obj the byte array which contains the timed text.
|
|
* @throws IllegalArgumentExcept if parseParcel() fails.
|
|
* {@hide}
|
|
*/
|
|
public TimedText(Parcel parcel) {
|
|
if (!parseParcel(parcel)) {
|
|
mKeyObjectMap.clear();
|
|
throw new IllegalArgumentException("parseParcel() fails");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get the characters in the timed text.
|
|
*
|
|
* @return the characters as a String object in the TimedText. Applications
|
|
* should stop rendering previous timed text at the current rendering region if
|
|
* a null is returned, until the next non-null timed text is received.
|
|
*/
|
|
public String getText() {
|
|
return mTextChars;
|
|
}
|
|
|
|
/**
|
|
* Get the rectangle area or region for rendering the timed text as specified
|
|
* by a Rect object.
|
|
*
|
|
* @return the rectangle region to render the characters in the timed text.
|
|
* If no bounds information is available (a null is returned), render the
|
|
* timed text at the center bottom of the display.
|
|
*/
|
|
public Rect getBounds() {
|
|
return mTextBounds;
|
|
}
|
|
|
|
/*
|
|
* Go over all the records, collecting metadata keys and fields in the
|
|
* Parcel. These are stored in mKeyObjectMap for application to retrieve.
|
|
* @return false if an error occurred during parsing. Otherwise, true.
|
|
*/
|
|
private boolean parseParcel(Parcel parcel) {
|
|
parcel.setDataPosition(0);
|
|
if (parcel.dataAvail() == 0) {
|
|
return false;
|
|
}
|
|
|
|
int type = parcel.readInt();
|
|
if (type == KEY_LOCAL_SETTING) {
|
|
type = parcel.readInt();
|
|
if (type != KEY_START_TIME) {
|
|
return false;
|
|
}
|
|
int mStartTimeMs = parcel.readInt();
|
|
mKeyObjectMap.put(type, mStartTimeMs);
|
|
|
|
type = parcel.readInt();
|
|
if (type != KEY_STRUCT_TEXT) {
|
|
return false;
|
|
}
|
|
|
|
int textLen = parcel.readInt();
|
|
byte[] text = parcel.createByteArray();
|
|
if (text == null || text.length == 0) {
|
|
mTextChars = null;
|
|
} else {
|
|
mTextChars = new String(text);
|
|
}
|
|
|
|
} else if (type != KEY_GLOBAL_SETTING) {
|
|
Log.w(TAG, "Invalid timed text key found: " + type);
|
|
return false;
|
|
}
|
|
|
|
while (parcel.dataAvail() > 0) {
|
|
int key = parcel.readInt();
|
|
if (!isValidKey(key)) {
|
|
Log.w(TAG, "Invalid timed text key found: " + key);
|
|
return false;
|
|
}
|
|
|
|
Object object = null;
|
|
|
|
switch (key) {
|
|
case KEY_STRUCT_STYLE_LIST: {
|
|
readStyle(parcel);
|
|
object = mStyleList;
|
|
break;
|
|
}
|
|
case KEY_STRUCT_FONT_LIST: {
|
|
readFont(parcel);
|
|
object = mFontList;
|
|
break;
|
|
}
|
|
case KEY_STRUCT_HIGHLIGHT_LIST: {
|
|
readHighlight(parcel);
|
|
object = mHighlightPosList;
|
|
break;
|
|
}
|
|
case KEY_STRUCT_KARAOKE_LIST: {
|
|
readKaraoke(parcel);
|
|
object = mKaraokeList;
|
|
break;
|
|
}
|
|
case KEY_STRUCT_HYPER_TEXT_LIST: {
|
|
readHyperText(parcel);
|
|
object = mHyperTextList;
|
|
|
|
break;
|
|
}
|
|
case KEY_STRUCT_BLINKING_TEXT_LIST: {
|
|
readBlinkingText(parcel);
|
|
object = mBlinkingPosList;
|
|
|
|
break;
|
|
}
|
|
case KEY_WRAP_TEXT: {
|
|
mWrapText = parcel.readInt();
|
|
object = mWrapText;
|
|
break;
|
|
}
|
|
case KEY_HIGHLIGHT_COLOR_RGBA: {
|
|
mHighlightColorRGBA = parcel.readInt();
|
|
object = mHighlightColorRGBA;
|
|
break;
|
|
}
|
|
case KEY_DISPLAY_FLAGS: {
|
|
mDisplayFlags = parcel.readInt();
|
|
object = mDisplayFlags;
|
|
break;
|
|
}
|
|
case KEY_STRUCT_JUSTIFICATION: {
|
|
|
|
int horizontal = parcel.readInt();
|
|
int vertical = parcel.readInt();
|
|
mJustification = new Justification(horizontal, vertical);
|
|
|
|
object = mJustification;
|
|
break;
|
|
}
|
|
case KEY_BACKGROUND_COLOR_RGBA: {
|
|
mBackgroundColorRGBA = parcel.readInt();
|
|
object = mBackgroundColorRGBA;
|
|
break;
|
|
}
|
|
case KEY_STRUCT_TEXT_POS: {
|
|
int top = parcel.readInt();
|
|
int left = parcel.readInt();
|
|
int bottom = parcel.readInt();
|
|
int right = parcel.readInt();
|
|
mTextBounds = new Rect(left, top, right, bottom);
|
|
|
|
break;
|
|
}
|
|
case KEY_SCROLL_DELAY: {
|
|
mScrollDelay = parcel.readInt();
|
|
object = mScrollDelay;
|
|
break;
|
|
}
|
|
default: {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (object != null) {
|
|
if (mKeyObjectMap.containsKey(key)) {
|
|
mKeyObjectMap.remove(key);
|
|
}
|
|
// Previous mapping will be replaced with the new object, if there was one.
|
|
mKeyObjectMap.put(key, object);
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
* To parse and store the Style list.
|
|
*/
|
|
private void readStyle(Parcel parcel) {
|
|
boolean endOfStyle = false;
|
|
int startChar = -1;
|
|
int endChar = -1;
|
|
int fontId = -1;
|
|
boolean isBold = false;
|
|
boolean isItalic = false;
|
|
boolean isUnderlined = false;
|
|
int fontSize = -1;
|
|
int colorRGBA = -1;
|
|
while (!endOfStyle && (parcel.dataAvail() > 0)) {
|
|
int key = parcel.readInt();
|
|
switch (key) {
|
|
case KEY_START_CHAR: {
|
|
startChar = parcel.readInt();
|
|
break;
|
|
}
|
|
case KEY_END_CHAR: {
|
|
endChar = parcel.readInt();
|
|
break;
|
|
}
|
|
case KEY_FONT_ID: {
|
|
fontId = parcel.readInt();
|
|
break;
|
|
}
|
|
case KEY_STYLE_FLAGS: {
|
|
int flags = parcel.readInt();
|
|
// In the absence of any bits set in flags, the text
|
|
// is plain. Otherwise, 1: bold, 2: italic, 4: underline
|
|
isBold = ((flags % 2) == 1);
|
|
isItalic = ((flags % 4) >= 2);
|
|
isUnderlined = ((flags / 4) == 1);
|
|
break;
|
|
}
|
|
case KEY_FONT_SIZE: {
|
|
fontSize = parcel.readInt();
|
|
break;
|
|
}
|
|
case KEY_TEXT_COLOR_RGBA: {
|
|
colorRGBA = parcel.readInt();
|
|
break;
|
|
}
|
|
default: {
|
|
// End of the Style parsing. Reset the data position back
|
|
// to the position before the last parcel.readInt() call.
|
|
parcel.setDataPosition(parcel.dataPosition() - 4);
|
|
endOfStyle = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
Style style = new Style(startChar, endChar, fontId, isBold,
|
|
isItalic, isUnderlined, fontSize, colorRGBA);
|
|
if (mStyleList == null) {
|
|
mStyleList = new ArrayList<Style>();
|
|
}
|
|
mStyleList.add(style);
|
|
}
|
|
|
|
/*
|
|
* To parse and store the Font list
|
|
*/
|
|
private void readFont(Parcel parcel) {
|
|
int entryCount = parcel.readInt();
|
|
|
|
for (int i = 0; i < entryCount; i++) {
|
|
int id = parcel.readInt();
|
|
int nameLen = parcel.readInt();
|
|
|
|
byte[] text = parcel.createByteArray();
|
|
final String name = new String(text, 0, nameLen);
|
|
|
|
Font font = new Font(id, name);
|
|
|
|
if (mFontList == null) {
|
|
mFontList = new ArrayList<Font>();
|
|
}
|
|
mFontList.add(font);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* To parse and store the Highlight list
|
|
*/
|
|
private void readHighlight(Parcel parcel) {
|
|
int startChar = parcel.readInt();
|
|
int endChar = parcel.readInt();
|
|
CharPos pos = new CharPos(startChar, endChar);
|
|
|
|
if (mHighlightPosList == null) {
|
|
mHighlightPosList = new ArrayList<CharPos>();
|
|
}
|
|
mHighlightPosList.add(pos);
|
|
}
|
|
|
|
/*
|
|
* To parse and store the Karaoke list
|
|
*/
|
|
private void readKaraoke(Parcel parcel) {
|
|
int entryCount = parcel.readInt();
|
|
|
|
for (int i = 0; i < entryCount; i++) {
|
|
int startTimeMs = parcel.readInt();
|
|
int endTimeMs = parcel.readInt();
|
|
int startChar = parcel.readInt();
|
|
int endChar = parcel.readInt();
|
|
Karaoke kara = new Karaoke(startTimeMs, endTimeMs,
|
|
startChar, endChar);
|
|
|
|
if (mKaraokeList == null) {
|
|
mKaraokeList = new ArrayList<Karaoke>();
|
|
}
|
|
mKaraokeList.add(kara);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* To parse and store HyperText list
|
|
*/
|
|
private void readHyperText(Parcel parcel) {
|
|
int startChar = parcel.readInt();
|
|
int endChar = parcel.readInt();
|
|
|
|
int len = parcel.readInt();
|
|
byte[] url = parcel.createByteArray();
|
|
final String urlString = new String(url, 0, len);
|
|
|
|
len = parcel.readInt();
|
|
byte[] alt = parcel.createByteArray();
|
|
final String altString = new String(alt, 0, len);
|
|
HyperText hyperText = new HyperText(startChar, endChar, urlString, altString);
|
|
|
|
|
|
if (mHyperTextList == null) {
|
|
mHyperTextList = new ArrayList<HyperText>();
|
|
}
|
|
mHyperTextList.add(hyperText);
|
|
}
|
|
|
|
/*
|
|
* To parse and store blinking text list
|
|
*/
|
|
private void readBlinkingText(Parcel parcel) {
|
|
int startChar = parcel.readInt();
|
|
int endChar = parcel.readInt();
|
|
CharPos blinkingPos = new CharPos(startChar, endChar);
|
|
|
|
if (mBlinkingPosList == null) {
|
|
mBlinkingPosList = new ArrayList<CharPos>();
|
|
}
|
|
mBlinkingPosList.add(blinkingPos);
|
|
}
|
|
|
|
/*
|
|
* To check whether the given key is valid.
|
|
* @param key the key to be checked.
|
|
* @return true if the key is a valid one. Otherwise, false.
|
|
*/
|
|
private boolean isValidKey(final int key) {
|
|
if (!((key >= FIRST_PUBLIC_KEY) && (key <= LAST_PUBLIC_KEY))
|
|
&& !((key >= FIRST_PRIVATE_KEY) && (key <= LAST_PRIVATE_KEY))) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
* To check whether the given key is contained in this TimedText object.
|
|
* @param key the key to be checked.
|
|
* @return true if the key is contained in this TimedText object.
|
|
* Otherwise, false.
|
|
*/
|
|
private boolean containsKey(final int key) {
|
|
if (isValidKey(key) && mKeyObjectMap.containsKey(key)) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
* @return a set of the keys contained in this TimedText object.
|
|
*/
|
|
private Set keySet() {
|
|
return mKeyObjectMap.keySet();
|
|
}
|
|
|
|
/*
|
|
* To retrieve the object associated with the key. Caller must make sure
|
|
* the key is present using the containsKey method otherwise a
|
|
* RuntimeException will occur.
|
|
* @param key the key used to retrieve the object.
|
|
* @return an object. The object could be 1) an instance of Integer; 2) a
|
|
* List of CharPos, Karaoke, Font, Style, and HyperText, or 3) an instance of
|
|
* Justification.
|
|
*/
|
|
private Object getObject(final int key) {
|
|
if (containsKey(key)) {
|
|
return mKeyObjectMap.get(key);
|
|
} else {
|
|
throw new IllegalArgumentException("Invalid key: " + key);
|
|
}
|
|
}
|
|
}
|