--- /dev/null
+/*
+ * Copyright (C) 2016 The Qt Company Ltd.
+ * Copyright (C) 2017 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 <QtCore/QCommandLineParser>
+#include <QtCore/QDebug>
+#include <QtCore/QDir>
+#include <QtCore/QStandardPaths>
+#include <QtCore/QUrlQuery>
+#include <QtGui/QGuiApplication>
+#include <QtQml/QQmlApplicationEngine>
+#include <QtQml/QQmlContext>
+#include <QtQml/qqml.h>
+#include <QtQuickControls2/QQuickStyle>
+#include "libsmwrapper.h"
+
+#ifdef HAVE_LIBHOMESCREEN
+#include <libhomescreen.hpp>
+#endif
+
+#include "playlistwithmetadata.h"
+
+LibSMWrapper* smw;
+static int mysourceID = 0;
+static bool firsttime = true;
+QObject *root;
+
+static void onRep(struct json_object* reply_contents);
+static void onEv(const std::string& event, struct json_object* event_contents);
+
+int main(int argc, char *argv[])
+{
+#ifdef HAVE_LIBHOMESCREEN
+ LibHomeScreen libHomeScreen;
+
+ if (!libHomeScreen.renderAppToAreaAllowed(0, 1)) {
+ qWarning() << "renderAppToAreaAllowed is denied";
+ return -1;
+ }
+#endif
+
+ QGuiApplication app(argc, argv);
+
+ QQuickStyle::setStyle("AGL");
+
+ qmlRegisterType<PlaylistWithMetadata>("MediaPlayer", 1, 0, "PlaylistWithMetadata");
+
+ QQmlApplicationEngine engine;
+ QQmlContext *context = engine.rootContext();
+
+ QCommandLineParser parser;
+ parser.addPositionalArgument("port", app.translate("main", "port for binding"));
+ parser.addPositionalArgument("secret", app.translate("main", "secret for binding"));
+ parser.addHelpOption();
+ parser.addVersionOption();
+ parser.process(app);
+ QStringList positionalArguments = parser.positionalArguments();
+
+ if (positionalArguments.length() == 2) {
+ int port = positionalArguments.takeFirst().toInt();
+ QString secret = positionalArguments.takeFirst();
+ QUrl bindingAddress;
+ bindingAddress.setScheme(QStringLiteral("ws"));
+ bindingAddress.setHost(QStringLiteral("localhost"));
+ bindingAddress.setPort(port);
+ bindingAddress.setPath(QStringLiteral("/api"));
+ QUrlQuery query;
+ query.addQueryItem(QStringLiteral("token"), secret);
+ bindingAddress.setQuery(query);
+ context->setContextProperty(QStringLiteral("bindingAddress"), bindingAddress);
+
+ // prepare to use soundmangaer
+ smw = new LibSMWrapper(port, secret);
+ smw->wrapper_registerCallback(onEv, onRep);
+ smw->subscribe(QString("asyncSetSourceState"));
+ smw->subscribe(QString("asyncConnect"));
+ smw->run_eventloop();
+ engine.rootContext()->setContextProperty("smw",smw);
+ }
+
+ engine.load(QUrl(QStringLiteral("qrc:/MediaPlayer.qml")));
+
+ root = engine.rootObjects().first();
+ QObject::connect(smw, SIGNAL(smEvent(QVariant, QVariant)),
+ root, SLOT(slotEvent(QVariant, QVariant)));
+ QObject::connect(smw, SIGNAL(smReply(QVariant)),
+ root, SLOT(slotReply(QVariant)));
+
+ return app.exec();
+}
+
+static void onRep(struct json_object* reply_contents)
+{
+ qDebug("%s is called", __FUNCTION__);
+ QString str = QString(json_object_get_string(reply_contents));
+ QJsonParseError error;
+ QJsonDocument jdoc = QJsonDocument::fromJson(str.toUtf8(), &error);
+ QJsonObject jobj = jdoc.object();
+
+ smw->emit_reply(jobj);
+ json_object_put(reply_contents);
+}
+
+static void onEv(const std::string& event, struct json_object* event_contents)
+{
+ qDebug("%s is called", __FUNCTION__);
+ QString str = QString(json_object_get_string(event_contents));
+ const QString event_name = QString(event.c_str());
+
+ if(firsttime){
+ qDebug("check to return acknowledge to SM");
+ if(!event_name.contains("asyncSetSourceState", Qt::CaseSensitive)){
+ return;
+ }
+ /* this is temporary fix because QML doesn't catch signal if application is on background first*/
+ qDebug("return acknowledge to SM");
+ struct json_object *content_data, *content_handle, *content_sourceID;
+ qDebug() << str;
+ json_object_object_get_ex(event_contents,"data", &content_data);
+ json_bool has_handle = json_object_object_get_ex(content_data,"handle",&content_handle);
+ json_bool has_sourceID = json_object_object_get_ex(content_data,"sourceID",&content_sourceID);
+ if(!has_handle || !has_sourceID){
+ qDebug("doesn't have sourceID/handle");
+ return;
+ }
+
+ int event_sourceID = json_object_get_int(content_sourceID);
+ /* QML has sourceID */
+ mysourceID = root->property("sourceID").toInt();
+ qDebug("my sourceID is %d", mysourceID);
+
+ if(event_sourceID != mysourceID){
+ qDebug("sourceID is not designated to me");
+ return;
+ }
+
+ /* Following code is mediaplayer only because mediaplayer doen't react in background first if it is on background*/
+ struct json_object* ret_obj = json_object_new_object();
+ json_object_object_add(ret_obj, "handle", content_handle);
+ json_object_object_add(ret_obj, "error", json_object_new_int(0));
+ QString ret = QString(json_object_get_string(ret_obj));
+ smw->call(QString("ackSetSourceState"), ret);
+ /* to here */
+ firsttime = false;
+ }
+
+ QJsonParseError error;
+ QJsonDocument jdoc = QJsonDocument::fromJson(str.toUtf8(), &error);
+ const QJsonObject jobj = jdoc.object();
+ smw->emit_event(event_name, jobj);
+
+ json_object_put(event_contents);
+}