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