Content of file CecClientAdapter.java.html

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><link rel="stylesheet" href="../../jacoco-resources/report.css" type="text/css"/><link rel="shortcut icon" href="../../jacoco-resources/report.gif" type="image/gif"/><title>CecClientAdapter.java</title><link rel="stylesheet" href="../../jacoco-resources/prettify.css" type="text/css"/><script type="text/javascript" src="../../jacoco-resources/prettify.js"></script></head><body onload="window['PR_TAB_WIDTH']=4;prettyPrint()"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../../jacoco-sessions.html" class="el_session">Sessions</a></span><a href="../../index.html" class="el_report">blueMarine II :: Application :: JavaFX</a> &gt; <a href="../index.html" class="el_bundle">it-tidalwave-cec</a> &gt; <a href="index.source.html" class="el_package">it.tidalwave.cec.impl</a> &gt; <span class="el_source">CecClientAdapter.java</span></div><h1>CecClientAdapter.java</h1><pre class="source lang-java linenums"><span class="nc" id="L1">/*</span>
 * *********************************************************************************************************************
 *
 * blueMarine II: Semantic Media Centre
 * http://tidalwave.it/projects/bluemarine2
 *
 * Copyright (C) 2015 - 2021 by Tidalwave s.a.s. (http://tidalwave.it)
 *
 * *********************************************************************************************************************
 *
 * Licensed under the Apache License, Version 2.0 (the &quot;License&quot;); 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 &quot;AS IS&quot; 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.
 *
 * *********************************************************************************************************************
 *
 * git clone https://bitbucket.org/tidalwave/bluemarine2-src
 * git clone https://github.com/tidalwave-it/bluemarine2-src
 *
 * *********************************************************************************************************************
 */
package it.tidalwave.cec.impl;

import javax.annotation.Nonnull;
import javax.inject.Inject;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.io.IOException;
import it.tidalwave.util.NotFoundException;
import it.tidalwave.util.ProcessExecutor;
import it.tidalwave.util.ProcessExecutor.ConsoleOutput;
import it.tidalwave.util.annotation.VisibleForTesting;
import it.tidalwave.util.spi.DefaultProcessExecutor;
import it.tidalwave.messagebus.MessageBus;
import it.tidalwave.messagebus.annotation.ListensTo;
import it.tidalwave.messagebus.annotation.SimpleMessageSubscriber;
import it.tidalwave.cec.CecEvent;
import it.tidalwave.cec.CecEvent.EventType;
import it.tidalwave.bluemarine2.message.PowerOnNotification;
import lombok.extern.slf4j.Slf4j;

/***********************************************************************************************************************
 *
 * An adapter that receives notifications from {@code cec-client} and forwards events to the message bus.
 *
 * @stereotype  Adapter
 *
 * @author  Fabrizio Giudici
 *
 **********************************************************************************************************************/
<span class="nc" id="L56">@SimpleMessageSubscriber @Slf4j</span>
<span class="nc" id="L57">public class CecClientAdapter</span>
  {
    private static final String CEC_REGEX = &quot;^TRAFFIC: *\\[ *([0-9]+)\\][ \\t&gt;]*([0-9A-Fa-f]+):([0-9A-Fa-f]+):([0-9A-Fa-f]+)$&quot;;

<span class="nc" id="L61">    private static final Pattern CEC_PATTERN = Pattern.compile(CEC_REGEX);</span>

    private ProcessExecutor executor;

    @Inject
    private MessageBus messageBus;

    /*******************************************************************************************************************
     *
     * Parses the output from {@code cec-client} and fires events.
     *
     ******************************************************************************************************************/
<span class="nc" id="L73">    private final ConsoleOutput.Listener listener = string -&gt;</span>
      {
<span class="nc" id="L75">        final Matcher matcher = CEC_PATTERN.matcher(string);</span>

<span class="nc bnc" id="L77" title="All 2 branches missed.">        if (matcher.matches())</span>
          {
<span class="nc" id="L79">            final int eventType = Integer.parseInt(matcher.group(3), 16);</span>
<span class="nc" id="L80">            final int keyCode = Integer.parseInt(matcher.group(4), 16);</span>

            try
              {
<span class="nc" id="L84">                final CecEvent event = EventType.forCode(eventType).createEvent(keyCode);</span>
<span class="nc" id="L85">                log.debug(&quot;Sending {}...&quot;, event);</span>
<span class="nc" id="L86">                messageBus.publish(event);</span>
              }
<span class="nc" id="L88">            catch (NotFoundException e)</span>
              {
                // 04:1a:01 - Give deck status
                // 04:90:00 - Report power status
                // 04:89:01 - Vendor specific data
<span class="nc" id="L93">                log.warn(&quot;Not found: {} / {}&quot;, string, e.getMessage());</span>
<span class="nc" id="L94">              }</span>
          }
<span class="nc" id="L96">      };</span>

    /*******************************************************************************************************************
     *
     * At power on runs {@code cec-client}.
     *
     ******************************************************************************************************************/
    @VisibleForTesting void onPowerOnReceived (@Nonnull @ListensTo final PowerOnNotification notification)
      {
        try
          {
<span class="nc" id="L107">            log.info(&quot;onPowerOnReceived({})&quot;, notification);</span>
<span class="nc" id="L108">            executor = DefaultProcessExecutor.forExecutable(&quot;/usr/bin/cec-client&quot;) // FIXME: path</span>
<span class="nc" id="L109">                                             .withArguments(&quot;-d&quot;, &quot;8&quot;, &quot;-t&quot;, &quot;p&quot;, &quot;-o&quot;, &quot;blueMarine&quot;)</span>
<span class="nc" id="L110">                                             .start();</span>
<span class="nc" id="L111">            executor.getStdout().setListener(listener);</span>
          }
<span class="nc" id="L113">        catch (IOException e)</span>
          {
<span class="nc" id="L115">            log.error(&quot;Cannot run cec-client: {}&quot;, e.toString());</span>
            // TODO: UI notification of the error
UI notification of the error
<span class="nc" id="L117"> }</span> <span class="nc" id="L118"> }</span> // TODO: kill executor on PowerOff? } </pre><div class="footer"><span class="right">Created with <a href="http://www.jacoco.org/jacoco">JaCoCo</a> 0.8.7.202105040129</span></div></body></html>