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

Commit 61791075 authored by Jinsuk Kim's avatar Jinsuk Kim
Browse files

Delegate HdmiCecService method impl to HdmiCecDevice subclass

Most of the methods in the interface IHdmiCecService should be implemented
based on the device type. This CL makes a change such that the HdmiCecDevice
just has stub methods that should be overriden by subclasses.

Other changes:
  - Fixed a bug of <Inactive Source> not sending its physical address
    in its message body. Also the command should have been sent to TV
    only rather than broadcast.

  - Put back sendGiveDevicePowerStatus interface method. It allows the client
    to keep track of the other device(like TV) power status more closely.
    Devices goes through the status from standby -> transient to on -> on
    but the CEC spec doesn't require that they broacast it actively.

    The restored method can be used to let the playback device to get
    up-to-date power status of TV/display when it is booting up.

    This method should work the same across all the device types. So it was
    implemented in the service, not delegated to HdmiCecDevice.

  - Send <Report Physical Address> when a new logical device is registered,
    which is required by CEC spec: "it should report the association between
    its logical and physical address by broadcasting <Report Physical
    Address>

Change-Id: Iac1d2cf5783d947f2dcd6965a54670fbdb8e6a63
parent bd6c5577
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -11033,6 +11033,7 @@ package android.hardware.hdmi {
  public final class HdmiCecClient {
    method public boolean isTvOn();
    method public void sendActiveSource();
    method public void sendGiveDevicePowerStatus(int);
    method public void sendImageViewOn();
    method public void sendInactiveSource();
    method public void sendTextViewOn();
+16 −2
Original line number Diff line number Diff line
@@ -109,6 +109,20 @@ public final class HdmiCecClient {
        }
    }

    /**
     * Send &lt;Give Device Power Status&gt; message.
     *
     * @param address logical address of the device to send the message to, such as
     *        {@link HdmiCec#ADDR_TV}.
     */
    public void sendGiveDevicePowerStatus(int address) {
        try {
            mService.sendGiveDevicePowerStatus(mBinder, address);
        } catch (RemoteException e) {
            Log.e(TAG, "sendGiveDevicePowerStatus threw exception ", e);
        }
    }

    /**
     * Returns true if the TV or attached display is powered on.
     * <p>
+1 −0
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ interface IHdmiCecService {
    void sendInactiveSource(IBinder b);
    void sendImageViewOn(IBinder b);
    void sendTextViewOn(IBinder b);
    void sendGiveDevicePowerStatus(IBinder b, int address);
    boolean isTvOn(IBinder b);
    void sendMessage(IBinder b, in HdmiCecMessage message);
}
+39 −1
Original line number Diff line number Diff line
@@ -181,12 +181,50 @@ abstract class HdmiCecDevice {
        mIsActiveSource = state;
    }

    /**
     * Send &lt;Active Source&gt; command. The default implementation does nothing. Should be
     * overriden by subclass.
     */
    public void sendActiveSource(int physicalAddress) {
        logWarning("<Active Source> not valid for the device type: " + mType
                + " address:" + physicalAddress);
    }

    /**
     * Send &lt;Inactive Source&gt; command. The default implementation does nothing. Should be
     * overriden by subclass.
     */
    public void sendInactiveSource(int physicalAddress) {
        logWarning("<Inactive Source> not valid for the device type: " + mType
                + " address:" + physicalAddress);
    }

    /**
     * Send &lt;Image View On&gt; command. The default implementation does nothing. Should be
     * overriden by subclass.
     */
    public void sendImageViewOn() {
        logWarning("<Image View On> not valid for the device type: " + mType);
    }

    /**
     * Send &lt;Text View On&gt; command. The default implementation does nothing. Should be
     * overriden by subclass.
     */
    public void sendTextViewOn() {
        logWarning("<Text View On> not valid for the device type: " + mType);
    }

    /**
     * Check if the connected sink device is in powered-on state. The default implementation
     * simply returns false. Should be overriden by subclass to report the correct state.
     */
    public boolean isSinkDeviceOn() {
        Log.w(TAG, "Not valid for the device type: " + mType);
        logWarning("isSinkDeviceOn() not valid for the device type: " + mType);
        return false;
    }

    private void logWarning(String msg) {
        Log.w(TAG, msg);
    }
}
+34 −3
Original line number Diff line number Diff line
@@ -66,14 +66,11 @@ final class HdmiCecDevicePlayback extends HdmiCecDevice {
        // 1) Response for the queried power status request arrives. Update the status.
        // 2) Broadcast or direct <Standby> command from TV, which is sent as TV itself is going
        //    into standby mode too.
        // 3) Broadcast <Report Physical Address> command from TV, which is sent while it boots up.
        if (opcode == HdmiCec.MESSAGE_REPORT_POWER_STATUS) {
            mSinkDevicePowerStatus = params[0];
        } else if (srcAddress == HdmiCec.ADDR_TV) {
            if (opcode == HdmiCec.MESSAGE_STANDBY) {
                mSinkDevicePowerStatus = HdmiCec.POWER_STATUS_STANDBY;
            } else if (opcode == HdmiCec.MESSAGE_REPORT_PHYSICAL_ADDRESS) {
                mSinkDevicePowerStatus = HdmiCec.POWER_STATUS_ON;
            }
        }
        super.handleMessage(srcAddress, dstAddress, opcode, params);
@@ -95,4 +92,38 @@ final class HdmiCecDevicePlayback extends HdmiCecDevice {
    public boolean isSinkDeviceOn() {
        return mSinkDevicePowerStatus == HdmiCec.POWER_STATUS_ON;
    }

    @Override
    public void sendActiveSource(int physicalAddress) {
        setIsActiveSource(true);
        byte[] param = new byte[] {
                (byte) ((physicalAddress >> 8) & 0xff),
                (byte) (physicalAddress & 0xff)
        };
        getService().sendMessage(getType(), HdmiCec.ADDR_BROADCAST, HdmiCec.MESSAGE_ACTIVE_SOURCE,
                param);
    }

    @Override
    public void sendInactiveSource(int physicalAddress) {
        setIsActiveSource(false);
        byte[] param = new byte[] {
                (byte) ((physicalAddress >> 8) & 0xff),
                (byte) (physicalAddress & 0xff)
        };
        getService().sendMessage(getType(), HdmiCec.ADDR_TV, HdmiCec.MESSAGE_INACTIVE_SOURCE,
                param);
    }

    @Override
    public void sendImageViewOn() {
        getService().sendMessage(getType(), HdmiCec.ADDR_TV, HdmiCec.MESSAGE_IMAGE_VIEW_ON,
                HdmiCecService.EMPTY_PARAM);
    }

    @Override
    public void sendTextViewOn() {
        getService().sendMessage(getType(), HdmiCec.ADDR_TV, HdmiCec.MESSAGE_TEXT_VIEW_ON,
                HdmiCecService.EMPTY_PARAM);
    }
}
Loading