diff --git a/core/java/android/hardware/hdmi/HdmiControlManager.java b/core/java/android/hardware/hdmi/HdmiControlManager.java
index 55db1df5438d7..a4a3ac389a0da 100644
--- a/core/java/android/hardware/hdmi/HdmiControlManager.java
+++ b/core/java/android/hardware/hdmi/HdmiControlManager.java
@@ -42,7 +42,7 @@ public final class HdmiControlManager {
* Broadcast Action: Display OSD message.
*
Send when the service has a message to display on screen for events
* that need user's attention such as ARC status change.
- *
Always contains the extra fields {@link #EXTRA_MESSAGE}.
+ *
Always contains the extra fields {@link #EXTRA_MESSAGE_ID}.
*
Requires {@link android.Manifest.permission#HDMI_CEC} to receive.
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
@@ -141,13 +141,71 @@ public final class HdmiControlManager {
/** Timer recording type for external source. */
public static final int TIMER_RECORDING_TYPE_EXTERNAL = 3;
+ // --- Timer Status Data
+ /** [Timer Status Data/Media Info] - Media present and not protected. */
+ public static final int TIMER_STATUS_MEDIA_INFO_PRESENT_NOT_PROTECTED = 0x0;
+ /** [Timer Status Data/Media Info] - Media present, but protected. */
+ public static final int TIMER_STATUS_MEDIA_INFO_PRESENT_PROTECTED = 0x1;
+ /** [Timer Status Data/Media Info] - Media not present. */
+ public static final int TIMER_STATUS_MEDIA_INFO_NOT_PRESENT = 0x2;
+
+ /** [Timer Status Data/Programmed Info] - Enough space available for recording. */
+ public static final int TIMER_STATUS_PROGRAMMED_INFO_ENOUGH_SPACE = 0x8;
+ /** [Timer Status Data/Programmed Info] - Not enough space available for recording. */
+ public static final int TIMER_STATUS_PROGRAMMED_INFO_NOT_ENOUGH_SPACE = 0x9;
+ /** [Timer Status Data/Programmed Info] - Might not enough space available for recording. */
+ public static final int TIMER_STATUS_PROGRAMMED_INFO_MIGHT_NOT_ENOUGH_SPACE = 0xB;
+ /** [Timer Status Data/Programmed Info] - No media info available. */
+ public static final int TIMER_STATUS_PROGRAMMED_INFO_NO_MEDIA_INFO = 0xA;
+
+ /** [Timer Status Data/Not Programmed Error Info] - No free timer available. */
+ public static final int TIMER_STATUS_NOT_PROGRAMMED_NO_FREE_TIME = 0x1;
+ /** [Timer Status Data/Not Programmed Error Info] - Date out of range. */
+ public static final int TIMER_STATUS_NOT_PROGRAMMED_DATE_OUT_OF_RANGE = 0x2;
+ /** [Timer Status Data/Not Programmed Error Info] - Recording Sequence error. */
+ public static final int TIMER_STATUS_NOT_PROGRAMMED_INVALID_SEQUENCE = 0x3;
+ /** [Timer Status Data/Not Programmed Error Info] - Invalid External Plug Number. */
+ public static final int TIMER_STATUS_NOT_PROGRAMMED_INVALID_EXTERNAL_PLUG_NUMBER = 0x4;
+ /** [Timer Status Data/Not Programmed Error Info] - Invalid External Physical Address. */
+ public static final int TIMER_STATUS_NOT_PROGRAMMED_INVALID_EXTERNAL_PHYSICAL_NUMBER = 0x5;
+ /** [Timer Status Data/Not Programmed Error Info] - CA system not supported. */
+ public static final int TIMER_STATUS_NOT_PROGRAMMED_CA_NOT_SUPPORTED = 0x6;
+ /** [Timer Status Data/Not Programmed Error Info] - No or insufficient CA Entitlements. */
+ public static final int TIMER_STATUS_NOT_PROGRAMMED_NO_CA_ENTITLEMENTS = 0x7;
+ /** [Timer Status Data/Not Programmed Error Info] - Does not support resolution. */
+ public static final int TIMER_STATUS_NOT_PROGRAMMED_UNSUPPORTED_RESOLUTION = 0x8;
+ /** [Timer Status Data/Not Programmed Error Info] - Parental Lock On. */
+ public static final int TIMER_STATUS_NOT_PROGRAMMED_PARENTAL_LOCK_ON= 0x9;
+ /** [Timer Status Data/Not Programmed Error Info] - Clock Failure. */
+ public static final int TIMER_STATUS_NOT_PROGRAMMED_CLOCK_FAILURE = 0xA;
+ /** [Timer Status Data/Not Programmed Error Info] - Duplicate: already programmed. */
+ public static final int TIMER_STATUS_NOT_PROGRAMMED_DUPLICATED = 0xE;
+
// --- Extra result value for timer recording.
+ /** No extra error. */
+ public static final int TIMER_RECORDING_RESULT_EXTRA_NO_ERROR = 0x00;
/** No timer recording - check recorder and connection. */
- public static final int TIME_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION = 0x01;
+ public static final int TIMER_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION = 0x01;
/** No timer recording - cannot record selected source. */
- public static final int TIME_RECORDING_RESULT_EXTRA_FAIL_TO_RECORD_SELECTED_SOURCE = 0x02;
+ public static final int TIMER_RECORDING_RESULT_EXTRA_FAIL_TO_RECORD_SELECTED_SOURCE = 0x02;
/** CEC is disabled. */
- public static final int TIME_RECORDING_RESULT_EXTRA_CEC_DISABLED = 0x33;
+ public static final int TIMER_RECORDING_RESULT_EXTRA_CEC_DISABLED = 0x03;
+
+ // -- Timer cleared status data code used for result of onClearTimerRecordingResult.
+ /** Timer not cleared – recording. */
+ public static final int CLEAR_TIMER_STATUS_TIMER_NOT_CLEARED_RECORDING = 0x00;
+ /** Timer not cleared – no matching. */
+ public static final int CLEAR_TIMER_STATUS_TIMER_NOT_CLEARED_NO_MATCHING = 0x01;
+ /** Timer not cleared – no info available. */
+ public static final int CLEAR_TIMER_STATUS_TIMER_NOT_CLEARED_NO_INFO_AVAILABLE = 0x02;
+ /** Timer cleared. */
+ public static final int CLEAR_TIMER_STATUS_TIMER_CLEARED = 0x80;
+ /** Clear timer error - check recorder and connection. */
+ public static final int CLEAR_TIMER_STATUS_CHECK_RECORDER_CONNECTION = 0xA0;
+ /** Clear timer error - cannot clear timer for selected source. */
+ public static final int CLEAR_TIMER_STATUS_FAIL_TO_CLEAR_SELECTED_SOURCE = 0xA1;
+ /** Clear timer error - CEC is disabled. */
+ public static final int CLEAR_TIMER_STATUS_CEC_DISABLE = 0xA2;
// True if we have a logical device of type playback hosted in the system.
private final boolean mHasPlaybackDevice;
@@ -281,6 +339,7 @@ public final class HdmiControlManager {
private IHdmiHotplugEventListener getHotplugEventListenerWrapper(
final HotplugEventListener listener) {
return new IHdmiHotplugEventListener.Stub() {
+ @Override
public void onReceived(HdmiHotplugEvent event) {
listener.onReceived(event);;
}
diff --git a/core/java/android/hardware/hdmi/HdmiRecordListener.java b/core/java/android/hardware/hdmi/HdmiRecordListener.java
index 0b1166b7c0d7c..fe44bd9f1c2c7 100644
--- a/core/java/android/hardware/hdmi/HdmiRecordListener.java
+++ b/core/java/android/hardware/hdmi/HdmiRecordListener.java
@@ -53,15 +53,191 @@ public abstract class HdmiRecordListener {
/**
* Called when timer recording is started or failed during initialization.
*
- * @param result The most significant three bytes may contain result of <Timer Status>
- * while the least significant byte may have error message like
- * {@link HdmiControlManager#TIME_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION}
- * or
- * {@link HdmiControlManager #TIME_RECORDING_RESULT_EXTRA_FAIL_TO_RECORD_SELECTED_SOURCE}
- * . If the least significant byte has non zero value the most significant three bytes
- * may have 0 value.
+ * @param data timer status data. For more details, look at {@link TimerStatusData}.
*/
- // TODO: implement result parser.
- public void onTimerRecordingResult(int result) {
+ public void onTimerRecordingResult(TimerStatusData data) {
+ }
+
+ /**
+ * [Timer overlap warning] [Media Info] [Timer Programmed Info]
+ * @hide
+ */
+ @SystemApi
+ public static class TimerStatusData {
+ private boolean mOverlapped;
+ private int mMediaInfo;
+ private boolean mProgrammed;
+
+ private int mProgrammedInfo;
+ private int mNotProgrammedError;
+ private int mDurationHour;
+ private int mDurationMinute;
+
+ private int mExtraError;
+
+ static TimerStatusData parseFrom(int result) {
+ TimerStatusData data = new TimerStatusData();
+ // Timer Overlap Warning - 1 bit
+ data.mOverlapped = ((result >> 31) & 0x1) != 0;
+ // Media Info - 2 bits;
+ data.mMediaInfo = (result >> 29) & 0x7;
+ // Programmed Indicator - 1 bit;
+ data.mProgrammed = ((result >> 28) & 0x1) != 0;
+ if (data.mProgrammed) {
+ data.mProgrammedInfo = (result >> 24) & 0xF;
+ data.mDurationHour = bcdByteToInt((byte) ((result >> 16) & 0xFF));
+ data.mDurationMinute = bcdByteToInt((byte) ((result >> 8) & 0xFF));
+ } else {
+ data.mNotProgrammedError = (result >> 24) & 0xF;
+ data.mDurationHour = bcdByteToInt((byte) ((result >> 16) & 0xFF));
+ data.mDurationMinute = bcdByteToInt((byte) ((result >> 8) & 0xFF));
+ }
+
+ // Programmed Info - 4 bits
+ data.mExtraError = result & 0xFF;
+ return data;
+ }
+
+ // Most significant 4 bits is used for 10 digits and
+ // Least significant 4 bits is used for 1 digits.
+ private static int bcdByteToInt(byte value) {
+ return ((value >> 4) & 0xF) * 10 + value & 0xF;
+ }
+
+ private TimerStatusData() {}
+
+ /**
+ * Indicates if there is another timer block already set which overlaps with this new
+ * recording request.
+ */
+ public boolean isOverlapped() {
+ return mOverlapped;
+ }
+
+ /**
+ * Indicates if removable media is present and its write protect state.
+ * It should be one of the following values.
+ *
+ * - {@link HdmiControlManager#TIMER_STATUS_MEDIA_INFO_PRESENT_NOT_PROTECTED}
+ *
- {@link HdmiControlManager#TIMER_STATUS_MEDIA_INFO_PRESENT_PROTECTED}
+ *
- {@link HdmiControlManager#TIMER_STATUS_MEDIA_INFO_NOT_PRESENT}
+ *
+ */
+ public int getMediaInfo() {
+ return mMediaInfo;
+ }
+
+ /**
+ * Selector for [Timer Programmed Info].
+ * If it is {@code true}, {@link #getProgrammedInfo()} would have meaningful value and
+ * ignore result of {@link #getNotProgammedError()}.
+ */
+ public boolean isProgrammed() {
+ return mProgrammed;
+ }
+
+ /**
+ * Information indicating any non-fatal issues with the programming request.
+ * It's set only if {@link #isProgrammed()} returns true.
+ * It should be one of the following values.
+ *
+ * - {@link HdmiControlManager#TIMER_STATUS_PROGRAMMED_INFO_ENOUGH_SPACE}
+ *
- {@link HdmiControlManager#TIMER_STATUS_PROGRAMMED_INFO_NOT_ENOUGH_SPACE}
+ *
- {@link HdmiControlManager#TIMER_STATUS_PROGRAMMED_INFO_MIGHT_NOT_ENOUGH_SPACE}
+ *
- {@link HdmiControlManager#TIMER_STATUS_PROGRAMMED_INFO_NO_MEDIA_INFO}
+ *
+ *
+ * @throw {@link IllegalStateException} if it's called when {@link #isProgrammed()}
+ * returns false
+ */
+ public int getProgrammedInfo() {
+ if (!isProgrammed()) {
+ throw new IllegalStateException(
+ "No programmed info. Call getNotProgammedError() instead.");
+ }
+ return mProgrammedInfo;
+ }
+
+ /**
+ * Information indicating any fatal issues with the programming request.
+ * It's set only if {@link #isProgrammed()} returns false.
+ * it should be one of the following values.
+ *
+ * - {@link HdmiControlManager#TIMER_STATUS_NOT_PROGRAMMED_NO_FREE_TIME}
+ *
- {@link HdmiControlManager#TIMER_STATUS_NOT_PROGRAMMED_DATE_OUT_OF_RANGE}
+ *
- {@link HdmiControlManager#TIMER_STATUS_NOT_PROGRAMMED_INVALID_SEQUENCE}
+ *
- {@link HdmiControlManager#TIMER_STATUS_NOT_PROGRAMMED_INVALID_EXTERNAL_PHYSICAL_NUMBER}
+ *
- {@link HdmiControlManager#TIMER_STATUS_NOT_PROGRAMMED_CA_NOT_SUPPORTED}
+ *
- {@link HdmiControlManager#TIMER_STATUS_NOT_PROGRAMMED_NO_CA_ENTITLEMENTS}
+ *
- {@link HdmiControlManager#TIMER_STATUS_NOT_PROGRAMMED_UNSUPPORTED_RESOLUTION}
+ *
- {@link HdmiControlManager#TIMER_STATUS_NOT_PROGRAMMED_PARENTAL_LOCK_ON}
+ *
- {@link HdmiControlManager#TIMER_STATUS_NOT_PROGRAMMED_CLOCK_FAILURE}
+ *
- {@link HdmiControlManager#TIMER_STATUS_NOT_PROGRAMMED_DUPLICATED}
+ *
+ *
+ * @throw {@link IllegalStateException} if it's called when {@link #isProgrammed()}
+ * returns true
+ */
+ public int getNotProgammedError() {
+ if (isProgrammed()) {
+ throw new IllegalStateException(
+ "Has no not-programmed error. Call getProgrammedInfo() instead.");
+ }
+ return mNotProgrammedError;
+ }
+
+ /**
+ * Duration hours.
+ * Optional parameter: Contains an estimate of the space left on the media, expressed as a
+ * time. This parameter may be returned when:
+ * - [Programmed Info] is “Not enough space available”; or
+ * - [Not Programmed Info] is “Duplicate: already programmed”
+ */
+ public int getDurationHour() {
+ return mDurationHour;
+ }
+
+ /**
+ * Duration minutes.
+ * Optional parameter: Contains an estimate of the space left on the media, expressed as a
+ * time. This parameter may be returned when:
+ * - [Programmed Info] is “Not enough space available”; or
+ * - [Not Programmed Info] is “Duplicate: already programmed”
+ */
+ public int getDurationMinute() {
+ return mDurationMinute;
+ }
+
+ /**
+ * Extra error code.
+ *
+ * - {@link HdmiControlManager#TIMER_RECORDING_RESULT_EXTRA_NO_ERROR}
+ * No extra errors. Other values of this class might be available.
+ *
- {@link HdmiControlManager#TIMER_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION}
+ * Check record connection. Other values of this class should be ignored.
+ *
- {@link HdmiControlManager#TIMER_RECORDING_RESULT_EXTRA_FAIL_TO_RECORD_SELECTED_SOURCE}
+ * Fail to record selected source. Other values of this class should be ignored.
+ *
- {@link HdmiControlManager#TIMER_RECORDING_RESULT_EXTRA_CEC_DISABLED}
+ * Cec disabled. Other values of this class should be ignored.
+ *
+ */
+ public int getExtraError() {
+ return mExtraError;
+ }
+ }
+
+ /**
+ * Called when receiving result for clear timer recording request.
+ *
+ * @param result result of clear timer. It should be one of
+ * {@link HdmiControlManager#CLEAR_TIMER_STATUS_TIMER_NOT_CLEARED_RECORDING}
+ * {@link HdmiControlManager#CLEAR_TIMER_STATUS_TIMER_NOT_CLEARED_NO_MATCHING},
+ * {@link HdmiControlManager#CLEAR_TIMER_STATUS_TIMER_NOT_CLEARED_NO_INFO_AVAILABLE},
+ * {@link HdmiControlManager#CLEAR_TIMER_STATUS_TIMER_CLEARED},
+ * {@link HdmiControlManager#CLEAR_TIMER_STATUS_CHECK_RECORDER_CONNECTION},
+ * {@link HdmiControlManager#CLEAR_TIMER_STATUS_FAIL_TO_CLEAR_SELECTED_SOURCE},
+ * {@link HdmiControlManager#CLEAR_TIMER_STATUS_CEC_DISABLE}.
+ */
+ public void onClearTimerRecordingResult(int result) {
}
}
diff --git a/core/java/android/hardware/hdmi/HdmiTvClient.java b/core/java/android/hardware/hdmi/HdmiTvClient.java
index 34362871e230c..2735108a35034 100644
--- a/core/java/android/hardware/hdmi/HdmiTvClient.java
+++ b/core/java/android/hardware/hdmi/HdmiTvClient.java
@@ -15,6 +15,7 @@
*/
package android.hardware.hdmi;
+import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.hardware.hdmi.HdmiRecordSources.RecordSource;
import android.hardware.hdmi.HdmiTimerRecordSources.TimerRecordSource;
@@ -116,7 +117,11 @@ public final class HdmiTvClient extends HdmiClient {
* @param logicalAddress
* @param callback
*/
- public void deviceSelect(int logicalAddress, SelectCallback callback) {
+ public void deviceSelect(int logicalAddress, @NonNull SelectCallback callback) {
+ if (callback == null) {
+ throw new IllegalArgumentException("callback must not be null.");
+ }
+
// TODO: Replace SelectCallback with PartialResult.
try {
mService.deviceSelect(logicalAddress, getCallbackWrapper(callback));
@@ -158,7 +163,10 @@ public final class HdmiTvClient extends HdmiClient {
*
* @param listener
*/
- public void setRecordListener(HdmiRecordListener listener) {
+ public void setRecordListener(@NonNull HdmiRecordListener listener) {
+ if (listener == null) {
+ throw new IllegalArgumentException("listener must not be null.");
+ }
try {
mService.setHdmiRecordListener(getListenerWrapper(listener));
} catch (RemoteException e) {
@@ -177,7 +185,11 @@ public final class HdmiTvClient extends HdmiClient {
* tvClient.startOneTouchRecord(recorderAddress, ownSource);
*
*/
- public void startOneTouchRecord(int recorderAddress, RecordSource source) {
+ public void startOneTouchRecord(int recorderAddress, @NonNull RecordSource source) {
+ if (source == null) {
+ throw new IllegalArgumentException("source must not be null.");
+ }
+
try {
byte[] data = new byte[source.getDataSize(true)];
source.toByteArray(true, data, 0);
@@ -223,6 +235,10 @@ public final class HdmiTvClient extends HdmiClient {
* @param source record source to be used
*/
public void startTimerRecording(int recorderAddress, int sourceType, TimerRecordSource source) {
+ if (source == null) {
+ throw new IllegalArgumentException("source must not be null.");
+ }
+
checkTimerRecordingSourceType(sourceType);
try {
@@ -250,6 +266,10 @@ public final class HdmiTvClient extends HdmiClient {
* For more details, please refer {@link #startTimerRecording(int, int, TimerRecordSource)}.
*/
public void clearTimerRecording(int recorderAddress, int sourceType, TimerRecordSource source) {
+ if (source == null) {
+ throw new IllegalArgumentException("source must not be null.");
+ }
+
checkTimerRecordingSourceType(sourceType);
try {
byte[] data = new byte[source.getDataSize()];
@@ -290,7 +310,13 @@ public final class HdmiTvClient extends HdmiClient {
@Override
public void onTimerRecordingResult(int result) {
- callback.onTimerRecordingResult(result);
+ callback.onTimerRecordingResult(
+ HdmiRecordListener.TimerStatusData.parseFrom(result));
+ }
+
+ @Override
+ public void onClearTimerRecordingResult(int result) {
+ callback.onClearTimerRecordingResult(result);
}
};
}
diff --git a/core/java/android/hardware/hdmi/IHdmiRecordListener.aidl b/core/java/android/hardware/hdmi/IHdmiRecordListener.aidl
index fba4b054996d8..44d9065837219 100644
--- a/core/java/android/hardware/hdmi/IHdmiRecordListener.aidl
+++ b/core/java/android/hardware/hdmi/IHdmiRecordListener.aidl
@@ -36,7 +36,14 @@ package android.hardware.hdmi;
void onOneTouchRecordResult(int result);
/**
* Called when timer recording is started or failed during initialization.
+
* @param result result code for timer recording
*/
void onTimerRecordingResult(int result);
+ /**
+ * Called when receiving result for clear timer recording request.
+ *
+ * @param result result of clear timer.
+ */
+ void onClearTimerRecordingResult(int result);
}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
index aedd632dcc3e7..7b382c63f9221 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
@@ -240,6 +240,8 @@ abstract class HdmiCecLocalDevice {
return handleSetOsdName(message);
case Constants.MESSAGE_RECORD_TV_SCREEN:
return handleRecordTvScreen(message);
+ case Constants.MESSAGE_TIMER_CLEARED_STATUS:
+ return handleTimerClearedStatus(message);
default:
return false;
}
@@ -451,6 +453,10 @@ abstract class HdmiCecLocalDevice {
return true;
}
+ protected boolean handleTimerClearedStatus(HdmiCecMessage message) {
+ return false;
+ }
+
@ServiceThreadOnly
final void handleAddressAllocated(int logicalAddress, boolean fromBootup) {
assertRunOnServiceThread();
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index a4550a2b3b709..8b2ed93fce908 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -16,12 +16,18 @@
package com.android.server.hdmi;
+import static android.hardware.hdmi.HdmiControlManager.CLEAR_TIMER_STATUS_CEC_DISABLE;
+import static android.hardware.hdmi.HdmiControlManager.CLEAR_TIMER_STATUS_CHECK_RECORDER_CONNECTION;
+import static android.hardware.hdmi.HdmiControlManager.CLEAR_TIMER_STATUS_FAIL_TO_CLEAR_SELECTED_SOURCE;
import static android.hardware.hdmi.HdmiControlManager.ONE_TOUCH_RECORD_CEC_DISABLED;
import static android.hardware.hdmi.HdmiControlManager.ONE_TOUCH_RECORD_CHECK_RECORDER_CONNECTION;
import static android.hardware.hdmi.HdmiControlManager.ONE_TOUCH_RECORD_FAIL_TO_RECORD_DISPLAYED_SCREEN;
-import static android.hardware.hdmi.HdmiControlManager.TIME_RECORDING_RESULT_EXTRA_CEC_DISABLED;
-import static android.hardware.hdmi.HdmiControlManager.TIME_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION;
-import static android.hardware.hdmi.HdmiControlManager.TIME_RECORDING_RESULT_EXTRA_FAIL_TO_RECORD_SELECTED_SOURCE;
+import static android.hardware.hdmi.HdmiControlManager.TIMER_RECORDING_RESULT_EXTRA_CEC_DISABLED;
+import static android.hardware.hdmi.HdmiControlManager.TIMER_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION;
+import static android.hardware.hdmi.HdmiControlManager.TIMER_RECORDING_RESULT_EXTRA_FAIL_TO_RECORD_SELECTED_SOURCE;
+import static android.hardware.hdmi.HdmiControlManager.TIMER_RECORDING_TYPE_ANALOGUE;
+import static android.hardware.hdmi.HdmiControlManager.TIMER_RECORDING_TYPE_DIGITAL;
+import static android.hardware.hdmi.HdmiControlManager.TIMER_RECORDING_TYPE_EXTERNAL;
import android.content.Intent;
import android.hardware.hdmi.HdmiCecDeviceInfo;
@@ -41,6 +47,7 @@ import android.util.SparseArray;
import com.android.internal.annotations.GuardedBy;
import com.android.server.hdmi.DeviceDiscoveryAction.DeviceDiscoveryCallback;
import com.android.server.hdmi.HdmiAnnotations.ServiceThreadOnly;
+import com.android.server.hdmi.HdmiControlService.SendMessageCallback;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
@@ -876,6 +883,14 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
return true;
}
+ @Override
+ protected boolean handleTimerClearedStatus(HdmiCecMessage message) {
+ byte[] params = message.getParams();
+ int timerClearedStatusData = params[0];
+ announceTimerRecordingResult(timerClearedStatusData);
+ return true;
+ }
+
void announceOneTouchRecordResult(int result) {
mService.invokeOneTouchRecordResult(result);
}
@@ -1347,21 +1362,21 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
assertRunOnServiceThread();
if (!mService.isControlEnabled()) {
Slog.w(TAG, "Can not start one touch record. CEC control is disabled.");
- announceTimerRecordingResult(TIME_RECORDING_RESULT_EXTRA_CEC_DISABLED);
+ announceTimerRecordingResult(TIMER_RECORDING_RESULT_EXTRA_CEC_DISABLED);
return;
}
if (!checkRecorder(recorderAddress)) {
Slog.w(TAG, "Invalid recorder address:" + recorderAddress);
announceTimerRecordingResult(
- TIME_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION);
+ TIMER_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION);
return;
}
if (!checkTimerRecordingSource(sourceType, recordSource)) {
Slog.w(TAG, "Invalid record source." + Arrays.toString(recordSource));
announceTimerRecordingResult(
- TIME_RECORDING_RESULT_EXTRA_FAIL_TO_RECORD_SELECTED_SOURCE);
+ TIMER_RECORDING_RESULT_EXTRA_FAIL_TO_RECORD_SELECTED_SOURCE);
return;
}
@@ -1379,7 +1394,55 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
@ServiceThreadOnly
void clearTimerRecording(int recorderAddress, int sourceType, byte[] recordSource) {
assertRunOnServiceThread();
+ if (!mService.isControlEnabled()) {
+ Slog.w(TAG, "Can not start one touch record. CEC control is disabled.");
+ announceTimerRecordingResult(CLEAR_TIMER_STATUS_CEC_DISABLE);
+ return;
+ }
- // TODO: implement this.
+ if (!checkRecorder(recorderAddress)) {
+ Slog.w(TAG, "Invalid recorder address:" + recorderAddress);
+ announceTimerRecordingResult(CLEAR_TIMER_STATUS_CHECK_RECORDER_CONNECTION);
+ return;
+ }
+
+ if (!checkTimerRecordingSource(sourceType, recordSource)) {
+ Slog.w(TAG, "Invalid record source." + Arrays.toString(recordSource));
+ announceTimerRecordingResult(CLEAR_TIMER_STATUS_FAIL_TO_CLEAR_SELECTED_SOURCE);
+ return;
+ }
+
+ sendClearTimerMessage(recorderAddress, sourceType, recordSource);
+ }
+
+ private void sendClearTimerMessage(int recorderAddress, int sourceType, byte[] recordSource) {
+ HdmiCecMessage message = null;
+ switch (sourceType) {
+ case TIMER_RECORDING_TYPE_DIGITAL:
+ message = HdmiCecMessageBuilder.buildClearDigitalTimer(mAddress, recorderAddress,
+ recordSource);
+ break;
+ case TIMER_RECORDING_TYPE_ANALOGUE:
+ message = HdmiCecMessageBuilder.buildClearAnalogueTimer(mAddress, recorderAddress,
+ recordSource);
+ break;
+ case TIMER_RECORDING_TYPE_EXTERNAL:
+ message = HdmiCecMessageBuilder.buildClearExternalTimer(mAddress, recorderAddress,
+ recordSource);
+ break;
+ default:
+ Slog.w(TAG, "Invalid source type:" + recorderAddress);
+ announceTimerRecordingResult(CLEAR_TIMER_STATUS_FAIL_TO_CLEAR_SELECTED_SOURCE);
+ return;
+
+ }
+ mService.sendCecCommand(message, new SendMessageCallback() {
+ @Override
+ public void onSendCompleted(int error) {
+ if (error != Constants.SEND_RESULT_SUCCESS) {
+ announceTimerRecordingResult(CLEAR_TIMER_STATUS_FAIL_TO_CLEAR_SELECTED_SOURCE);
+ }
+ }
+ });
}
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 613ae4fb7ea20..435507de654c7 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -1315,7 +1315,19 @@ public final class HdmiControlService extends SystemService {
try {
mRecordListener.onTimerRecordingResult(result);
} catch (RemoteException e) {
- Slog.w(TAG, "Failed to call onOneTouchRecordResult.", e);
+ Slog.w(TAG, "Failed to call onTimerRecordingResult.", e);
+ }
+ }
+ }
+ }
+
+ void invokeClearTimerRecordingResult(int result) {
+ synchronized (mLock) {
+ if (mRecordListener != null) {
+ try {
+ mRecordListener.onClearTimerRecordingResult(result);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed to call onClearTimerRecordingResult.", e);
}
}
}
@@ -1356,11 +1368,6 @@ public final class HdmiControlService extends SystemService {
}
}
- private static boolean hasSameTopPort(int path1, int path2) {
- return (path1 & Constants.ROUTING_PATH_TOP_MASK)
- == (path2 & Constants.ROUTING_PATH_TOP_MASK);
- }
-
private HdmiCecLocalDeviceTv tv() {
return (HdmiCecLocalDeviceTv) mCecController.getLocalDevice(HdmiCecDeviceInfo.DEVICE_TV);
}
diff --git a/services/core/java/com/android/server/hdmi/TimerRecordingAction.java b/services/core/java/com/android/server/hdmi/TimerRecordingAction.java
index 1dc26f175ee67..0275853d0098b 100644
--- a/services/core/java/com/android/server/hdmi/TimerRecordingAction.java
+++ b/services/core/java/com/android/server/hdmi/TimerRecordingAction.java
@@ -16,10 +16,11 @@
package com.android.server.hdmi;
+import static android.hardware.hdmi.HdmiControlManager.TIMER_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION;
+import static android.hardware.hdmi.HdmiControlManager.TIMER_RECORDING_RESULT_EXTRA_FAIL_TO_RECORD_SELECTED_SOURCE;
import static android.hardware.hdmi.HdmiControlManager.TIMER_RECORDING_TYPE_ANALOGUE;
import static android.hardware.hdmi.HdmiControlManager.TIMER_RECORDING_TYPE_DIGITAL;
import static android.hardware.hdmi.HdmiControlManager.TIMER_RECORDING_TYPE_EXTERNAL;
-import static android.hardware.hdmi.HdmiControlManager.TIME_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION;
import android.util.Slog;
@@ -74,7 +75,7 @@ public class TimerRecordingAction extends FeatureAction {
break;
default:
tv().announceTimerRecordingResult(
- TIME_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION);
+ TIMER_RECORDING_RESULT_EXTRA_FAIL_TO_RECORD_SELECTED_SOURCE);
finish();
return;
}
@@ -138,7 +139,7 @@ public class TimerRecordingAction extends FeatureAction {
}
int reason = params[1];
Slog.i(TAG, "[Feature Abort] for " + messageType + " reason:" + reason);
- tv().announceTimerRecordingResult(TIME_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION);
+ tv().announceTimerRecordingResult(TIMER_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION);
finish();
return true;
}
@@ -163,7 +164,7 @@ public class TimerRecordingAction extends FeatureAction {
return;
}
- tv().announceTimerRecordingResult(TIME_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION);
+ tv().announceTimerRecordingResult(TIMER_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION);
finish();
}
}