From fd1fbfdbdddaa659e8148e4ecce7ec33fb8b8ae0 Mon Sep 17 00:00:00 2001 From: zheng_wenlong Date: Thu, 22 Nov 2018 14:30:38 +0900 Subject: dynamic update applist --- launcher/src/appfwhandler.cpp | 212 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 212 insertions(+) create mode 100644 launcher/src/appfwhandler.cpp (limited to 'launcher/src/appfwhandler.cpp') diff --git a/launcher/src/appfwhandler.cpp b/launcher/src/appfwhandler.cpp new file mode 100644 index 0000000..9df6d7d --- /dev/null +++ b/launcher/src/appfwhandler.cpp @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2018 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 +#include +#include "appfwhandler.h" +#include "hmi-debug.h" + +AppFwHandler* AppFwHandler::myself = nullptr; + +// called when pws hangsup +static void _on_pws_hangup(void *closure) +{ + if(AppFwHandler::myself) + AppFwHandler::myself->on_pws_hangup(); +} + +static void _on_pws_reply(void *closure, void *request, struct json_object *obj, const char *error, const char *info) +{ + HMI_DEBUG("AppFwHandler", "%s called,error=[%s], info=[%s], obj=[%s]", __FUNCTION__, error, info, json_object_to_json_string(obj)); + if(json_object_is_type(obj, json_type_object)) { + struct json_object *obj1, *obj2, *obj3; + json_object_object_get_ex(obj, "icon", &obj1); + json_object_object_get_ex(obj, "name", &obj2); + json_object_object_get_ex(obj, "id", &obj3); + if(json_object_is_type(obj3, json_type_null)) + return; + QString icon = json_object_get_string(obj1); + QString name = json_object_get_string(obj2); + QString id = json_object_get_string(obj3); + QStringList info; + info << icon << name << id; + emit AppFwHandler::myself->applistupdate(info); + } +} + +static void _on_pws_event_broadcast(void *closure, const char *event_name, struct json_object *data) +{ + HMI_DEBUG("AppFwHandler", "%s called,event=%s, [%s]", __FUNCTION__, event_name, json_object_to_json_string(data)); + QStringList list = QString(event_name).split('/'); + if(list[0] == "afm-main" && list[1] == "application-list-changed") { + struct json_object *obj1, *obj2; + json_object_object_get_ex(data, "operation", &obj1); + json_object_object_get_ex(data, "data", &obj2); + QString oper = json_object_get_string(obj1); + QString id = json_object_get_string(obj2); + + if(oper == "uninstall") { + QStringList info; + // icon, name, id + info << "" << "" << id; + emit AppFwHandler::myself->applistupdate(info); + } + else if (oper == "install") { + // call state + AppFwHandler::myself->detail(id); + } + else { + HMI_DEBUG("AppFwHandler","data error"); + } + } +} + +// the callback interface for pws +static struct afb_proto_ws_client_itf pws_itf = { + .on_reply = _on_pws_reply, + .on_event_create = nullptr, + .on_event_remove = nullptr, + .on_event_subscribe = nullptr, + .on_event_unsubscribe = nullptr, + .on_event_push = nullptr, + .on_event_broadcast = _on_pws_event_broadcast, +}; + +AppFwHandler::AppFwHandler(const char* appname, QObject *parent) : QObject(parent) +{ + myself = this; + int uid = getuid(); + QString _uid; + if(uid == 0) + _uid = QString('0'); + else + _uid = QString(uid); + + m_sessionid = _uid + QString(appname); + m_uri = "unix:/run/user/" + _uid + "/apis/ws/afm-main"; + HMI_NOTICE("AppFwHandler","m_uri=%s, m_sessionid=%s", m_uri.toStdString().c_str(), m_sessionid.toStdString().c_str()); +} + +int AppFwHandler::init(void) +{ + // get default loop + int rc = sd_event_default(&m_evloop); + if(rc < 0) + { + HMI_ERROR("AppFwHandler", "can't create event loop"); + return 1; + } + + // connect to framework + if (!try_connect_pws()) { + HMI_ERROR("connection to %s failed: %m\n", m_uri.toStdString().c_str()); + return 1; + } +// runnables(); + return 0; +} + +int AppFwHandler::runnables(void) +{ + int ret = 1; + if(call(__FUNCTION__, "{\"info\":\"test my guess\"}") < 0) + ret = 0; + return ret; +} + +int AppFwHandler::detail(QString id) +{ + int ret = 1; + HMI_DEBUG("AppFwHandler", "detail id is %s\n", id.toStdString().c_str()); + if(call(__FUNCTION__, id.toStdString().c_str()) < 0) + ret = 0; + return ret; +} + +int AppFwHandler::try_connect_pws(void) +{ + m_pws = afb_ws_client_connect_api(m_evloop, m_uri.toStdString().c_str(), &pws_itf, NULL); + if (m_pws == nullptr) { + HMI_ERROR("AppFwHandler", "connection to %s failed!\n", m_uri.toStdString().c_str()); + return 0; + } + afb_proto_ws_on_hangup(m_pws, _on_pws_hangup); + return 1; +} + +void AppFwHandler::on_pws_hangup(void) +{ + struct afb_proto_ws *apw = m_pws; + m_pws = nullptr; + afb_proto_ws_unref(apw); + attempt_connect_pws(10); +} + +void AppFwHandler::attempt_connect_pws(int count) +{ + if(m_time != nullptr) { + HMI_NOTICE("AppFwHandler", "attempt_connect_pws retrying!\n"); + return; + } + if(count > 0) + m_retry = count; + else + return; + + m_time = new QTimer(this); + connect(m_time, SIGNAL(timeout()), this, SLOT(connect_pws_timer_slot())); + m_time->start(5000); +} + +void AppFwHandler::connect_pws_timer_slot(void) +{ + --m_retry; + int ret = try_connect_pws(); + if(ret) { + m_retry = 0; + disconnect(m_time, 0, 0, 0); + delete m_time; + m_time = nullptr; + } + else { + if(m_retry > 0) + m_time->start(5000); + } +} + +int AppFwHandler::call(const char *verb, const char *object) +{ + static int num = 0; + if(verb == nullptr) { + HMI_NOTICE("AppFwHandler", "parameter is null!\n"); + return 0; + } + num++; + + QString key = QString(num) + ':' + QString(verb); + enum json_tokener_error jerr; + struct json_object *obj = json_tokener_parse_verbose(object, &jerr); + if (jerr != json_tokener_success) + obj = json_object_new_string(object); + + int rc = afb_proto_ws_client_call(m_pws, verb, obj, m_sessionid.toStdString().c_str(), key.toLatin1().data(), NULL); + json_object_put(obj); + if (rc < 0) { + HMI_ERROR("AppFwHandler", "calling %s(%s) failed!\n", verb, object); + } + + return rc; +} -- cgit 1.2.3-korg