diff --git a/core/java/android/hardware/hdmi/HdmiTimerRecordSources.java b/core/java/android/hardware/hdmi/HdmiTimerRecordSources.java new file mode 100644 index 0000000000000..03efd8c4d1624 --- /dev/null +++ b/core/java/android/hardware/hdmi/HdmiTimerRecordSources.java @@ -0,0 +1,415 @@ +/* + * Copyright (C) 2014 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.hardware.hdmi; + +import android.annotation.SystemApi; +import android.hardware.hdmi.HdmiRecordSources.AnalogueServiceSource; +import android.hardware.hdmi.HdmiRecordSources.DigitalServiceSource; +import android.hardware.hdmi.HdmiRecordSources.ExternalPhysicalAddress; +import android.hardware.hdmi.HdmiRecordSources.ExternalPlugData; +import android.hardware.hdmi.HdmiRecordSources.RecordSource; +import android.util.Log; + +/** + * Container for timer record source used for timer recording. Timer source consists of two parts, + * timer info and record source. + *
+ * Timer info contains all timing information used for recording. It consists of the following + * values. + *
+ * Record source containers all program information used for recording. + * For more details, look at {@link HdmiRecordSources}. + *
+ * Usage + *
+ * TimeOrDuration startTime = HdmiTimerRecordSources.ofTime(18, 00); // 6PM. + * TimeOrDuration duration = HdmiTimerRecordSource.ofDuration(1, 00); // 1 hour duration. + * // For 1 hour from 6PM, August 10th every SaturDay and Sunday. + * TimerInfo timerInfo = HdmiTimerRecordSource.timerInfoOf(10, 8, starTime, duration, + * HdmiTimerRecordSource.RECORDING_SEQUENCE_REPEAT_SATURDAY | + * HdmiTimerRecordSource.RECORDING_SEQUENCE_REPEAT_SUNDAY); + * // create digital source. + * DigitalServiceSource recordSource = HdmiRecordSource.ofDvb(...); + * TimerRecordSource source = ofDigitalSource(timerInfo, recordSource); + *+ * + * @hide + */ +@SystemApi +public class HdmiTimerRecordSources { + private static final String TAG = "HdmiTimerRecordingSources"; + + private HdmiTimerRecordSources() {} + + /** + * Create {@link TimerRecordSource} for digital source which is used for <Set Digital + * Timer>. + * + * @param timerInfo timer info used for timer recording + * @param source digital source used for timer recording + * @return {@link TimerRecordSource} + * @throws IllegalArgumentException if {@code timerInfo} or {@code source} is null + */ + public static TimerRecordSource ofDigitalSource(TimerInfo timerInfo, + DigitalServiceSource source) { + checkTimerRecordSourceInputs(timerInfo, source); + return new TimerRecordSource(timerInfo, source); + } + + /** + * Create {@link TimerRecordSource} for analogue source which is used for <Set Analogue + * Timer>. + * + * @param timerInfo timer info used for timer recording + * @param source digital source used for timer recording + * @return {@link TimerRecordSource} + * @throws IllegalArgumentException if {@code timerInfo} or {@code source} is null + */ + public static TimerRecordSource ofAnalogueSource(TimerInfo timerInfo, + AnalogueServiceSource source) { + checkTimerRecordSourceInputs(timerInfo, source); + return new TimerRecordSource(timerInfo, source); + } + + /** + * Create {@link TimerRecordSource} for external plug which is used for <Set External + * Timer>. + * + * @param timerInfo timer info used for timer recording + * @param source digital source used for timer recording + * @return {@link TimerRecordSource} + * @throws IllegalArgumentException if {@code timerInfo} or {@code source} is null + */ + public static TimerRecordSource ofExternalPlug(TimerInfo timerInfo, ExternalPlugData source) { + checkTimerRecordSourceInputs(timerInfo, source); + return new TimerRecordSource(timerInfo, + new ExternalSourceDecorator(source, EXTERNAL_SOURCE_SPECIFIER_EXTERNAL_PLUG)); + } + + /** + * Create {@link TimerRecordSource} for external physical address which is used for <Set + * External Timer>. + * + * @param timerInfo timer info used for timer recording + * @param source digital source used for timer recording + * @return {@link TimerRecordSource} + * @throws IllegalArgumentException if {@code timerInfo} or {@code source} is null + */ + public static TimerRecordSource ofExternalPhysicalAddress(TimerInfo timerInfo, + ExternalPhysicalAddress source) { + checkTimerRecordSourceInputs(timerInfo, source); + return new TimerRecordSource(timerInfo, + new ExternalSourceDecorator(source, + EXTERNAL_SOURCE_SPECIFIER_EXTERNAL_PHYSICAL_ADDRESS)); + } + + private static void checkTimerRecordSourceInputs(TimerInfo timerInfo, RecordSource source) { + if (timerInfo == null) { + Log.w(TAG, "TimerInfo should not be null."); + throw new IllegalArgumentException("TimerInfo should not be null."); + } + if (source == null) { + Log.w(TAG, "source should not be null."); + throw new IllegalArgumentException("source should not be null."); + } + } + + /** + * Create {@link Duration} for time value. + * + * @param hour hour in range of [0, 24] + * @param minute minute in range of [0, 60] + * @return {@link Duration} + * @throw IllegalArgumentException if hour or minute is out of range + */ + public static Time ofTime(int hour, int minute) { + checkTimeValue(hour, minute); + return new Time(hour, minute); + } + + private static void checkTimeValue(int hour, int minute) { + if (hour < 0 || hour > 24) { + throw new IllegalArgumentException("Hour should be in rage of [0, 24]:" + hour); + } + if (minute < 0 || minute > 60) { + throw new IllegalArgumentException("Minute should be in rage of [0, 60]:" + minute); + } + } + + /** + * Create {@link Duration} for duration value. + * + * @param hour hour in range of [0, 90] + * @param minute minute in range of [0, 60] + * @return {@link Duration} + * @throw IllegalArgumentException if hour or minute is out of range + */ + public static Duration ofDuration(int hour, int minute) { + checkDurationValue(hour, minute); + return new Duration(hour, minute); + } + + private static void checkDurationValue(int hour, int minute) { + if (hour < 0 || hour > 99) { + throw new IllegalArgumentException("Hour should be in rage of [0, 99]:" + hour); + } + if (minute < 0 || minute > 60) { + throw new IllegalArgumentException("minute should be in rage of [0, 60]:" + minute); + } + } + + private static class TimeUnit { + protected final int mHour; + protected final int mMinute; + + protected TimeUnit(int hour, int minute) { + mHour = hour; + mMinute = minute; + } + + protected int toByteArray(byte[] data, int index) { + data[index] = toBcdByte(mHour); + data[index + 1] = toBcdByte(mMinute); + return 2; + } + + protected static byte toBcdByte(int value) { + int digitOfTen = (value / 10) % 10; + int digitOfOne = value % 10; + return (byte) ((digitOfTen << 4) | digitOfOne); + } + } + + /** + * Place holder for time value. + */ + public static class Time extends TimeUnit { + private Time(int hour, int minute) { + super(hour, minute); + } + } + + /** + * Place holder for duration value. + */ + public static class Duration extends TimeUnit { + private Duration(int hour, int minute) { + super(hour, minute); + } + } + + /** + * Fields for recording sequence. + * The following can be merged by OR(|) operation. + */ + public static final int RECORDING_SEQUENCE_REPEAT_ONCE_ONLY = 0; + public static final int RECORDING_SEQUENCE_REPEAT_SUNDAY = 1 << 0; + public static final int RECORDING_SEQUENCE_REPEAT_MONDAY = 1 << 1; + public static final int RECORDING_SEQUENCE_REPEAT_TUESDAY = 1 << 2; + public static final int RECORDING_SEQUENCE_REPEAT_WEDNESDAY = 1 << 3; + public static final int RECORDING_SEQUENCE_REPEAT_THURSDAY = 1 << 4; + public static final int RECORDING_SEQUENCE_REPEAT_FRIDAY = 1 << 5; + public static final int RECORDING_SEQUENCE_REPEAT_SATUREDAY = 1 << 6; + + private static final int RECORDING_SEQUENCE_REPEAT_MASK = + (RECORDING_SEQUENCE_REPEAT_SUNDAY | RECORDING_SEQUENCE_REPEAT_MONDAY | + RECORDING_SEQUENCE_REPEAT_TUESDAY | RECORDING_SEQUENCE_REPEAT_WEDNESDAY | + RECORDING_SEQUENCE_REPEAT_THURSDAY | RECORDING_SEQUENCE_REPEAT_FRIDAY | + RECORDING_SEQUENCE_REPEAT_SATUREDAY); + + /** + * Create {@link TimerInfo} with the given information. + * + * @param dayOfMonth day of month + * @param monthOfYear month of year + * @param startTime start time in {@link Time} + * @param duration duration in {@link Duration} + * @param recordingSequence recording sequence. Use RECORDING_SEQUENCE_REPEAT_ONCE_ONLY for no + * repeat. Otherwise use combination of {@link #RECORDING_SEQUENCE_REPEAT_SUNDAY}, + * {@link #RECORDING_SEQUENCE_REPEAT_MONDAY}, + * {@link #RECORDING_SEQUENCE_REPEAT_TUESDAY}, + * {@link #RECORDING_SEQUENCE_REPEAT_WEDNESDAY}, + * {@link #RECORDING_SEQUENCE_REPEAT_THURSDAY}, + * {@link #RECORDING_SEQUENCE_REPEAT_FRIDAY}, + * {@link #RECORDING_SEQUENCE_REPEAT_SATUREDAY}. + * @return {@link TimerInfo}. + * @throw IllegalArgumentException if input value is invalid + */ + public static TimerInfo timerInfoOf(int dayOfMonth, int monthOfYear, Time startTime, + Duration duration, int recordingSequence) { + if (dayOfMonth < 0 || dayOfMonth > 31) { + throw new IllegalArgumentException( + "Day of month should be in range of [0, 31]:" + dayOfMonth); + } + if (monthOfYear < 1 || monthOfYear > 12) { + throw new IllegalArgumentException( + "Month of year should be in range of [1, 12]:" + monthOfYear); + } + checkTimeValue(startTime.mHour, startTime.mMinute); + checkDurationValue(duration.mHour, duration.mMinute); + // Recording sequence should use least 7 bits or no bits. + if ((recordingSequence != 0) + && ((recordingSequence & ~RECORDING_SEQUENCE_REPEAT_MASK) != 0)) { + throw new IllegalArgumentException( + "Invalid reecording sequence value:" + recordingSequence); + } + + return new TimerInfo(dayOfMonth, monthOfYear, startTime, duration, recordingSequence); + } + + /** + * Container basic timer information. It consists of the following fields. + *
+ * In order to create this from each source type, use one of helper method. + *
Usage + * Start one touch recording with the given recorder address and recorder source. + *
+ * Usage *
* HdmiTvClient tvClient = ....;
* // for own source.
* OwnSource ownSource = ownHdmiRecordSources.ownSource();
- * tvClient.startRecord(recorderAddress, ownSource);
+ * tvClient.startOneTouchRecord(recorderAddress, ownSource);
*
*/
- public void startRecord(int recorderAddress, HdmiRecordSources.RecordSource source) {
+ public void startOneTouchRecord(int recorderAddress, HdmiRecordSources.RecordSource source) {
try {
byte[] data = new byte[source.getDataSize(true)];
source.toByteArray(true, data, 0);
- mService.startRecord(recorderAddress, data);
+ mService.startOneTouchRecord(recorderAddress, data);
+ } catch (RemoteException e) {
+ Log.e(TAG, "failed to start record: ", e);
+ }
+ }
+
+ /**
+ * Start timer recording with the given recoder address and recorder source.
+ * + * Usage + *
+ * HdmiTvClient tvClient = ....; + * // create timer info + * TimerInfo timerInfo = HdmiTimerRecourdSources.timerInfoOf(...); + * // for digital source. + * DigitalServiceSource recordSource = HdmiRecordSources.ofDigitalService(...); + * // create timer recording source. + * TimerRecordSource source = HdmiTimerRecourdSources.ofDigitalSource(timerInfo, recordSource); + * tvClient.startTimerRecording(recorderAddress, source); + *+ */ + public void startTimerRecording(int recorderAddress, + HdmiTimerRecordSources.TimerRecordSource source) { + try { + byte[] data = new byte[source.getDataSize()]; + source.toByteArray(data, 0); + mService.startTimerRecording(recorderAddress, data); } catch (RemoteException e) { Log.e(TAG, "failed to start record: ", e); } diff --git a/core/java/android/hardware/hdmi/IHdmiControlService.aidl b/core/java/android/hardware/hdmi/IHdmiControlService.aidl index 6f3763b2d7597..53b8b3f153eb6 100644 --- a/core/java/android/hardware/hdmi/IHdmiControlService.aidl +++ b/core/java/android/hardware/hdmi/IHdmiControlService.aidl @@ -55,13 +55,14 @@ interface IHdmiControlService { void setArcMode(boolean enabled); void setOption(int option, int value); void setProhibitMode(boolean enabled); - oneway void setSystemAudioVolume(int oldIndex, int newIndex, int maxIndex); - oneway void setSystemAudioMute(boolean mute); + void setSystemAudioVolume(int oldIndex, int newIndex, int maxIndex); + void setSystemAudioMute(boolean mute); void setInputChangeListener(IHdmiInputChangeListener listener); List