Loading core/java/android/hardware/hdmi/HdmiControlManager.java +63 −4 Original line number Diff line number Diff line Loading @@ -42,7 +42,7 @@ public final class HdmiControlManager { * Broadcast Action: Display OSD message. * <p>Send when the service has a message to display on screen for events * that need user's attention such as ARC status change. * <p>Always contains the extra fields {@link #EXTRA_MESSAGE}. * <p>Always contains the extra fields {@link #EXTRA_MESSAGE_ID}. * <p>Requires {@link android.Manifest.permission#HDMI_CEC} to receive. */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) Loading Loading @@ -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; Loading Loading @@ -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);; } Loading core/java/android/hardware/hdmi/HdmiRecordListener.java +185 −9 Original line number Diff line number Diff line Loading @@ -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. * <ul> * <li>{@link HdmiControlManager#TIMER_STATUS_MEDIA_INFO_PRESENT_NOT_PROTECTED} * <li>{@link HdmiControlManager#TIMER_STATUS_MEDIA_INFO_PRESENT_PROTECTED} * <li>{@link HdmiControlManager#TIMER_STATUS_MEDIA_INFO_NOT_PRESENT} * </ul> */ 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. * <ul> * <li>{@link HdmiControlManager#TIMER_STATUS_PROGRAMMED_INFO_ENOUGH_SPACE} * <li>{@link HdmiControlManager#TIMER_STATUS_PROGRAMMED_INFO_NOT_ENOUGH_SPACE} * <li>{@link HdmiControlManager#TIMER_STATUS_PROGRAMMED_INFO_MIGHT_NOT_ENOUGH_SPACE} * <li>{@link HdmiControlManager#TIMER_STATUS_PROGRAMMED_INFO_NO_MEDIA_INFO} * </ul> * * @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. * <ul> * <li>{@link HdmiControlManager#TIMER_STATUS_NOT_PROGRAMMED_NO_FREE_TIME} * <li>{@link HdmiControlManager#TIMER_STATUS_NOT_PROGRAMMED_DATE_OUT_OF_RANGE} * <li>{@link HdmiControlManager#TIMER_STATUS_NOT_PROGRAMMED_INVALID_SEQUENCE} * <li>{@link HdmiControlManager#TIMER_STATUS_NOT_PROGRAMMED_INVALID_EXTERNAL_PHYSICAL_NUMBER} * <li>{@link HdmiControlManager#TIMER_STATUS_NOT_PROGRAMMED_CA_NOT_SUPPORTED} * <li>{@link HdmiControlManager#TIMER_STATUS_NOT_PROGRAMMED_NO_CA_ENTITLEMENTS} * <li>{@link HdmiControlManager#TIMER_STATUS_NOT_PROGRAMMED_UNSUPPORTED_RESOLUTION} * <li>{@link HdmiControlManager#TIMER_STATUS_NOT_PROGRAMMED_PARENTAL_LOCK_ON} * <li>{@link HdmiControlManager#TIMER_STATUS_NOT_PROGRAMMED_CLOCK_FAILURE} * <li>{@link HdmiControlManager#TIMER_STATUS_NOT_PROGRAMMED_DUPLICATED} * </ul> * * @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. * <ul> * <li>{@link HdmiControlManager#TIMER_RECORDING_RESULT_EXTRA_NO_ERROR} * No extra errors. Other values of this class might be available. * <li>{@link HdmiControlManager#TIMER_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION} * Check record connection. Other values of this class should be ignored. * <li>{@link HdmiControlManager#TIMER_RECORDING_RESULT_EXTRA_FAIL_TO_RECORD_SELECTED_SOURCE} * Fail to record selected source. Other values of this class should be ignored. * <li>{@link HdmiControlManager#TIMER_RECORDING_RESULT_EXTRA_CEC_DISABLED} * Cec disabled. Other values of this class should be ignored. * </ul> */ 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) { } } core/java/android/hardware/hdmi/HdmiTvClient.java +30 −4 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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)); Loading Loading @@ -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) { Loading @@ -177,7 +185,11 @@ public final class HdmiTvClient extends HdmiClient { * tvClient.startOneTouchRecord(recorderAddress, ownSource); * </pre> */ 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); Loading Loading @@ -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 { Loading Loading @@ -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()]; Loading Loading @@ -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); } }; } Loading core/java/android/hardware/hdmi/IHdmiRecordListener.aidl +7 −0 Original line number Diff line number Diff line Loading @@ -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 services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java +6 −0 Original line number Diff line number Diff line Loading @@ -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; } Loading Loading @@ -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(); Loading Loading
core/java/android/hardware/hdmi/HdmiControlManager.java +63 −4 Original line number Diff line number Diff line Loading @@ -42,7 +42,7 @@ public final class HdmiControlManager { * Broadcast Action: Display OSD message. * <p>Send when the service has a message to display on screen for events * that need user's attention such as ARC status change. * <p>Always contains the extra fields {@link #EXTRA_MESSAGE}. * <p>Always contains the extra fields {@link #EXTRA_MESSAGE_ID}. * <p>Requires {@link android.Manifest.permission#HDMI_CEC} to receive. */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) Loading Loading @@ -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; Loading Loading @@ -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);; } Loading
core/java/android/hardware/hdmi/HdmiRecordListener.java +185 −9 Original line number Diff line number Diff line Loading @@ -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. * <ul> * <li>{@link HdmiControlManager#TIMER_STATUS_MEDIA_INFO_PRESENT_NOT_PROTECTED} * <li>{@link HdmiControlManager#TIMER_STATUS_MEDIA_INFO_PRESENT_PROTECTED} * <li>{@link HdmiControlManager#TIMER_STATUS_MEDIA_INFO_NOT_PRESENT} * </ul> */ 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. * <ul> * <li>{@link HdmiControlManager#TIMER_STATUS_PROGRAMMED_INFO_ENOUGH_SPACE} * <li>{@link HdmiControlManager#TIMER_STATUS_PROGRAMMED_INFO_NOT_ENOUGH_SPACE} * <li>{@link HdmiControlManager#TIMER_STATUS_PROGRAMMED_INFO_MIGHT_NOT_ENOUGH_SPACE} * <li>{@link HdmiControlManager#TIMER_STATUS_PROGRAMMED_INFO_NO_MEDIA_INFO} * </ul> * * @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. * <ul> * <li>{@link HdmiControlManager#TIMER_STATUS_NOT_PROGRAMMED_NO_FREE_TIME} * <li>{@link HdmiControlManager#TIMER_STATUS_NOT_PROGRAMMED_DATE_OUT_OF_RANGE} * <li>{@link HdmiControlManager#TIMER_STATUS_NOT_PROGRAMMED_INVALID_SEQUENCE} * <li>{@link HdmiControlManager#TIMER_STATUS_NOT_PROGRAMMED_INVALID_EXTERNAL_PHYSICAL_NUMBER} * <li>{@link HdmiControlManager#TIMER_STATUS_NOT_PROGRAMMED_CA_NOT_SUPPORTED} * <li>{@link HdmiControlManager#TIMER_STATUS_NOT_PROGRAMMED_NO_CA_ENTITLEMENTS} * <li>{@link HdmiControlManager#TIMER_STATUS_NOT_PROGRAMMED_UNSUPPORTED_RESOLUTION} * <li>{@link HdmiControlManager#TIMER_STATUS_NOT_PROGRAMMED_PARENTAL_LOCK_ON} * <li>{@link HdmiControlManager#TIMER_STATUS_NOT_PROGRAMMED_CLOCK_FAILURE} * <li>{@link HdmiControlManager#TIMER_STATUS_NOT_PROGRAMMED_DUPLICATED} * </ul> * * @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. * <ul> * <li>{@link HdmiControlManager#TIMER_RECORDING_RESULT_EXTRA_NO_ERROR} * No extra errors. Other values of this class might be available. * <li>{@link HdmiControlManager#TIMER_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION} * Check record connection. Other values of this class should be ignored. * <li>{@link HdmiControlManager#TIMER_RECORDING_RESULT_EXTRA_FAIL_TO_RECORD_SELECTED_SOURCE} * Fail to record selected source. Other values of this class should be ignored. * <li>{@link HdmiControlManager#TIMER_RECORDING_RESULT_EXTRA_CEC_DISABLED} * Cec disabled. Other values of this class should be ignored. * </ul> */ 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) { } }
core/java/android/hardware/hdmi/HdmiTvClient.java +30 −4 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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)); Loading Loading @@ -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) { Loading @@ -177,7 +185,11 @@ public final class HdmiTvClient extends HdmiClient { * tvClient.startOneTouchRecord(recorderAddress, ownSource); * </pre> */ 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); Loading Loading @@ -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 { Loading Loading @@ -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()]; Loading Loading @@ -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); } }; } Loading
core/java/android/hardware/hdmi/IHdmiRecordListener.aidl +7 −0 Original line number Diff line number Diff line Loading @@ -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
services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java +6 −0 Original line number Diff line number Diff line Loading @@ -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; } Loading Loading @@ -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(); Loading