Adapt the mixer demo to use kuksa.val service 60/28160/1
authorRoger Zanoni <rzanoni@igalia.com>
Fri, 11 Nov 2022 15:53:15 +0000 (16:53 +0100)
committerRoger Zanoni <rzanoni@igalia.com>
Fri, 11 Nov 2022 15:54:34 +0000 (16:54 +0100)
Bug-AGL: SPEC-4599
Signed-off-by: Roger Zanoni <rzanoni@igalia.com>
Change-Id: If8308d3402c11ac3acc7dc11c11ed042f014b87e

src/index.html
src/index.js
src/js/agl_stubs_audiomixer.js [deleted file]
src/js/app.js
src/js/kuksa.js [new file with mode: 0644]
src/js/paths.js [new file with mode: 0644]
src/js/volume.js [moved from src/js/sliders.js with 52% similarity]
webpack.config.js

index 5095354..c12b13e 100644 (file)
                     <div class="label">
                         {{ name }}: <span class="value"> {{ value }}%</span>
                     </div>
-                    <a class="button" onclick="window.decrease(this);">
+                    <a id="decrease-{{id}}" class="button" onclick="VOLUME.decrease(this);">
                         <span class="icon-volume-decrease"></span>
                     </a>
                     <div class="slider">
-                        <input type="range" min="1" value="{{ value }}" max="100" oninput="window.change(this);">
+                        <input id="progress-{{id}}" type="range" min="1" value="{{ value }}" max="100" oninput="VOLUME.change(this);">
                         <progress value="{{ value }}" max="100"></progress>
                     </div>
-                    <a class="button" onclick="window.increase(this);">
+                    <a id="increase-{{id}}" class="button" onclick="VOLUME.increase(this);">
                         <span class="icon-volume-increase"></span>
                     </a>
                 </div>
index 37b78c4..a022899 100644 (file)
 
 /* JS */
 import { init } from './js/app';
-import { increase, decrease, change } from './js/sliders';
 
 /* CSS */
 import './styles/app.scss';
 
+document.addEventListener('DOMContentLoaded', function(){
+    init();
 
-window.increase = increase;
-window.decrease = decrease;
-window.change = change;
-init();
\ No newline at end of file
+    KUKSA.init([
+        [PATHS.volume, VOLUME],
+    ], VOLUME.init);
+});
diff --git a/src/js/agl_stubs_audiomixer.js b/src/js/agl_stubs_audiomixer.js
deleted file mode 100644 (file)
index c5f8d2e..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-export function on_volume_changed() {
-}
-
-export function list_controls() {
-    return new Promise((result, reject) => {
-        result([
-            { control: "MAIN", volume: 0.5 }
-        ]);
-    });
-}
-
-export function set_volume() {
-}
index bfebf1c..9ad4ea1 100644 (file)
@@ -1,14 +1,17 @@
 import Mustache from 'mustache';
-import * as audiomixer from './agl_stubs_audiomixer';
-import { setValue } from './sliders';
 
 var template;
 
+var controls = [
+    { id: 'MAIN', name: 'Main', volume: 50 },
+];
+
 function render_sliders(sliders) {
     var sliderContainer = document.getElementById('SliderContainer');
     for( var i=0; i<sliders.length; i++) {
         var node = Mustache.render(template, sliders[i]);
         sliderContainer.innerHTML += node;
+        console.log(sliderContainer.innerHTML)
     }
 }
 
@@ -16,24 +19,5 @@ export function init() {
     template = document.getElementById('slider-template').innerHTML;
     Mustache.parse(template);
 
-    audiomixer.list_controls().then(function(result) {
-        var sliders =  [];
-       for( var i=0; i<result.length; i++) {
-            sliders.push({
-                id: result[i].control,
-                name: result[i].control,
-                value: Math.floor(result[i].volume*100)
-            });
-        }
-
-        render_sliders(sliders);
-    }).catch(function(error) {
-        console.error('ERROR loading sliders', error);
-    });
-
-    audiomixer.on_volume_changed(function(data){
-        setValue(document.getElementById("slider-"+data.control), Math.ceil(data.value*100), true);
-    }).then(function(result) {
-        console.log("SUBSCRIBED TO VOLUME CHANGED");
-    });
-}
\ No newline at end of file
+    render_sliders(controls);
+}
diff --git a/src/js/kuksa.js b/src/js/kuksa.js
new file mode 100644 (file)
index 0000000..bbd14fa
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2022 Igalia, S.L.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * 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 "AS IS" 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.
+ */
+
+import { v4 as uuidv4 } from 'uuid';
+
+const DEFAULT_TARGET = "wss://localhost:8090";
+
+// TODO: use an application token when needed
+// currently using https://github.com/eclipse/kuksa.val/blob/master/kuksa_certificates/jwt/super-admin.json.token
+const TEST_TOKEN = 
+    'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJrdWtzYS52YWwiLCJpc3MiOiJFY2xpcHNlIEtVS1NBIERldiIsImFkbWluIjp0cnVlLCJtb2RpZnlUcmVlIjp0cnVlLCJpYXQiOjE1MTYyMzkwMjIsImV4cCI6MTc2NzIyNTU5OSwia3Vrc2EtdnNzIjp7IioiOiJydyJ9fQ.p2cnFGH16QoQ14l6ljPVKggFXZKmD-vrw8G6Vs6DvAokjsUG8FHh-F53cMsE-GDjyZH_1_CrlDCnbGlqjsFbgAylqA7IAJWp9_N6dL5p8DHZTwlZ4IV8L1CtCALs7XVqvcQKHCCzB63Y8PgVDCAqpQSRb79JPVD4pZwkBKpOknfEY5y9wfbswZiRKdgz7o61_oFnd-yywpse-23HD6v0htThVF1SuGL1PuvGJ8p334nt9bpkZO3gaTh1xVD_uJMwHzbuBCF33_f-I5QMZO6bVooXqGfe1zvl3nDrPEjq1aPulvtP8RgREYEqE6b2hB8jouTiC_WpE3qrdMw9sfWGFbm04qC-2Zjoa1yYSXoxmYd0SnliSYHAad9aXoEmFENezQV-of7sc-NX1-2nAXRAEhaqh0IRuJwB4_sG7SvQmnanwkz-sBYxKqkoFpOsZ6hblgPDOPYY2NAsZlYkjvAL2mpiInrsmY_GzGsfwPeAx31iozImX75rao8rm-XucAmCIkRlpBz6MYKCjQgyRz3UtZCJ2DYF4lKqTjphEAgclbYZ7KiCuTn9HualwtEmVzHHFneHMKl7KnRQk-9wjgiyQ5nlsVpCCblg6JKr9of4utuPO3cBvbjhB4_ueQ40cpWVOICcOLS7_w0i3pCq1ZKDEMrYDJfz87r2sU9kw1zeFQk';
+
+var kuksa_context = {
+    authToken: TEST_TOKEN,
+    socket: undefined,
+    target: DEFAULT_TARGET,
+}
+
+var pathToHandler = null;
+
+function logReceivedMessage(data) {
+    console.log('Received message:', data)
+}
+
+function logConnectionStatus(status, event) {
+    console.log('Connection status:', status);
+}
+
+function kuksaws_onopen(event) {
+    logConnectionStatus('Connected.', event);
+
+    authorize();
+    subscribe(PATHS.volume);
+}
+
+function kuksaws_onerror(event) {
+    logConnectionStatus('Failed to connect:', event);
+}
+
+function kuksaws_onmessage(event) {
+    logReceivedMessage(event.data);
+
+    var jsonData = JSON.parse(event.data);
+
+    if (jsonData.action == 'get' ||
+        jsonData.action =='subscription') {
+        updateVehicleInfo(jsonData);
+    }
+}
+
+function updateVehicleInfo(message) {
+    var value = message.data.dp.value;
+    var path = message.data.path;
+
+    if (!pathToHandler.has(path)) {
+        console.log('Handler not found for', path);
+        return;
+    }
+
+    var handler = pathToHandler.get(path);
+    handler.update(path, value)
+}
+
+function send(action, values) {
+    var uuid = uuidv4();
+    var data = Object.assign({
+        action: action,
+        tokens: kuksa_context.authToken,
+        requestId: uuid,
+    }, values);
+    var message = JSON.stringify(data);
+    console.log('Sent message:', message);
+    kuksa_context.socket.send(message);
+    return uuid;
+}
+
+function subscribe(path) {
+    return send('subscribe', { path: path });
+}
+
+function authorize() {
+    return send('authorize');
+}
+
+export function get(path) {
+    return send('get', { path: path });
+}
+
+export function set(path, value) {
+    return send('set', { path: path, value: value });
+}
+
+export function init(handlers, onopen) {
+    pathToHandler = new Map(handlers);
+    if (kuksa_context.socket == undefined) {
+        kuksa_context.socket = new WebSocket(kuksa_context.target);
+        kuksa_context.socket.onopen = function() {
+            kuksaws_onopen();
+            if (onopen) {
+               onopen(); 
+            }
+        };
+        kuksa_context.socket.onerror = kuksaws_onerror;
+        kuksa_context.socket.onmessage = kuksaws_onmessage;
+    }
+}
diff --git a/src/js/paths.js b/src/js/paths.js
new file mode 100644 (file)
index 0000000..a065036
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2022 Igalia, S.L.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * 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 "AS IS" 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.
+ */
+
+//  https://github.com/COVESA/vehicle_signal_specification/blob/master/spec/Cabin/Infotainment.vspec
+export const volume = 'Vehicle.Cabin.Infotainment.Media.Volume';
similarity index 52%
rename from src/js/sliders.js
rename to src/js/volume.js
index 5b9191c..0bbb481 100644 (file)
@@ -1,11 +1,9 @@
-import * as audiomixer from './agl_stubs_audiomixer';
-
 function getRootNode(node) {
-    while(!node.hasAttribute('slider-id') && node.parentNode) {
+    while (!node.hasAttribute('slider-id') && node.parentNode) {
         return getRootNode(node.parentNode);
     }
 
-    if( node.hasAttribute('slider-id') ) {
+    if (node.hasAttribute('slider-id')) {
         return node;
     } else {
         return false;
@@ -14,35 +12,44 @@ function getRootNode(node) {
 
 function getValue(node) {
     node = getRootNode(node);
-    if( node ) {
+    if (node) {
         return parseInt(node.getAttribute('value'));
     } else {
         return false;
     }
 }
 
-export function setValue(node, value, notUpdate) {
+export function setValue(node, value) {
     node = getRootNode(node);
-    if( node ){
+    if (node) {
         value = Math.max(Math.min(value, 100), 0);
         node.setAttribute('value', value);
         node.getElementsByTagName('progress')[0].value = value;
         node.getElementsByTagName('input')[0].value = value;
         node.getElementsByClassName('value')[0].innerHTML = value+'%';
-        if( !notUpdate ) {
-            audiomixer.set_volume(node.getAttribute('slider-id'), value/100);
-        }
     }
 }
 
+// TODO: right now there's only one PATHS
+// if it gets update to use multiple volume controls
+// all the below functions need to be update to use
+// the correct paths/elements
 export function increase(node) {
-    setValue(node, getValue(node)+5);
+    KUKSA.set(PATHS.volume, getValue(node)+5);
 }
 
 export function decrease(node) {
-    setValue(node, getValue(node)-5);
+    KUKSA.set(PATHS.volume, getValue(node)-5);
 }
 
 export function change(node) {
-    setValue(node, node.value);
-}
\ No newline at end of file
+    KUKSA.set(PATHS.volume, node.value);
+}
+
+export function update(path, value) {
+    setValue(document.getElementById('progress-MAIN'), value);
+}
+
+export function init() {
+    KUKSA.set(PATHS.volume, 20);
+}
index 4bb79af..6a5c57c 100644 (file)
@@ -8,6 +8,9 @@ const CopyPlugin = require('copy-webpack-plugin');
 module.exports = {
     mode: 'production',
     entry: {
+        PATHS: './src/js/paths.js',
+        KUKSA: './src/js/kuksa.js',
+        VOLUME: './src/js/volume.js',
         index: './src/index.js'
     },
     output: {
@@ -90,4 +93,4 @@ module.exports = {
         compress: true,
         port: 9000
     }
-}; 
\ No newline at end of file
+};