diff options
Diffstat (limited to 'launcher')
48 files changed, 1667 insertions, 0 deletions
diff --git a/launcher/README.md b/launcher/README.md new file mode 100644 index 0000000..4a80a6c --- /dev/null +++ b/launcher/README.md @@ -0,0 +1,10 @@ +AGL launcher reference implementation + + +Build with QtCreator 3.5.1 + +AGL repo for source code: +https://gerrit.automotivelinux.org/gerrit/#/admin/projects/apps/launcher + +AGL repo for bitbake recipe: +https://gerrit.automotivelinux.org/gerrit/apps/launcher diff --git a/launcher/launcher.pro b/launcher/launcher.pro new file mode 100644 index 0000000..cf36ae8 --- /dev/null +++ b/launcher/launcher.pro @@ -0,0 +1,41 @@ +# Copyright (C) 2016, 2017 Mentor Graphics Development (Deutschland) GmbH +# Copyright (c) 2018-2019 TOYOTA MOTOR CORPORATION +# +# 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. + +TEMPLATE = app +TARGET = launcher +QT = qml quick dbus websockets +CONFIG += c++11 link_pkgconfig +DESTDIR = $${OUT_PWD}/../package/root/bin +PKGCONFIG += qlibwindowmanager qlibhomescreen + +include(../interfaces/interfaces.pri) + +SOURCES += \ + src/main.cpp \ + src/applicationmodel.cpp \ + src/appinfo.cpp \ + src/applicationlauncher.cpp + +HEADERS += \ + src/applicationlauncher.h \ + src/applicationmodel.h \ + src/appinfo.h + +OTHER_FILES += \ + README.md + +RESOURCES += \ + qml/images/images.qrc \ + qml/qml.qrc diff --git a/launcher/qml/ChangeItemPosition.js b/launcher/qml/ChangeItemPosition.js new file mode 100644 index 0000000..9fae07c --- /dev/null +++ b/launcher/qml/ChangeItemPosition.js @@ -0,0 +1,89 @@ +function next() { + repeater.currentItem += 1; + if (repeater.currentItem > repeater.count - 1) + { + repeater.currentItem = 0; + } + var count = 0; + + for (var i = 0; i < repeater.count; i++) + { + var item = repeater.itemAt(i); + item.currentState -= 1; + if ( item.currentState < 1 ) + { + item.currentState = repeater.count; + } + if ( item.currentState >= 1 && item.currentState <= 10 ) + { + item.state = "pos" + item.currentState + } else if ( item.currentState === 15 ){ + item.state = "pos11"; + } else if ( item.currentState === 16 ){ + item.state = "pos12"; + } else if ( item.currentState === 17 ){ + item.state = "pos13"; + } else if ( item.currentState >= 18 ){ + item.state = "pos0"; + } else { + item.state = "pos10"; + } + } +} + +function prev() { + repeater.currentItem -= 1; + if (repeater.currentItem < 0) + { + repeater.currentItem = repeater.count - 1; + } + var count = repeater.count; + for (var i = 0; i < repeater.count; i++) + { + var item = repeater.itemAt(i); + item.currentState += 1; + if ( item.currentState > repeater.count ) + { + item.currentState = 1; + } + if ( item.currentState >= 1 && item.currentState <= 10 ) + { + item.state = "pos" + item.currentState + } else if ( item.currentState === 15 ){ + item.state = "pos11"; + } else if ( item.currentState === 16 ){ + item.state = "pos12"; + } else if ( item.currentState === 17 ){ + item.state = "pos13"; + } else if ( item.currentState >= 18 ){ + item.state = "pos0"; + } else { + item.state = "pos10"; + } + } +} + +function move(pos, item) { + var distance = firstPox - pos; + if(distance > 200) { + next() + firstPox = pos + iconMoved = true + item.iconReleased() + } else if (distance < -200) { + prev() + firstPox = pos + iconMoved = true + item.iconReleased() + } +} + +function getCenterItem() { + var item; + for (var i = 0; i < repeater.count; i++) + { + item = repeater.itemAt(i) + if (item.state === "pos5" || item.state === "pos14") + return item + } +} diff --git a/launcher/qml/IconItem.qml b/launcher/qml/IconItem.qml new file mode 100644 index 0000000..342b539 --- /dev/null +++ b/launcher/qml/IconItem.qml @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2016 The Qt Company Ltd. + * Copyright (c) 2018-2019 TOYOTA MOTOR CORPORATION + * + * 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 QtQuick 2.0 +import QtQuick.Controls 2.0 +import QtGraphicalEffects 1.0 +import "ChangeItemPosition.js" as Cip + +Item { + id: main + width: 300 + height: 300 + property string icon: model.icon + property int pid: -1 + property bool isBlank: false + property bool isPressing: false + + Timer { + id: launchTimer + interval: 650 + repeat: false + onTriggered: { + launchApp() + } + } + + Item { + id: container + width: main.width + height: main.height + MouseArea { + anchors.fill: parent + onClicked: { + if(main.state === "pos14") { + launchApp() + } else if(main.state === "pos4") { + Cip.prev() + launchTimer.start() + } else if(main.state === "pos3") { + Cip.prev() + Cip.prev() + launchTimer.start() + } else if(main.state === "pos2") { + Cip.prev() + Cip.prev() + Cip.prev() + launchTimer.start() + } else if(main.state === "pos1") { + Cip.prev() + Cip.prev() + Cip.prev() + Cip.prev() + launchTimer.start() + } else if(main.state === "pos6") { + Cip.next() + launchTimer.start() + } else if(main.state === "pos7") { + Cip.next() + Cip.next() + launchTimer.start() + } else if(main.state === "pos8") { + Cip.next() + Cip.next() + Cip.next() + launchTimer.start() + } else if(main.state === "pos9") { + Cip.next() + Cip.next() + Cip.next() + Cip.next() + launchTimer.start() + } + } + } + + Image { + id: item + anchors.fill: parent + source: './images/%1_active.png'.arg(model.icon) + property string initial: model.name.substring(0,1).toUpperCase() + property bool hasIcon: model.icon !== 'blank' + + Label { + style: Text.Outline + styleColor: 'white' + color: 'transparent' + font.pixelSize: 225 + anchors.centerIn: parent + anchors.verticalCenterOffset: -50 + text: item.initial + visible: item.hasIcon ? false : true + } + + Label { + id: name + anchors.bottom: item.bottom + anchors.left: parent.left + anchors.right: parent.right + anchors.margins: 20 + font.pixelSize: 25 + font.letterSpacing: 5 + wrapMode: Text.WordWrap + horizontalAlignment: Text.AlignHCenter + color: "white" + text: qsTr(model.name.toUpperCase()) + } + + } + } + function iconPressed() { + item.source = './images/%1_inactive.png'.arg(model.icon) + } + function iconReleased() { + item.source = './images/%1_active.png'.arg(model.icon) + } + function launchApp() { + pid = launcher.launch(model.id) + if (1 < pid) { + } else { + console.warn("app cannot be launched!") + } + homescreenHandler.tapShortcut(model.name) + } +} diff --git a/launcher/qml/Launcher.qml b/launcher/qml/Launcher.qml new file mode 100644 index 0000000..605eba4 --- /dev/null +++ b/launcher/qml/Launcher.qml @@ -0,0 +1,516 @@ +/* + * Copyright (C) 2016 The Qt Company Ltd. + * Copyright (C) 2016, 2017 Mentor Graphics Development (Deutschland) GmbH + * Copyright (c) 2018-2019 TOYOTA MOTOR CORPORATION + * + * 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 QtQuick 2.6 +import QtQuick.Layouts 1.1 +import QtQuick.Controls 2.0 +import AppModel 1.0 +import "ChangeItemPosition.js" as Cip + +ApplicationWindow { + id: root + width: 1920 + height: 720 + + property int pid: -1 + property int firstPox: -1 + property bool iconMoved: false + + Timer { + id: timer + interval: 650 + repeat: false + onTriggered: { + var centerItem = Cip.getCenterItem() + centerItem.state = "pos14" + centerImage.opacity = 1.0 + } + } + + Repeater { + id: repeater + model: ApplicationModel { id: applicationModel } + + property int currentItem + + IconItem { + id: rect1 + property int currentState: 1 + + width: 300 + height: 300 + anchors.topMargin: 230 + + smooth: true + + anchors.centerIn: parent + + Behavior on opacity { + NumberAnimation { duration: 200 } + } + + Behavior on z { + NumberAnimation { duration: 300 } + } + transform: [ + Rotation { + id: rotate + angle: 0 + origin.y: 150 + origin.x: 150 + axis { x: 0; y: 1; z: 0 } + Behavior on angle { + NumberAnimation { easing.overshoot: 1; easing.type: Easing.OutBack; duration: 600 } + } + }, + Translate { + id: trans + x: 0 + y: 0 + Behavior on x { + NumberAnimation { easing.overshoot: 1; easing.type: Easing.OutBack; duration: 600 } + } + Behavior on y { + NumberAnimation { easing.overshoot: 1; easing.type: Easing.OutBack; duration: 600 } + } + }, + Scale { + id: scale + origin.x: 150 + origin.y: 150 + xScale: 1 + yScale: 1 + Behavior on xScale { + NumberAnimation { easing.overshoot: 1; easing.type: Easing.OutBack; duration: 600 } + } + Behavior on yScale { + NumberAnimation { easing.overshoot: 1; easing.type: Easing.OutBack; duration: 600 } + } + } + ] + + states: [ + State { + name: "pos0" + PropertyChanges { + target: rotate + angle: 80 + } + PropertyChanges { + target: trans + x: -1050 + y: 270 + } + PropertyChanges { + target: rect1 + z: 0 + opacity: 0 + } + PropertyChanges { + target: scale + xScale: 1.2 + yScale: 1.2 + } + }, + State { + name: "pos1" + PropertyChanges { + target: rotate + angle: 75 + } + PropertyChanges { + target: trans + x: -700 + y: 0 + } + PropertyChanges { + target: rect1 + z: 0 + opacity: 1 + } + PropertyChanges { + target: scale + xScale: 1.2 + yScale: 1.2 + } + }, + State { + name: "pos2" + PropertyChanges { + target: rotate + angle: 60 + } + PropertyChanges { + target: trans + x: -820 + y: 0 + } + PropertyChanges { + target: rect1 + z: 0 + opacity: 1 + } + PropertyChanges { + target: scale + xScale: 0.79 + yScale: 0.79 + } + }, + State { + name: "pos3" + PropertyChanges { + target: rotate + angle: 40 + } + PropertyChanges { + target: trans + x: -780 + y: 0 + } + PropertyChanges { + target: rect1 + z: 0 + opacity: 1 + } + PropertyChanges { + target: scale + xScale: 0.55 + yScale: 0.55 + } + }, + State { + name: "pos4" + PropertyChanges { + target: rotate + angle: 15 + } + PropertyChanges { + target: trans + x: -470 + y: 0 + } + PropertyChanges { + target: rect1 + z: 0 + opacity: 1 + } + PropertyChanges { + target: scale + xScale: 0.45 + yScale: 0.45 + } + }, + State { + name: "pos5" + PropertyChanges { + target: rotate + angle: 0 + } + PropertyChanges { + target: trans + x: 0 + y: 0 + } + PropertyChanges { + target: rect1 + z: 1 + opacity: 1 + } + PropertyChanges { + target: scale + xScale: 0.42 + yScale: 0.42 + } + }, + State { + name: "pos6" + PropertyChanges { + target: rotate + angle: -15 + } + PropertyChanges { + target: trans + x: 470 + y: 0 + } + PropertyChanges { + target: rect1 + z: 0 + opacity: 1 + } + PropertyChanges { + target: scale + xScale: 0.45 + yScale: 0.45 + } + }, + State { + name: "pos7" + PropertyChanges { + target: rotate + angle: -40 + } + PropertyChanges { + target: trans + x: 780 + y: 0 + } + PropertyChanges { + target: rect1 + z: 0 + opacity: 1 + } + PropertyChanges { + target: scale + xScale: 0.55 + yScale: 0.55 + } + }, + State { + name: "pos8" + PropertyChanges { + target: rotate + angle: -60 + } + PropertyChanges { + target: trans + x: 820 + y: 0 + } + PropertyChanges { + target: rect1 + z: 0 + opacity: 1 + } + PropertyChanges { + target: scale + xScale: 0.79 + yScale: 0.79 + } + }, + State { + name: "pos9" + PropertyChanges { + target: rotate + angle: -75 + } + PropertyChanges { + target: trans + x: 700 + y: 0 + } + PropertyChanges { + target: rect1 + z: 0 + opacity: 1 + } + PropertyChanges { + target: scale + xScale: 1.2 + yScale: 1.2 + } + }, + State { + name: "pos10" + PropertyChanges { + target: rotate + angle: -80 + } + PropertyChanges { + target: trans + x: 1050 + y: 270 + } + PropertyChanges { + target: rect1 + z: 0 + opacity: 0 + } + PropertyChanges { + target: scale + xScale: 1.2 + yScale: 1.2 + } + }, + State { + name: "pos11" + PropertyChanges { + target: rotate + angle: 0 + } + PropertyChanges { + target: trans + x: 1050 + y: 540 + } + PropertyChanges { + target: rect1 + z: 0 + opacity: 0 + } + PropertyChanges { + target: scale + xScale: 1 + yScale: 1 + } + }, + State { + name: "pos12" + PropertyChanges { + target: rotate + angle: 0 + } + PropertyChanges { + target: trans + x: 0 + y: 540 + } + PropertyChanges { + target: rect1 + z: 0 + opacity: 0 + } + PropertyChanges { + target: scale + xScale: 1 + yScale: 1 + } + }, + State { + name: "pos13" + PropertyChanges { + target: rotate + angle: 0 + } + PropertyChanges { + target: trans + x: -1050 + y: 540 + } + PropertyChanges { + target: rect1 + z: 0 + opacity: 0 + } + PropertyChanges { + target: scale + xScale: 1 + yScale: 1 + } + }, + State { + name: "pos14" + PropertyChanges { + target: rotate + angle: 0 + } + PropertyChanges { + target: trans + x: 0 + y: 0 + } + PropertyChanges { + target: rect1 + z: 1 + opacity: 1 + } + PropertyChanges { + target: scale + xScale: 1 + yScale: 1 + } + } + ] + } + + } + Component.onCompleted: { + repeater.currentItem = 5; + var count = repeater.count; + for ( var i = 0; i < repeater.count; i++) + { + var item = repeater.itemAt(i); + item.currentState = i + 1; + if ( item.currentState >= 1 && item.currentState <= 10 ) + { + item.state = "pos" + item.currentState; + if ( item.currentState === 5 ) + item.state = "pos14"; + } else if ( item.currentState === 15 ){ + item.state = "pos11"; + } else if ( item.currentState === 16 ){ + item.state = "pos12"; + } else if ( item.currentState === 17 ){ + item.state = "pos13"; + } else if ( item.currentState >= 18 ){ + item.state = "pos0"; + } else { + item.state = "pos10"; + } + } + } + + Image { + id: centerImage + source: './images/center_background.png' + height: 590 + width: 350 + anchors.centerIn: parent + opacity: 1.0 + } + + MouseArea { + anchors.fill: parent + propagateComposedEvents: true + z: 2 + + onPressed: { + firstPox = mouseX; + iconMoved = false; + centerImage.opacity = 0.0; + if(mouseX >= 800 && mouseX <= 1120) + { + var item = Cip.getCenterItem() + item.iconPressed() + } + } + + onReleased: { + timer.start() + if(mouseX >= 800 && mouseX <= 1120) + { + var item = Cip.getCenterItem() + item.iconReleased() + } + } + + onClicked: { + if (iconMoved) + { + mouse.accepted = true + } else { + mouse.accepted = false + } + } + + onPositionChanged: { + var item = Cip.getCenterItem() + Cip.move(mouseX, item) + } + } + +} diff --git a/launcher/qml/images/blank_active.png b/launcher/qml/images/blank_active.png Binary files differnew file mode 100644 index 0000000..e5a0dd4 --- /dev/null +++ b/launcher/qml/images/blank_active.png diff --git a/launcher/qml/images/blank_inactive.png b/launcher/qml/images/blank_inactive.png Binary files differnew file mode 100644 index 0000000..80b5198 --- /dev/null +++ b/launcher/qml/images/blank_inactive.png diff --git a/launcher/qml/images/browser_active.png b/launcher/qml/images/browser_active.png Binary files differnew file mode 100644 index 0000000..8ef350b --- /dev/null +++ b/launcher/qml/images/browser_active.png diff --git a/launcher/qml/images/browser_inactive.png b/launcher/qml/images/browser_inactive.png Binary files differnew file mode 100644 index 0000000..faeee45 --- /dev/null +++ b/launcher/qml/images/browser_inactive.png diff --git a/launcher/qml/images/center_background.png b/launcher/qml/images/center_background.png Binary files differnew file mode 100644 index 0000000..8e160f4 --- /dev/null +++ b/launcher/qml/images/center_background.png diff --git a/launcher/qml/images/connectivity_active.png b/launcher/qml/images/connectivity_active.png Binary files differnew file mode 100644 index 0000000..168b7fd --- /dev/null +++ b/launcher/qml/images/connectivity_active.png diff --git a/launcher/qml/images/connectivity_inactive.png b/launcher/qml/images/connectivity_inactive.png Binary files differnew file mode 100644 index 0000000..68f1ca0 --- /dev/null +++ b/launcher/qml/images/connectivity_inactive.png diff --git a/launcher/qml/images/dashboard_meter_active.png b/launcher/qml/images/dashboard_meter_active.png Binary files differnew file mode 100644 index 0000000..84b973b --- /dev/null +++ b/launcher/qml/images/dashboard_meter_active.png diff --git a/launcher/qml/images/dashboard_meter_inactive.png b/launcher/qml/images/dashboard_meter_inactive.png Binary files differnew file mode 100644 index 0000000..045658c --- /dev/null +++ b/launcher/qml/images/dashboard_meter_inactive.png diff --git a/launcher/qml/images/gtf_launcher_active.png b/launcher/qml/images/gtf_launcher_active.png Binary files differnew file mode 100644 index 0000000..fa39830 --- /dev/null +++ b/launcher/qml/images/gtf_launcher_active.png diff --git a/launcher/qml/images/gtf_launcher_inactive.png b/launcher/qml/images/gtf_launcher_inactive.png Binary files differnew file mode 100644 index 0000000..80b5198 --- /dev/null +++ b/launcher/qml/images/gtf_launcher_inactive.png diff --git a/launcher/qml/images/hvac_active.png b/launcher/qml/images/hvac_active.png Binary files differnew file mode 100644 index 0000000..9d4f6ac --- /dev/null +++ b/launcher/qml/images/hvac_active.png diff --git a/launcher/qml/images/hvac_inactive.png b/launcher/qml/images/hvac_inactive.png Binary files differnew file mode 100644 index 0000000..806d661 --- /dev/null +++ b/launcher/qml/images/hvac_inactive.png diff --git a/launcher/qml/images/images.qrc b/launcher/qml/images/images.qrc new file mode 100644 index 0000000..4f22483 --- /dev/null +++ b/launcher/qml/images/images.qrc @@ -0,0 +1,37 @@ +<RCC> + <qresource prefix="/images"> + <file>connectivity_active.png</file> + <file>connectivity_inactive.png</file> + <file>dashboard_meter_active.png</file> + <file>dashboard_meter_inactive.png</file> + <file>hvac_active.png</file> + <file>hvac_inactive.png</file> + <file>mixer_active.png</file> + <file>mixer_inactive.png</file> + <file>mediaplayer_active.png</file> + <file>mediaplayer_inactive.png</file> + <file>music_active.png</file> + <file>music_inactive.png</file> + <file>navigation_active.png</file> + <file>navigation_inactive.png</file> + <file>phone_active.png</file> + <file>phone_inactive.png</file> + <file>poi_active.png</file> + <file>poi_inactive.png</file> + <file>radio_active.png</file> + <file>radio_inactive.png</file> + <file>settings_active.png</file> + <file>settings_inactive.png</file> + <file>videoplayer_active.png</file> + <file>videoplayer_inactive.png</file> + <file>browser_active.png</file> + <file>browser_inactive.png</file> + <file>weather_active.png</file> + <file>weather_inactive.png</file> + <file>blank_active.png</file> + <file>blank_inactive.png</file> + <file>gtf_launcher_active.png</file> + <file>gtf_launcher_inactive.png</file> + <file>center_background.png</file> + </qresource> +</RCC> diff --git a/launcher/qml/images/mediaplayer_active.png b/launcher/qml/images/mediaplayer_active.png Binary files differnew file mode 100644 index 0000000..140733a --- /dev/null +++ b/launcher/qml/images/mediaplayer_active.png diff --git a/launcher/qml/images/mediaplayer_inactive.png b/launcher/qml/images/mediaplayer_inactive.png Binary files differnew file mode 100644 index 0000000..38e6111 --- /dev/null +++ b/launcher/qml/images/mediaplayer_inactive.png diff --git a/launcher/qml/images/mixer_active.png b/launcher/qml/images/mixer_active.png Binary files differnew file mode 100644 index 0000000..ab0b9f3 --- /dev/null +++ b/launcher/qml/images/mixer_active.png diff --git a/launcher/qml/images/mixer_inactive.png b/launcher/qml/images/mixer_inactive.png Binary files differnew file mode 100644 index 0000000..e3872bb --- /dev/null +++ b/launcher/qml/images/mixer_inactive.png diff --git a/launcher/qml/images/music_active.png b/launcher/qml/images/music_active.png Binary files differnew file mode 100644 index 0000000..140733a --- /dev/null +++ b/launcher/qml/images/music_active.png diff --git a/launcher/qml/images/music_inactive.png b/launcher/qml/images/music_inactive.png Binary files differnew file mode 100644 index 0000000..38e6111 --- /dev/null +++ b/launcher/qml/images/music_inactive.png diff --git a/launcher/qml/images/navigation_active.png b/launcher/qml/images/navigation_active.png Binary files differnew file mode 100644 index 0000000..ae3f720 --- /dev/null +++ b/launcher/qml/images/navigation_active.png diff --git a/launcher/qml/images/navigation_inactive.png b/launcher/qml/images/navigation_inactive.png Binary files differnew file mode 100644 index 0000000..52530d6 --- /dev/null +++ b/launcher/qml/images/navigation_inactive.png diff --git a/launcher/qml/images/phone_active.png b/launcher/qml/images/phone_active.png Binary files differnew file mode 100644 index 0000000..8a10a92 --- /dev/null +++ b/launcher/qml/images/phone_active.png diff --git a/launcher/qml/images/phone_inactive.png b/launcher/qml/images/phone_inactive.png Binary files differnew file mode 100644 index 0000000..2b61477 --- /dev/null +++ b/launcher/qml/images/phone_inactive.png diff --git a/launcher/qml/images/poi_active.png b/launcher/qml/images/poi_active.png Binary files differnew file mode 100644 index 0000000..dcf799f --- /dev/null +++ b/launcher/qml/images/poi_active.png diff --git a/launcher/qml/images/poi_inactive.png b/launcher/qml/images/poi_inactive.png Binary files differnew file mode 100644 index 0000000..c0a4fd3 --- /dev/null +++ b/launcher/qml/images/poi_inactive.png diff --git a/launcher/qml/images/radio_active.png b/launcher/qml/images/radio_active.png Binary files differnew file mode 100644 index 0000000..411f94a --- /dev/null +++ b/launcher/qml/images/radio_active.png diff --git a/launcher/qml/images/radio_inactive.png b/launcher/qml/images/radio_inactive.png Binary files differnew file mode 100644 index 0000000..f8c2cc1 --- /dev/null +++ b/launcher/qml/images/radio_inactive.png diff --git a/launcher/qml/images/settings_active.png b/launcher/qml/images/settings_active.png Binary files differnew file mode 100644 index 0000000..e9bec82 --- /dev/null +++ b/launcher/qml/images/settings_active.png diff --git a/launcher/qml/images/settings_inactive.png b/launcher/qml/images/settings_inactive.png Binary files differnew file mode 100644 index 0000000..fc72f9d --- /dev/null +++ b/launcher/qml/images/settings_inactive.png diff --git a/launcher/qml/images/videoplayer_active.png b/launcher/qml/images/videoplayer_active.png Binary files differnew file mode 100644 index 0000000..69bd5bc --- /dev/null +++ b/launcher/qml/images/videoplayer_active.png diff --git a/launcher/qml/images/videoplayer_inactive.png b/launcher/qml/images/videoplayer_inactive.png Binary files differnew file mode 100644 index 0000000..99c44ff --- /dev/null +++ b/launcher/qml/images/videoplayer_inactive.png diff --git a/launcher/qml/images/weather_active.png b/launcher/qml/images/weather_active.png Binary files differnew file mode 100644 index 0000000..4ff7223 --- /dev/null +++ b/launcher/qml/images/weather_active.png diff --git a/launcher/qml/images/weather_inactive.png b/launcher/qml/images/weather_inactive.png Binary files differnew file mode 100644 index 0000000..d5a18b3 --- /dev/null +++ b/launcher/qml/images/weather_inactive.png diff --git a/launcher/qml/qml.qrc b/launcher/qml/qml.qrc new file mode 100644 index 0000000..0dfd6b1 --- /dev/null +++ b/launcher/qml/qml.qrc @@ -0,0 +1,7 @@ +<RCC> + <qresource prefix="/"> + <file>Launcher.qml</file> + <file>IconItem.qml</file> + <file>ChangeItemPosition.js</file> + </qresource> +</RCC> diff --git a/launcher/src/appinfo.cpp b/launcher/src/appinfo.cpp new file mode 100644 index 0000000..c8bb943 --- /dev/null +++ b/launcher/src/appinfo.cpp @@ -0,0 +1,177 @@ +/* + * Copyright (C) 2016, 2017 Mentor Graphics Development (Deutschland) GmbH + * Copyright (C) 2016 The Qt Company Ltd. + * Copyright (c) 2018-2019 TOYOTA MOTOR CORPORATION + * + * 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. + */ + +#include "appinfo.h" + +#include <QtCore/QJsonObject> + +class AppInfo::Private : public QSharedData +{ +public: + Private(); + Private(const Private &other); + + QString id; + QString version; + int width; + int height; + QString name; + QString description; + QString shortname; + QString author; + QString iconPath; +}; + +AppInfo::Private::Private() + : width(-1) + , height(-1) +{ +} + +AppInfo::Private::Private(const Private &other) + : QSharedData(other) + , id(other.id) + , version(other.version) + , width(other.width) + , height(other.height) + , name(other.name) + , description(other.description) + , shortname(other.shortname) + , author(other.author) + , iconPath(other.iconPath) +{ +} + +AppInfo::AppInfo() + : d(new Private) +{ +} + +AppInfo::AppInfo(const QString &icon, const QString &name, const QString &id) + : d(new Private) +{ + d->iconPath = icon; + d->name = name; + d->id = id; +} + +AppInfo::AppInfo(const AppInfo &other) + : d(other.d) +{ +} + +AppInfo::~AppInfo() +{ +} + +AppInfo &AppInfo::operator =(const AppInfo &other) +{ + d = other.d; + return *this; +} + +QString AppInfo::id() const +{ + return d->id; +} + +QString AppInfo::version() const +{ + return d->version; +} + +int AppInfo::width() const +{ + return d->width; +} + +int AppInfo::height() const +{ + return d->height; +} + +QString AppInfo::name() const +{ + return d->name; +} + +QString AppInfo::description() const +{ + return d->description; +} + +QString AppInfo::shortname() const +{ + return d->shortname; +} + +QString AppInfo::author() const +{ + return d->author; +} + +QString AppInfo::iconPath() const +{ + return d->iconPath; +} + +void AppInfo::read(const QJsonObject &json) +{ + d->id = json["id"].toString(); + d->version = json["version"].toString(); + d->width = json["width"].toInt(); + d->height = json["height"].toInt(); + d->name = json["name"].toString(); + d->description = json["description"].toString(); + d->shortname = json["shortname"].toString(); + d->author = json["author"].toString(); + d->iconPath = json["iconPath"].toString(); +} + +QDBusArgument &operator <<(QDBusArgument &argument, const AppInfo &appInfo) +{ + argument.beginStructure(); + argument << appInfo.d->id; + argument << appInfo.d->version; + argument << appInfo.d->width; + argument << appInfo.d->height; + argument << appInfo.d->name; + argument << appInfo.d->description; + argument << appInfo.d->shortname; + argument << appInfo.d->author; + argument << appInfo.d->iconPath; + argument.endStructure(); + + return argument; +} + +const QDBusArgument &operator >>(const QDBusArgument &argument, AppInfo &appInfo) +{ + argument.beginStructure(); + argument >> appInfo.d->id; + argument >> appInfo.d->version; + argument >> appInfo.d->width; + argument >> appInfo.d->height; + argument >> appInfo.d->name; + argument >> appInfo.d->description; + argument >> appInfo.d->shortname; + argument >> appInfo.d->author; + argument >> appInfo.d->iconPath; + argument.endStructure(); + return argument; +} diff --git a/launcher/src/appinfo.h b/launcher/src/appinfo.h new file mode 100644 index 0000000..b6beaa2 --- /dev/null +++ b/launcher/src/appinfo.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2016, 2017 Mentor Graphics Development (Deutschland) GmbH + * Copyright (C) 2016 The Qt Company Ltd. + * Copyright (c) 2018-2019 TOYOTA MOTOR CORPORATION + * + * 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. + */ + +#ifndef APPINFO_H +#define APPINFO_H + +#include <QtCore/QSharedDataPointer> +#include <QtDBus/QDBusArgument> + +class AppInfo +{ + Q_GADGET + Q_PROPERTY(QString id READ id) + Q_PROPERTY(QString version READ version) + Q_PROPERTY(int width READ width) + Q_PROPERTY(int height READ height) + Q_PROPERTY(QString name READ name) + Q_PROPERTY(QString description READ description) + Q_PROPERTY(QString shortname READ shortname) + Q_PROPERTY(QString author READ author) + Q_PROPERTY(QString iconPath READ iconPath) +public: + AppInfo(); + AppInfo(const QString &icon, const QString &name, const QString &id); + AppInfo(const AppInfo &other); + virtual ~AppInfo(); + AppInfo &operator =(const AppInfo &other); + void swap(AppInfo &other) { qSwap(d, other.d); } + + QString id() const; + QString version() const; + int width() const; + int height() const; + QString name() const; + QString description() const; + QString shortname() const; + QString author() const; + QString iconPath() const; + + void read(const QJsonObject &json); + + friend QDBusArgument &operator <<(QDBusArgument &argument, const AppInfo &appInfo); + friend const QDBusArgument &operator >>(const QDBusArgument &argument, AppInfo &appInfo); + +private: + class Private; + QSharedDataPointer<Private> d; +}; + +Q_DECLARE_SHARED(AppInfo) +Q_DECLARE_METATYPE(AppInfo) +Q_DECLARE_METATYPE(QList<AppInfo>) + +#endif // APPINFO_H diff --git a/launcher/src/applicationlauncher.cpp b/launcher/src/applicationlauncher.cpp new file mode 100644 index 0000000..fe76b0c --- /dev/null +++ b/launcher/src/applicationlauncher.cpp @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2016 The Qt Company Ltd. + * Copyright (C) 2016, 2017 Mentor Graphics Development (Deutschland) GmbH + * Copyright (c) 2018-2019 TOYOTA MOTOR CORPORATION + * + * 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. + */ + +#include "applicationlauncher.h" + +#include "afm_user_daemon_proxy.h" + +#include "hmi-debug.h" + +extern org::AGL::afm::user *afm_user_daemon_proxy; + +ApplicationLauncher::ApplicationLauncher(QObject *parent) + : QObject(parent) + , m_launching(false) + , m_timeout(new QTimer(this)) +{ + m_timeout->setInterval(3000); + m_timeout->setSingleShot(true); + connect(m_timeout, &QTimer::timeout, [&]() { + setLaunching(false); + }); + connect(this, &ApplicationLauncher::launchingChanged, [&](bool launching) { + if (launching) + m_timeout->start(); + else + m_timeout->stop(); + }); + connect(this, &ApplicationLauncher::currentChanged, [&]() { + setLaunching(false); + }); +} + +int ApplicationLauncher::launch(const QString &application) +{ + int result = -1; + HMI_DEBUG("launch","ApplicationLauncher launch %s.", application.toStdString().c_str()); + + result = afm_user_daemon_proxy->start(application).value().toInt(); + HMI_DEBUG("launch","ApplicationLauncher pid: %d.", result); + + if (result > 1) { + setLaunching(true); + } + + return result; +} + +bool ApplicationLauncher::isLaunching() const +{ + return m_launching; +} + +void ApplicationLauncher::setLaunching(bool launching) +{ + if (m_launching == launching) return; + m_launching = launching; + launchingChanged(launching); +} + +QString ApplicationLauncher::current() const +{ + return m_current; +} + +void ApplicationLauncher::setCurrent(const QString ¤t) +{ + if (m_current == current) return; + m_current = current; + emit currentChanged(current); +} diff --git a/launcher/src/applicationlauncher.h b/launcher/src/applicationlauncher.h new file mode 100644 index 0000000..95b1dec --- /dev/null +++ b/launcher/src/applicationlauncher.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2016 The Qt Company Ltd. + * Copyright (C) 2016, 2017 Mentor Graphics Development (Deutschland) GmbH + * Copyright (c) 2018-2019 TOYOTA MOTOR CORPORATION + * + * 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. + */ + +#ifndef APPLICATIONLAUNCHER_H +#define APPLICATIONLAUNCHER_H + +#include <QtCore/QObject> + +class QTimer; + +class ApplicationLauncher : public QObject +{ + Q_OBJECT + Q_PROPERTY(bool launching READ isLaunching NOTIFY launchingChanged) + Q_PROPERTY(QString current READ current WRITE setCurrent NOTIFY currentChanged) +public: + explicit ApplicationLauncher(QObject *parent = NULL); + + bool isLaunching() const; + QString current() const; + +signals: + void newAppRequestsToBeVisible(int pid); + void launchingChanged(bool launching); + void currentChanged(const QString ¤t); + +public slots: + int launch(const QString &application); + void setCurrent(const QString ¤t); + +private: + void setLaunching(bool launching); + +private: + bool m_launching; + QString m_current; + QTimer *m_timeout; +}; + +#endif // APPLICATIONLAUNCHER_H diff --git a/launcher/src/applicationmodel.cpp b/launcher/src/applicationmodel.cpp new file mode 100644 index 0000000..fe5e1c1 --- /dev/null +++ b/launcher/src/applicationmodel.cpp @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2016 The Qt Company Ltd. + * Copyright (C) 2016, 2017 Mentor Graphics Development (Deutschland) GmbH + * Copyright (c) 2018-2019 TOYOTA MOTOR CORPORATION + * + * 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. + */ + +#include "applicationmodel.h" +#include "appinfo.h" + +#include "hmi-debug.h" + +#include <QtDBus/QDBusInterface> +#include <QtDBus/QDBusReply> + +#include "afm_user_daemon_proxy.h" + +extern org::AGL::afm::user *afm_user_daemon_proxy; + +class ApplicationModel::Private +{ +public: + Private(); + int loadAppInfo(); + + QList<AppInfo> data; +}; + +namespace { + QString get_icon_name(QJsonObject const &i) + { + QString icon = i["name"].toString().toLower(); + + if ( !QFile::exists(QString(":/images/%1_active.png").arg(icon)) || + !QFile::exists(QString(":/images/%1_inactive.png").arg(icon)) ) + { + icon = "blank"; + } + return icon; + } +} + +ApplicationModel::Private::Private() +{ + int appCount = 0; + while(appCount <= 22) + { + appCount += loadAppInfo(); + HMI_DEBUG("launcher", "appCount = %d", appCount); + } +} + +int ApplicationModel::Private::loadAppInfo() +{ + QString apps = afm_user_daemon_proxy->runnables(QStringLiteral("")); + QJsonDocument japps = QJsonDocument::fromJson(apps.toUtf8()); + int appCount = 0; + for (auto const &app : japps.array()) { + QJsonObject const &jso = app.toObject(); + auto const name = jso["name"].toString(); + auto const id = jso["id"].toString(); + auto const icon = get_icon_name(jso); + + // Hide HomeScreen icon itself + if (name != "launcher" && + name != "homescreen" && + name != "HomeScreen" && + !name.contains("OnScreen", Qt::CaseInsensitive)) { + this->data.append(AppInfo(icon, name, id)); + } + appCount++; + + HMI_DEBUG("launcher","name: %s icon: %s id: %s.", name.toStdString().c_str(), icon.toStdString().c_str(), id.toStdString().c_str()); + } + return appCount; +} + +ApplicationModel::ApplicationModel(QObject *parent) + : QAbstractListModel(parent) + , d(new Private()) +{ +} + +ApplicationModel::~ApplicationModel() +{ + delete this->d; +} + +int ApplicationModel::rowCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + return 0; + + return this->d->data.count(); +} + +QVariant ApplicationModel::data(const QModelIndex &index, int role) const +{ + QVariant ret; + if (!index.isValid()) + return ret; + + switch (role) { + case Qt::DecorationRole: + ret = this->d->data[index.row()].iconPath(); + break; + case Qt::DisplayRole: + ret = this->d->data[index.row()].name(); + break; + case Qt::UserRole: + ret = this->d->data[index.row()].id(); + break; + default: + break; + } + + return ret; +} + +QHash<int, QByteArray> ApplicationModel::roleNames() const +{ + QHash<int, QByteArray> roles; + roles[Qt::DecorationRole] = "icon"; + roles[Qt::DisplayRole] = "name"; + roles[Qt::UserRole] = "id"; + return roles; +} + +QString ApplicationModel::id(int i) const +{ + return data(index(i), Qt::UserRole).toString(); +} + +QString ApplicationModel::name(int i) const +{ + return data(index(i), Qt::DisplayRole).toString(); +} + +void ApplicationModel::move(int from, int to) +{ + QModelIndex parent; + if (to < 0 || to > rowCount()) return; + if (from < to) { + if (!beginMoveRows(parent, from, from, parent, to + 1)) { + HMI_NOTICE("launcher","from : %d, to : %d. false.", from, to); + return; + } + d->data.move(from, to); + endMoveRows(); + } else if (from > to) { + if (!beginMoveRows(parent, from, from, parent, to)) { + HMI_NOTICE("launcher","from : %d, to : %d. false.", from, to); + return; + } + d->data.move(from, to); + endMoveRows(); + } else { + HMI_NOTICE("launcher","from : %d, to : %d. false.", from, to); + } +} diff --git a/launcher/src/applicationmodel.h b/launcher/src/applicationmodel.h new file mode 100644 index 0000000..5b7c6aa --- /dev/null +++ b/launcher/src/applicationmodel.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2016 The Qt Company Ltd. + * Copyright (c) 2018-2019 TOYOTA MOTOR CORPORATION + * + * 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. + */ + +#ifndef APPLICATIONMODEL_H +#define APPLICATIONMODEL_H + +#include <QtCore/QAbstractListModel> + +class ApplicationModel : public QAbstractListModel +{ + Q_OBJECT +public: + explicit ApplicationModel(QObject *parent = nullptr); + ~ApplicationModel(); + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + QHash<int, QByteArray> roleNames() const override; + Q_INVOKABLE QString id(int index) const; + Q_INVOKABLE QString name(int index) const; + Q_INVOKABLE void move(int from, int to); + +private: + class Private; + Private *d; +}; + +#endif // APPLICATIONMODEL_H diff --git a/launcher/src/hmi-debug.h b/launcher/src/hmi-debug.h new file mode 100644 index 0000000..f637db3 --- /dev/null +++ b/launcher/src/hmi-debug.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2018-2019 TOYOTA MOTOR CORPORATION + * + * 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. + */ + +#ifndef __HMI_DEBUG_H__ +#define __HMI_DEBUG_H__ + +#include <time.h> +#include <stdio.h> +#include <stdarg.h> +#include <string.h> +#include <stdlib.h> + +enum LOG_LEVEL{ + LOG_LEVEL_NONE = 0, + LOG_LEVEL_ERROR, + LOG_LEVEL_WARNING, + LOG_LEVEL_NOTICE, + LOG_LEVEL_INFO, + LOG_LEVEL_DEBUG, + LOG_LEVEL_MAX = LOG_LEVEL_DEBUG +}; + +#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) + +#define HMI_ERROR(prefix, args,...) _HMI_LOG(LOG_LEVEL_ERROR, __FILENAME__, __FUNCTION__, __LINE__, prefix, args, ##__VA_ARGS__) +#define HMI_WARNING(prefix, args,...) _HMI_LOG(LOG_LEVEL_WARNING, __FILENAME__, __FUNCTION__,__LINE__, prefix, args,##__VA_ARGS__) +#define HMI_NOTICE(prefix, args,...) _HMI_LOG(LOG_LEVEL_NOTICE, __FILENAME__, __FUNCTION__,__LINE__, prefix, args,##__VA_ARGS__) +#define HMI_INFO(prefix, args,...) _HMI_LOG(LOG_LEVEL_INFO, __FILENAME__, __FUNCTION__,__LINE__, prefix, args,##__VA_ARGS__) +#define HMI_DEBUG(prefix, args,...) _HMI_LOG(LOG_LEVEL_DEBUG, __FILENAME__, __FUNCTION__,__LINE__, prefix, args,##__VA_ARGS__) + +static char ERROR_FLAG[6][20] = {"NONE", "ERROR", "WARNING", "NOTICE", "INFO", "DEBUG"}; + +static void _HMI_LOG(enum LOG_LEVEL level, const char* file, const char* func, const int line, const char* prefix, const char* log, ...) +{ + const int log_level = (getenv("USE_HMI_DEBUG") == NULL)?LOG_LEVEL_ERROR:atoi(getenv("USE_HMI_DEBUG")); + if(log_level < level) + { + return; + } + + char *message; + struct timespec tp; + unsigned int time; + + clock_gettime(CLOCK_REALTIME, &tp); + time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000); + + va_list args; + va_start(args, log); + if (log == NULL || vasprintf(&message, log, args) < 0) + message = NULL; + fprintf(stderr, "[%10.3f] [%s %s] [%s, %s(), Line:%d] >>> %s \n", time / 1000.0, prefix, ERROR_FLAG[level], file, func, line, message); + va_end(args); + free(message); +} + +#endif //__HMI_DEBUG_H__ diff --git a/launcher/src/main.cpp b/launcher/src/main.cpp new file mode 100644 index 0000000..d6a19d5 --- /dev/null +++ b/launcher/src/main.cpp @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2016, 2017 Mentor Graphics Development (Deutschland) GmbH + * Copyright (c) 2018-2019 TOYOTA MOTOR CORPORATION + * + * 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. + */ + +#include <QGuiApplication> +#include <QCommandLineParser> +#include <QtGui/QGuiApplication> +#include <QtQml/QQmlApplicationEngine> +#include <QtQml/QQmlContext> +#include <QtQml/qqml.h> +#include <QQuickWindow> +#include <QThread> + +#include <qlibwindowmanager.h> +#include "applicationlauncher.h" +#include "applicationmodel.h" +#include "appinfo.h" +#include "afm_user_daemon_proxy.h" +#include "qlibhomescreen.h" +#include "hmi-debug.h" + +// XXX: We want this DBus connection to be shared across the different +// QML objects, is there another way to do this, a nice way, perhaps? +org::AGL::afm::user *afm_user_daemon_proxy; + +namespace { + +struct Cleanup { + static inline void cleanup(org::AGL::afm::user *p) { + delete p; + afm_user_daemon_proxy = Q_NULLPTR; + } +}; + +void noOutput(QtMsgType, const QMessageLogContext &, const QString &) +{ +} + +} + +int main(int argc, char *argv[]) +{ + QString myname = QString("launcher"); + QGuiApplication a(argc, argv); + + // use launch process + QScopedPointer<org::AGL::afm::user, Cleanup> afm_user_daemon_proxy(new org::AGL::afm::user("org.AGL.afm.user", + "/org/AGL/afm/user", + QDBusConnection::sessionBus(), + 0)); + ::afm_user_daemon_proxy = afm_user_daemon_proxy.data(); + + QCoreApplication::setOrganizationDomain("LinuxFoundation"); + QCoreApplication::setOrganizationName("AutomotiveGradeLinux"); + QCoreApplication::setApplicationName(myname); + QCoreApplication::setApplicationVersion("0.1.0"); + + QCommandLineParser parser; + parser.addPositionalArgument("port", a.translate("main", "port for binding")); + parser.addPositionalArgument("secret", a.translate("main", "secret for binding")); + parser.addHelpOption(); + parser.addVersionOption(); + parser.process(a); + QStringList positionalArguments = parser.positionalArguments(); + + int port = 1700; + QString token = "wm"; + + if (positionalArguments.length() == 2) { + port = positionalArguments.takeFirst().toInt(); + token = positionalArguments.takeFirst(); + } + + HMI_DEBUG("launcher","port = %d, token = %s", port, token.toStdString().c_str()); + + // import C++ class to QML + qmlRegisterType<ApplicationModel>("AppModel", 1, 0, "ApplicationModel"); + + // DBus + qDBusRegisterMetaType<AppInfo>(); + qDBusRegisterMetaType<QList<AppInfo> >(); + + QLibHomeScreen* homescreenHandler = new QLibHomeScreen(); + ApplicationLauncher *launcher = new ApplicationLauncher(); + QLibWindowmanager* layoutHandler = new QLibWindowmanager(); + if(layoutHandler->init(port,token) != 0){ + exit(EXIT_FAILURE); + } + + if (layoutHandler->requestSurface(myname) != 0) { + exit(EXIT_FAILURE); + } + + layoutHandler->set_event_handler(QLibWindowmanager::Event_SyncDraw, [layoutHandler, myname](json_object *object) { + layoutHandler->endDraw(myname); + }); + + layoutHandler->set_event_handler(QLibWindowmanager::Event_Visible, [layoutHandler, launcher](json_object *object) { + QString label = QString(json_object_get_string( json_object_object_get(object, "drawing_name") )); + qDebug() << label; + QMetaObject::invokeMethod(launcher, "setCurrent", Qt::QueuedConnection, Q_ARG(QString, label == "HomeScreen" ? "Home" : label)); + }); + + layoutHandler->set_event_handler(QLibWindowmanager::Event_Invisible, [layoutHandler, launcher](json_object *object) { + const char* label = json_object_get_string( json_object_object_get(object, "drawing_name") ); + HMI_DEBUG("launch", "surface %s Event_Invisible", label); + }); + + QUrl bindingAddress; + bindingAddress.setScheme(QStringLiteral("ws")); + bindingAddress.setHost(QStringLiteral("localhost")); + bindingAddress.setPort(port); + bindingAddress.setPath(QStringLiteral("/api")); + + QUrlQuery query; + query.addQueryItem(QStringLiteral("token"), token); + bindingAddress.setQuery(query); + + const QByteArray hack_delay = qgetenv("HMI_LAUNCHER_STARTUP_DELAY"); + int delay_time = 1; + + if (!hack_delay.isEmpty()) { + delay_time = (QString::fromLocal8Bit(hack_delay)).toInt(); + } + + QThread::sleep(delay_time); + qDebug("Sleep %d sec to resolve race condtion between HomeScreen and Launcher", delay_time); + + // mail.qml loading + QQmlApplicationEngine engine; + engine.rootContext()->setContextProperty("layoutHandler", layoutHandler); + engine.rootContext()->setContextProperty("homescreenHandler", homescreenHandler); + engine.rootContext()->setContextProperty("launcher", launcher); + engine.load(QUrl(QStringLiteral("qrc:/Launcher.qml"))); + + QObject *root = engine.rootObjects().first(); + QQuickWindow *window = qobject_cast<QQuickWindow *>(root); + QObject::connect(window, SIGNAL(frameSwapped()), layoutHandler, SLOT(slotActivateSurface())); + + homescreenHandler->init(port, token.toStdString().c_str()); + + homescreenHandler->set_event_handler(QLibHomeScreen::Event_TapShortcut, [layoutHandler, myname](json_object *object){ + layoutHandler->activateSurface(myname); + }); + + return a.exec(); +} |