HdmiRecordSources.java revision b6591b8e5399099dc6b7693e0fc719b613aba89c
1/* 2 * Copyright (C) 2014 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 android.hardware.hdmi; 18 19import android.annotation.Nullable; 20import android.annotation.SystemApi; 21import android.util.Log; 22 23/** 24 * Container for record source used for one touch record. 25 * Use one of helper method by source type. 26 * <ul> 27 * <li>Own source: {@link #ofOwnSource()} 28 * <li>Digital service(channel id): {@link #ofDigitalChannelId(int, DigitalChannelData)} 29 * <li>Digital service(ARIB): {@link #ofArib(int, AribData)} 30 * <li>Digital service(ATSC): {@link #ofAtsc(int, AtscData)} 31 * <li>Digital service(DVB): {@link #ofDvb(int, DvbData)} 32 * <li>Analogue: {@link #ofAnalogue(int, int, int)} 33 * <li>External plug: {@link #ofExternalPlug(int)} 34 * <li>External physical address: {@link #ofExternalPhysicalAddress(int)}. 35 * <ul> 36 * 37 * @hide 38 */ 39@SystemApi 40public final class HdmiRecordSources { 41 private static final String TAG = "HdmiRecordSources"; 42 43 /** Record source type for "Own Source". */ 44 private static final int RECORD_SOURCE_TYPE_OWN_SOURCE = 1; 45 /** Record source type for "Digital Service". */ 46 private static final int RECORD_SOURCE_TYPE_DIGITAL_SERVICE = 2; 47 /** Record source type for "Analogue Service". */ 48 private static final int RECORD_SOURCE_TYPE_ANALOGUE_SERVICE = 3; 49 /** Record source type for "Exteranl Plug". */ 50 private static final int RECORD_SOURCE_TYPE_EXTERNAL_PLUG = 4; 51 /** Record source type for "External Physical Address". */ 52 private static final int RECORD_SOURCE_TYPE_EXTERNAL_PHYSICAL_ADDRESS = 5; 53 54 private HdmiRecordSources() {} 55 56 /** 57 * Base class for each record source. 58 */ 59 static abstract class RecordSource { 60 protected final int mSourceType; 61 protected final int mExtraDataSize; 62 63 protected RecordSource(int sourceType, int extraDataSize) { 64 mSourceType = sourceType; 65 mExtraDataSize = extraDataSize; 66 } 67 68 abstract int extraParamToByteArray(byte[] data, int index); 69 70 final int getDataSize(boolean includeType) { 71 return includeType ? mExtraDataSize + 1 : mExtraDataSize; 72 } 73 74 public final int toByteArray(boolean includeType, byte[] data, int index) { 75 if (includeType) { 76 // 1 to 8 bytes (depends on source). 77 // {[Record Source Type]} | 78 // {[Record Source Type] [Digital Service Identification]} | 79 // {[Record Source Type] [Analogue Broadcast Type] [Analogue Frequency] 80 // [Broadcast System]} | 81 // {[Record Source Type] [External Plug]} | 82 // {[Record Source Type] [External Physical Address]} 83 // The first byte is used for record source type. 84 data[index++] = (byte) mSourceType; 85 } 86 extraParamToByteArray(data, index); 87 return getDataSize(includeType); 88 } 89 } 90 91 // --------------------------------------------------------------------------------------------- 92 // ---- Own source ----------------------------------------------------------------------------- 93 // --------------------------------------------------------------------------------------------- 94 /** 95 * Create {@link OwnSource} of own source. 96 */ 97 public static OwnSource ofOwnSource() { 98 return new OwnSource(); 99 } 100 101 /** 102 * @hide 103 */ 104 @SystemApi 105 public static final class OwnSource extends RecordSource { 106 private static final int EXTRA_DATA_SIZE = 0; 107 108 private OwnSource() { 109 super(RECORD_SOURCE_TYPE_OWN_SOURCE, EXTRA_DATA_SIZE); 110 } 111 112 @Override 113 int extraParamToByteArray(byte[] data, int index) { 114 return 0; 115 } 116 } 117 118 119 // --------------------------------------------------------------------------------------------- 120 // ---- Digital service data ------------------------------------------------------------------- 121 // --------------------------------------------------------------------------------------------- 122 /** 123 * Digital broadcast general types 124 */ 125 /** @hide */ 126 public static final int DIGITAL_BROADCAST_TYPE_ARIB = 0x0; 127 /** @hide */ 128 public static final int DIGITAL_BROADCAST_TYPE_ATSC = 0x1; 129 /** @hide */ 130 public static final int DIGITAL_BROADCAST_TYPE_DVB = 0x2; 131 132 /** 133 * Digital broadcast specific types 134 */ 135 /** @hide */ 136 public static final int DIGITAL_BROADCAST_TYPE_ARIB_BS = 0x8; 137 /** @hide */ 138 public static final int DIGITAL_BROADCAST_TYPE_ARIB_CS = 0x9; 139 /** @hide */ 140 public static final int DIGITAL_BROADCAST_TYPE_ARIB_T = 0xA; 141 /** @hide */ 142 public static final int DIGITAL_BROADCAST_TYPE_ATSC_CABLE = 0x10; 143 /** @hide */ 144 public static final int DIGITAL_BROADCAST_TYPE_ATSC_SATELLITE = 0x11; 145 /** @hide */ 146 public static final int DIGITAL_BROADCAST_TYPE_ATSC_TERRESTRIAL = 0x12; 147 /** @hide */ 148 public static final int DIGITAL_BROADCAST_TYPE_DVB_C = 0x18; 149 /** @hide */ 150 public static final int DIGITAL_BROADCAST_TYPE_DVB_S = 0x19; 151 /** @hide */ 152 public static final int DIGITAL_BROADCAST_TYPE_DVB_S2 = 0x1A; 153 /** @hide */ 154 public static final int DIGITAL_BROADCAST_TYPE_DVB_T = 0x1B; 155 156 /** Channel number formats. */ 157 private static final int CHANNEL_NUMBER_FORMAT_1_PART = 0x01; 158 private static final int CHANNEL_NUMBER_FORMAT_2_PART = 0x02; 159 160 /** 161 * Interface for digital source identification. 162 */ 163 private interface DigitalServiceIdentification { 164 void toByteArray(byte[] data, int index); 165 } 166 167 /** 168 * Digital service identification for ARIB. 169 * <p> 170 * It consists of the following fields 171 * <ul> 172 * <li>transport stream id: 2bytes 173 * <li>service id: 2bytes 174 * <li>original network id: 2bytes 175 * </ul> 176 * @hide 177 */ 178 public static final class AribData implements DigitalServiceIdentification { 179 /** The transport_stream_ID of the transport stream carrying the required service */ 180 private final int mTransportStreamId; 181 /** The service_ID of the required service */ 182 private final int mServiceId; 183 /** 184 * The original_network_ID of the network carrying the transport stream for the required 185 * service 186 */ 187 private final int mOriginalNetworkId; 188 189 public AribData(int transportStreamId, int serviceId, int originalNetworkId) { 190 mTransportStreamId = transportStreamId; 191 mServiceId = serviceId; 192 mOriginalNetworkId = originalNetworkId; 193 } 194 195 @Override 196 public void toByteArray(byte[] data, int index) { 197 threeFieldsToSixBytes(mTransportStreamId, mServiceId, mOriginalNetworkId, data, index); 198 } 199 } 200 201 /** 202 * Digital service identification for ATSC. 203 * <p> 204 * It consists of the following fields 205 * <ul> 206 * <li>transport stream id: 2bytes 207 * <li>program number: 2bytes 208 * <li>reserved: 2bytes 209 * </ul> 210 * @hide 211 */ 212 public static final class AtscData implements DigitalServiceIdentification { 213 /** The transport_stream_ID of the transport stream carrying the required service */ 214 private final int mTransportStreamId; 215 /** The Program_number of the required service */ 216 private final int mProgramNumber; 217 218 public AtscData(int transportStreamId, int programNumber) { 219 mTransportStreamId = transportStreamId; 220 mProgramNumber = programNumber; 221 } 222 223 @Override 224 public void toByteArray(byte[] data, int index) { 225 threeFieldsToSixBytes(mTransportStreamId, mProgramNumber, 0, data, index); 226 } 227 } 228 229 /** 230 * Digital service identification for DVB. 231 * <p> 232 * It consists of the following fields 233 * <ul> 234 * <li>transport stream id: 2bytes 235 * <li>service id: 2bytes 236 * <li>original network id: 2bytes 237 * </ul> 238 * @hide 239 */ 240 public static final class DvbData implements DigitalServiceIdentification { 241 /** The transport_stream_ID of the transport stream carrying the required service */ 242 private final int mTransportStreamId; 243 /** The service_ID of the required service */ 244 private final int mServiceId; 245 /** 246 * The original_network_ID of the network carrying the transport stream for the required 247 * service 248 */ 249 private final int mOriginalNetworkId; 250 251 public DvbData(int transportStreamId, int serviceId, int originalNetworkId) { 252 mTransportStreamId = transportStreamId; 253 mServiceId = serviceId; 254 mOriginalNetworkId = originalNetworkId; 255 } 256 257 @Override 258 public void toByteArray(byte[] data, int index) { 259 threeFieldsToSixBytes(mTransportStreamId, mServiceId, mOriginalNetworkId, data, index); 260 } 261 } 262 263 /** 264 * Identifies a 1-part Logical or Virtual Channel Number or a 2-part Major and Minor channel 265 * combination. 266 */ 267 private static final class ChannelIdentifier { 268 /** Identifies Channel Format */ 269 private final int mChannelNumberFormat; 270 /** 271 * Major Channel Number (if Channel Number Format is 2-part). If format is 272 * CHANNEL_NUMBER_FORMAT_1_PART, this will be ignored(0). 273 */ 274 private final int mMajorChannelNumber; 275 /** 276 * 1-part Channel Number, or a Minor Channel Number (if Channel Number Format is 2-part). 277 */ 278 private final int mMinorChannelNumber; 279 280 private ChannelIdentifier(int format, int majorNumber, int minorNumer) { 281 mChannelNumberFormat = format; 282 mMajorChannelNumber = majorNumber; 283 mMinorChannelNumber = minorNumer; 284 } 285 286 private void toByteArray(byte[] data, int index) { 287 // The first 6 bits for format, the 10 bits for major number. 288 data[index] = (byte) (((mChannelNumberFormat << 2) | (mMajorChannelNumber >>> 8) & 0x3)); 289 data[index + 1] = (byte) (mMajorChannelNumber & 0xFF); 290 // Minor number uses the next 16 bits. 291 shortToByteArray((short) mMinorChannelNumber, data, index + 2); 292 } 293 } 294 295 /** 296 * Digital channel id. 297 * <p> 298 * It consists of the following fields 299 * <ul> 300 * <li>channel number format: 6bits 301 * <li>major number: 10bits 302 * <li>minor number: 16bits 303 * <li>reserved: 2bytes 304 * </ul> 305 * @hide 306 */ 307 public static final class DigitalChannelData implements DigitalServiceIdentification { 308 /** Identifies the logical or virtual channel number of a service. */ 309 private ChannelIdentifier mChannelIdentifier; 310 311 public static DigitalChannelData ofTwoNumbers(int majorNumber, int minorNumber) { 312 return new DigitalChannelData( 313 new ChannelIdentifier(CHANNEL_NUMBER_FORMAT_2_PART, majorNumber, minorNumber)); 314 } 315 316 public static DigitalChannelData ofOneNumber(int number) { 317 return new DigitalChannelData( 318 new ChannelIdentifier(CHANNEL_NUMBER_FORMAT_1_PART, 0, number)); 319 } 320 321 private DigitalChannelData(ChannelIdentifier id) { 322 mChannelIdentifier = id; 323 } 324 325 @Override 326 public void toByteArray(byte[] data, int index) { 327 mChannelIdentifier.toByteArray(data, index); 328 // The last 2 bytes is reserved for future use. 329 data[index + 4] = 0; 330 data[index + 5] = 0; 331 } 332 } 333 334 /** 335 * Create {@link DigitalServiceSource} with channel type. 336 * 337 * @param broadcastSystem digital broadcast system. It should be one of 338 * <ul> 339 * <li>{@link #DIGITAL_BROADCAST_TYPE_ARIB} 340 * <li>{@link #DIGITAL_BROADCAST_TYPE_ATSC} 341 * <li>{@link #DIGITAL_BROADCAST_TYPE_DVB} 342 * <li>{@link #DIGITAL_BROADCAST_TYPE_ARIB_BS} 343 * <li>{@link #DIGITAL_BROADCAST_TYPE_ARIB_CS} 344 * <li>{@link #DIGITAL_BROADCAST_TYPE_ARIB_T} 345 * <li>{@link #DIGITAL_BROADCAST_TYPE_ATSC_CABLE} 346 * <li>{@link #DIGITAL_BROADCAST_TYPE_ATSC_SATELLITE} 347 * <li>{@link #DIGITAL_BROADCAST_TYPE_ATSC_TERRESTRIAL} 348 * <li>{@link #DIGITAL_BROADCAST_TYPE_DVB_C} 349 * <li>{@link #DIGITAL_BROADCAST_TYPE_DVB_S} 350 * <li>{@link #DIGITAL_BROADCAST_TYPE_DVB_S2} 351 * <li>{@link #DIGITAL_BROADCAST_TYPE_DVB_T} 352 * </ul> 353 * @hide 354 */ 355 public static DigitalServiceSource ofDigitalChannelId(int broadcastSystem, 356 DigitalChannelData data) { 357 if (data == null) { 358 throw new IllegalArgumentException("data should not be null."); 359 } 360 switch (broadcastSystem) { 361 case DIGITAL_BROADCAST_TYPE_ARIB: 362 case DIGITAL_BROADCAST_TYPE_ATSC: 363 case DIGITAL_BROADCAST_TYPE_DVB: 364 case DIGITAL_BROADCAST_TYPE_ARIB_BS: 365 case DIGITAL_BROADCAST_TYPE_ARIB_CS: 366 case DIGITAL_BROADCAST_TYPE_ARIB_T: 367 case DIGITAL_BROADCAST_TYPE_ATSC_CABLE: 368 case DIGITAL_BROADCAST_TYPE_ATSC_SATELLITE: 369 case DIGITAL_BROADCAST_TYPE_ATSC_TERRESTRIAL: 370 case DIGITAL_BROADCAST_TYPE_DVB_C: 371 case DIGITAL_BROADCAST_TYPE_DVB_S: 372 case DIGITAL_BROADCAST_TYPE_DVB_S2: 373 case DIGITAL_BROADCAST_TYPE_DVB_T: 374 return new DigitalServiceSource( 375 DigitalServiceSource.DIGITAL_SERVICE_IDENTIFIED_BY_CHANNEL, 376 broadcastSystem, 377 data); 378 default: 379 Log.w(TAG, "Invalid broadcast type:" + broadcastSystem); 380 throw new IllegalArgumentException( 381 "Invalid broadcast system value:" + broadcastSystem); 382 } 383 } 384 385 /** 386 * Create {@link DigitalServiceSource} of ARIB type. 387 * 388 * @param aribType ARIB type. It should be one of 389 * <ul> 390 * <li>{@link #DIGITAL_BROADCAST_TYPE_ARIB} 391 * <li>{@link #DIGITAL_BROADCAST_TYPE_ARIB_BS} 392 * <li>{@link #DIGITAL_BROADCAST_TYPE_ARIB_CS} 393 * <li>{@link #DIGITAL_BROADCAST_TYPE_ARIB_T} 394 * </ul> 395 * @hide 396 */ 397 @Nullable 398 public static DigitalServiceSource ofArib(int aribType, AribData data) { 399 if (data == null) { 400 throw new IllegalArgumentException("data should not be null."); 401 } 402 switch (aribType) { 403 case DIGITAL_BROADCAST_TYPE_ARIB: 404 case DIGITAL_BROADCAST_TYPE_ARIB_BS: 405 case DIGITAL_BROADCAST_TYPE_ARIB_CS: 406 case DIGITAL_BROADCAST_TYPE_ARIB_T: 407 return new DigitalServiceSource( 408 DigitalServiceSource.DIGITAL_SERVICE_IDENTIFIED_BY_DIGITAL_ID, 409 aribType, data); 410 default: 411 Log.w(TAG, "Invalid ARIB type:" + aribType); 412 throw new IllegalArgumentException("type should not be null."); 413 } 414 } 415 416 /** 417 * Create {@link DigitalServiceSource} of ATSC type. 418 * 419 * @param atscType ATSC type. It should be one of 420 * <ul> 421 * <li>{@link #DIGITAL_BROADCAST_TYPE_ATSC} 422 * <li>{@link #DIGITAL_BROADCAST_TYPE_ATSC_CABLE} 423 * <li>{@link #DIGITAL_BROADCAST_TYPE_ATSC_SATELLITE} 424 * <li>{@link #DIGITAL_BROADCAST_TYPE_ATSC_TERRESTRIAL} 425 * </ul> 426 * @hide 427 */ 428 @Nullable 429 public static DigitalServiceSource ofAtsc(int atscType, AtscData data) { 430 if (data == null) { 431 throw new IllegalArgumentException("data should not be null."); 432 } 433 switch (atscType) { 434 case DIGITAL_BROADCAST_TYPE_ATSC: 435 case DIGITAL_BROADCAST_TYPE_ATSC_CABLE: 436 case DIGITAL_BROADCAST_TYPE_ATSC_SATELLITE: 437 case DIGITAL_BROADCAST_TYPE_ATSC_TERRESTRIAL: 438 return new DigitalServiceSource( 439 DigitalServiceSource.DIGITAL_SERVICE_IDENTIFIED_BY_DIGITAL_ID, 440 atscType, data); 441 default: 442 Log.w(TAG, "Invalid ATSC type:" + atscType); 443 throw new IllegalArgumentException("Invalid ATSC type:" + atscType); 444 } 445 } 446 447 /** 448 * Create {@link DigitalServiceSource} of ATSC type. 449 * 450 * @param dvbType DVB type. It should be one of 451 * <ul> 452 * <li>{@link #DIGITAL_BROADCAST_TYPE_DVB} 453 * <li>{@link #DIGITAL_BROADCAST_TYPE_DVB_C} 454 * <li>{@link #DIGITAL_BROADCAST_TYPE_DVB_S} 455 * <li>{@link #DIGITAL_BROADCAST_TYPE_DVB_S2} 456 * <li>{@link #DIGITAL_BROADCAST_TYPE_DVB_T} 457 * </ul> 458 * @hide 459 */ 460 @Nullable 461 public static DigitalServiceSource ofDvb(int dvbType, DvbData data) { 462 if (data == null) { 463 throw new IllegalArgumentException("data should not be null."); 464 } 465 switch (dvbType) { 466 case DIGITAL_BROADCAST_TYPE_DVB: 467 case DIGITAL_BROADCAST_TYPE_DVB_C: 468 case DIGITAL_BROADCAST_TYPE_DVB_S: 469 case DIGITAL_BROADCAST_TYPE_DVB_S2: 470 case DIGITAL_BROADCAST_TYPE_DVB_T: 471 return new DigitalServiceSource( 472 DigitalServiceSource.DIGITAL_SERVICE_IDENTIFIED_BY_DIGITAL_ID, 473 dvbType, data); 474 default: 475 Log.w(TAG, "Invalid DVB type:" + dvbType); 476 throw new IllegalArgumentException("Invalid DVB type:" + dvbType); 477 } 478 } 479 480 /** 481 * Record source container for "Digital Service". 482 * <ul> 483 * <li>[Record Source Type] - 1 byte 484 * <li>[Digital Identification] - 7 bytes 485 * </ul> 486 * @hide 487 */ 488 @SystemApi 489 public static final class DigitalServiceSource extends RecordSource { 490 /** Indicates that a service is identified by digital service IDs. */ 491 private static final int DIGITAL_SERVICE_IDENTIFIED_BY_DIGITAL_ID = 0; 492 /** Indicates that a service is identified by a logical or virtual channel number. */ 493 private static final int DIGITAL_SERVICE_IDENTIFIED_BY_CHANNEL = 1; 494 495 private static final int EXTRA_DATA_SIZE = 7; 496 497 /** 498 * Type of identification. It should be one of DIGITAL_SERVICE_IDENTIFIED_BY_DIGITAL_ID and 499 * DIGITAL_SERVICE_IDENTIFIED_BY_CHANNEL 500 */ 501 private final int mIdentificationMethod; 502 /** 503 * Indicates the Digital Broadcast System of required service. This is present irrespective 504 * of the state of [Service Identification Method]. 505 */ 506 private final int mBroadcastSystem; 507 508 /** 509 * Extra parameter for digital service identification. 510 */ 511 private final DigitalServiceIdentification mIdentification; 512 513 private DigitalServiceSource(int identificatinoMethod, int broadcastSystem, 514 DigitalServiceIdentification identification) { 515 super(RECORD_SOURCE_TYPE_DIGITAL_SERVICE, EXTRA_DATA_SIZE); 516 mIdentificationMethod = identificatinoMethod; 517 mBroadcastSystem = broadcastSystem; 518 mIdentification = identification; 519 } 520 521 @Override 522 int extraParamToByteArray(byte[] data, int index) { 523 data[index] = (byte) ((mIdentificationMethod << 7) | (mBroadcastSystem & 0x7F)); 524 mIdentification.toByteArray(data, index + 1); 525 return EXTRA_DATA_SIZE; 526 527 } 528 } 529 530 531 // --------------------------------------------------------------------------------------------- 532 // ---- Analogue service data ------------------------------------------------------------------ 533 // --------------------------------------------------------------------------------------------- 534 /** 535 * Analogue broadcast types. 536 */ 537 /** @hide */ 538 public static final int ANALOGUE_BROADCAST_TYPE_CABLE = 0x0; 539 /** @hide */ 540 public static final int ANALOGUE_BROADCAST_TYPE_SATELLITE = 0x1; 541 /** @hide */ 542 public static final int ANALOGUE_BROADCAST_TYPE_TERRESTRIAL = 0x2; 543 544 /** 545 * Broadcast system values. 546 */ 547 /** @hide */ 548 public static final int BROADCAST_SYSTEM_PAL_BG = 0; 549 /** @hide */ 550 public static final int BROADCAST_SYSTEM_SECAM_LP = 1; 551 /** @hide */ 552 public static final int BROADCAST_SYSTEM_PAL_M = 2; 553 /** @hide */ 554 public static final int BROADCAST_SYSTEM_NTSC_M = 3; 555 /** @hide */ 556 public static final int BROADCAST_SYSTEM_PAL_I = 4; 557 /** @hide */ 558 public static final int BROADCAST_SYSTEM_SECAM_DK = 5; 559 /** @hide */ 560 public static final int BROADCAST_SYSTEM_SECAM_BG = 6; 561 /** @hide */ 562 public static final int BROADCAST_SYSTEM_SECAM_L = 7; 563 /** @hide */ 564 public static final int BROADCAST_SYSTEM_PAL_DK = 8; 565 /** @hide */ 566 public static final int BROADCAST_SYSTEM_PAL_OTHER_SYSTEM = 31; 567 568 /** 569 * Create {@link AnalogueServiceSource} of analogue service. 570 * 571 * @param broadcastType 572 * @param frequency 573 * @param broadcastSystem 574 * @hide 575 */ 576 @Nullable 577 public static AnalogueServiceSource ofAnalogue(int broadcastType, int frequency, 578 int broadcastSystem){ 579 if (broadcastType < ANALOGUE_BROADCAST_TYPE_CABLE 580 || broadcastType > ANALOGUE_BROADCAST_TYPE_TERRESTRIAL) { 581 Log.w(TAG, "Invalid Broadcast type:" + broadcastType); 582 throw new IllegalArgumentException("Invalid Broadcast type:" + broadcastType); 583 } 584 if (frequency < 0 || frequency > 0xFFFF) { 585 Log.w(TAG, "Invalid frequency value[0x0000-0xFFFF]:" + frequency); 586 throw new IllegalArgumentException( 587 "Invalid frequency value[0x0000-0xFFFF]:" + frequency); 588 } 589 if (broadcastSystem < BROADCAST_SYSTEM_PAL_BG 590 || broadcastSystem > BROADCAST_SYSTEM_PAL_OTHER_SYSTEM) { 591 592 Log.w(TAG, "Invalid Broadcast system:" + broadcastSystem); 593 throw new IllegalArgumentException( 594 "Invalid Broadcast system:" + broadcastSystem); 595 } 596 597 return new AnalogueServiceSource(broadcastType, frequency, broadcastSystem); 598 } 599 600 /** 601 * Record source for analogue service data. It consists of 602 * <ul> 603 * <li>[Record Source Type] - 1 byte 604 * <li>[Analogue Broadcast Type] - 1 byte 605 * <li>[Analogue Frequency] - 2 bytes 606 * <li>[Broadcast System] - 1 byte 607 * </ul> 608 * @hide 609 */ 610 @SystemApi 611 public static final class AnalogueServiceSource extends RecordSource { 612 private static final int EXTRA_DATA_SIZE = 4; 613 614 /** Indicates the Analogue broadcast type. */ 615 private final int mBroadcastType; 616 /** Used to specify the frequency used by an analogue tuner. 0x0000<N<0xFFFF. */ 617 private final int mFrequency; 618 /** 619 * This specifies information about the color system, the sound carrier and the 620 * IF-frequency. 621 */ 622 private final int mBroadcastSystem; 623 624 private AnalogueServiceSource(int broadcastType, int frequency, int broadcastSystem) { 625 super(RECORD_SOURCE_TYPE_ANALOGUE_SERVICE, EXTRA_DATA_SIZE); 626 mBroadcastType = broadcastType; 627 mFrequency = frequency; 628 mBroadcastSystem = broadcastSystem; 629 } 630 631 @Override 632 protected int extraParamToByteArray(byte[] data, int index) { 633 // [Analogue Broadcast Type] - 1 byte 634 data[index] = (byte) mBroadcastType; 635 // [Analogue Frequency] - 2 bytes 636 shortToByteArray((short) mFrequency, data, index + 1); 637 // [Broadcast System] - 1 byte 638 data[index + 3] = (byte) mBroadcastSystem; 639 return EXTRA_DATA_SIZE; 640 } 641 } 642 643 644 // --------------------------------------------------------------------------------------------- 645 // ---- External plug data --------------------------------------------------------------------- 646 // --------------------------------------------------------------------------------------------- 647 /** 648 * Create {@link ExternalPlugData} of external plug type. 649 * 650 * @param plugNumber plug number. It should be in range of [1, 255] 651 * @hide 652 */ 653 public static ExternalPlugData ofExternalPlug(int plugNumber) { 654 if (plugNumber < 1 || plugNumber > 255) { 655 Log.w(TAG, "Invalid plug number[1-255]" + plugNumber); 656 throw new IllegalArgumentException("Invalid plug number[1-255]" + plugNumber); 657 } 658 return new ExternalPlugData(plugNumber); 659 } 660 661 /** 662 * Record source for external plug (external non-HDMI device connect) type. 663 * <ul> 664 * <li>[Record Source Type] - 1 byte 665 * <li>[External Plug] - 1 byte 666 * </ul> 667 * @hide 668 */ 669 @SystemApi 670 public static final class ExternalPlugData extends RecordSource { 671 private static final int EXTRA_DATA_SIZE = 1; 672 673 /** External Plug number on the Recording Device. */ 674 private final int mPlugNumber; 675 676 private ExternalPlugData(int plugNumber) { 677 super(RECORD_SOURCE_TYPE_EXTERNAL_PLUG, EXTRA_DATA_SIZE); 678 mPlugNumber = plugNumber; 679 } 680 681 @Override 682 int extraParamToByteArray(byte[] data, int index) { 683 data[index] = (byte) mPlugNumber; 684 return EXTRA_DATA_SIZE; 685 } 686 } 687 688 // --------------------------------------------------------------------------------------------- 689 // ---- External physical address -------------------------------------------------------------- 690 // --------------------------------------------------------------------------------------------- 691 /** 692 * Create {@link ExternalPhysicalAddress} of external physical address. 693 * 694 * @param physicalAddress 695 * @hide 696 */ 697 public static ExternalPhysicalAddress ofExternalPhysicalAddress(int physicalAddress) { 698 if ((physicalAddress & ~0xFFFF) != 0) { 699 Log.w(TAG, "Invalid physical address:" + physicalAddress); 700 throw new IllegalArgumentException("Invalid physical address:" + physicalAddress); 701 } 702 703 return new ExternalPhysicalAddress(physicalAddress); 704 } 705 706 /** 707 * Record source for external physical address. 708 * <ul> 709 * <li>[Record Source Type] - 1 byte 710 * <li>[Physical address] - 2 byte 711 * </ul> 712 * @hide 713 */ 714 @SystemApi 715 public static final class ExternalPhysicalAddress extends RecordSource { 716 private static final int EXTRA_DATA_SIZE = 2; 717 718 private final int mPhysicalAddress; 719 720 private ExternalPhysicalAddress(int physicalAddress) { 721 super(RECORD_SOURCE_TYPE_EXTERNAL_PHYSICAL_ADDRESS, EXTRA_DATA_SIZE); 722 mPhysicalAddress = physicalAddress; 723 } 724 725 @Override 726 int extraParamToByteArray(byte[] data, int index) { 727 shortToByteArray((short) mPhysicalAddress, data, index); 728 return EXTRA_DATA_SIZE; 729 } 730 } 731 732 733 // --------------------------------------------------------------------------------------------- 734 // ------- Helper methods ---------------------------------------------------------------------- 735 // --------------------------------------------------------------------------------------------- 736 private static int threeFieldsToSixBytes(int first, int second, int third, byte[] data, 737 int index) { 738 shortToByteArray((short) first, data, index); 739 shortToByteArray((short) second, data, index + 2); 740 shortToByteArray((short) third, data, index + 4); 741 return 6; 742 } 743 744 private static int shortToByteArray(short value, byte[] byteArray, int index) { 745 byteArray[index] = (byte) ((value >>> 8) & 0xFF); 746 byteArray[index + 1] = (byte) (value & 0xFF); 747 return 2; 748 } 749 750 /** 751 * Check the byte array of record source. 752 * @hide 753 */ 754 public static boolean checkRecordSource(byte[] recordSource) { 755 int recordSourceType = recordSource[0]; 756 int extraDataSize = recordSource.length - 1; 757 switch (recordSourceType) { 758 case RECORD_SOURCE_TYPE_OWN_SOURCE: 759 return extraDataSize == OwnSource.EXTRA_DATA_SIZE; 760 case RECORD_SOURCE_TYPE_DIGITAL_SERVICE: 761 return extraDataSize == DigitalServiceSource.EXTRA_DATA_SIZE; 762 case RECORD_SOURCE_TYPE_ANALOGUE_SERVICE: 763 return extraDataSize == AnalogueServiceSource.EXTRA_DATA_SIZE; 764 case RECORD_SOURCE_TYPE_EXTERNAL_PLUG: 765 return extraDataSize == ExternalPlugData.EXTRA_DATA_SIZE; 766 case RECORD_SOURCE_TYPE_EXTERNAL_PHYSICAL_ADDRESS: 767 return extraDataSize == ExternalPhysicalAddress.EXTRA_DATA_SIZE; 768 default: 769 return false; 770 } 771 } 772} 773