Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4f9e21ee authored by Jungshik Jang's avatar Jungshik Jang Committed by Android (Google) Code Review
Browse files

Merge "Implement clear timer." into lmp-dev

parents af9a696b e5a9337e
Loading
Loading
Loading
Loading
+63 −4
Original line number Diff line number Diff line
@@ -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)
@@ -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);;
            }
+185 −9
Original line number Diff line number Diff line
@@ -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 &lt;Timer Status&gt;
     *        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) {
    }
}
+30 −4
Original line number Diff line number Diff line
@@ -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);
     * </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);
@@ -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);
            }
        };
    }
+7 −0
Original line number Diff line number Diff line
@@ -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
+6 −0
Original line number Diff line number Diff line
@@ -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();
Loading