diff options
author | wang_zhiqiang <wang_zhiqiang@dl.cn.nexty-ele.com> | 2018-10-19 09:26:27 +0800 |
---|---|---|
committer | wang_zhiqiang <wang_zhiqiang@dl.cn.nexty-ele.com> | 2018-10-19 09:26:27 +0800 |
commit | 840301eadc6deb4e8ed9b910f9c30b4b7e6195b4 (patch) | |
tree | 2a2191fac1358780de49dfaa236e02c3139abb09 | |
parent | 3c25a2edfe2772e42d5f60b79b8cc2bae59f9302 (diff) |
add appfwhandler app to access afm-main
Change-Id: Id3b53c439ec832269886c17281d27c7deeb34640
-rw-r--r-- | launcher/launcher.pro | 8 | ||||
-rw-r--r-- | launcher/src/appfwhandler.cpp | 170 | ||||
-rw-r--r-- | launcher/src/appfwhandler.h | 75 | ||||
-rw-r--r-- | package/config.xml | 1 |
4 files changed, 251 insertions, 3 deletions
diff --git a/launcher/launcher.pro b/launcher/launcher.pro index 7fd1319..1130052 100644 --- a/launcher/launcher.pro +++ b/launcher/launcher.pro @@ -18,7 +18,7 @@ TARGET = launcher QT = qml quick dbus websockets CONFIG += c++11 link_pkgconfig DESTDIR = $${OUT_PWD}/../package/root/bin -PKGCONFIG += qlibwindowmanager qlibhomescreen +PKGCONFIG += qlibwindowmanager qlibhomescreen libafbwsc include(../interfaces/interfaces.pri) @@ -26,12 +26,14 @@ SOURCES += \ src/main.cpp \ src/applicationmodel.cpp \ src/appinfo.cpp \ - src/applicationlauncher.cpp + src/applicationlauncher.cpp \ + src/appfwhandler.cpp HEADERS += \ src/applicationlauncher.h \ src/applicationmodel.h \ - src/appinfo.h + src/appinfo.h \ + src/appfwhandler.h OTHER_FILES += \ README.md diff --git a/launcher/src/appfwhandler.cpp b/launcher/src/appfwhandler.cpp new file mode 100644 index 0000000..7f92b9d --- /dev/null +++ b/launcher/src/appfwhandler.cpp @@ -0,0 +1,170 @@ +/* + * 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 <unistd.h> +#include <sys/types.h> +#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)); +} + +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") + emit AppFwHandler::myself->applistupdate(data); +} + +// 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::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; +} diff --git a/launcher/src/appfwhandler.h b/launcher/src/appfwhandler.h new file mode 100644 index 0000000..275afeb --- /dev/null +++ b/launcher/src/appfwhandler.h @@ -0,0 +1,75 @@ +/* + * 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. + */ + +#ifndef APPFWHANDLER_H +#define APPFWHANDLER_H + +#include <QObject> +#include <QString> +#include <QTimer> +#include <json-c/json.h> +#include <systemd/sd-event.h> +extern "C" { +#include <afb/afb-proto-ws.h> +#include <afb/afb-ws-client.h> +} + +class AppFwHandler : public QObject +{ + Q_OBJECT +public: + AppFwHandler(const char* appname, QObject *parent = nullptr); + AppFwHandler(AppFwHandler&) = delete; + AppFwHandler &operator=(AppFwHandler&) = delete; + ~AppFwHandler() = default; + + int init(void); + int runnables(void); + void on_pws_hangup(void); + void registerCallback( + /* can't be NULL */ + void (*on_reply_cb)(void *closure, void *request, struct json_object *obj, const char *error, const char *info), + + /* can be NULL */ + void (*on_event_create_cb)(void *closure, const char *event_name, int event_id) = nullptr, + void (*on_event_remove_cb)(void *closure, const char *event_name, int event_id) = nullptr, + void (*on_event_subscribe_cb)(void *closure, void *request, const char *event_name, int event_id) = nullptr, + void (*on_event_unsubscribe_cb)(void *closure, void *request, const char *event_name, int event_id) = nullptr, + void (*on_event_push_cb)(void *closure, const char *event_name, int event_id, struct json_object *data) = nullptr, + void (*on_event_broadcast_cb)(void *closure, const char *event_name, struct json_object *data) = nullptr); + + static AppFwHandler* myself; +signals: + void applistupdate(struct json_object * obj); + +private slots: + void connect_pws_timer_slot(void); + +private: + int try_connect_pws(void); + void attempt_connect_pws(int count); + int call(const char *verb, const char *object); + + QString m_api = "afm-main"; + QString m_uri; + QString m_sessionid; + sd_event *m_evloop = nullptr; + afb_proto_ws *m_pws = nullptr; + QTimer* m_time; + int m_retry = 0; +}; + +#endif // APPFWHANDLER_H diff --git a/package/config.xml b/package/config.xml index 1b5e9cf..d9b15cc 100644 --- a/package/config.xml +++ b/package/config.xml @@ -15,5 +15,6 @@ <param name="urn:AGL:permission::public:no-htdocs" value="required" /> <param name="urn:AGL:permission::system:run-by-default" value="required" /> <param name="http://tizen.org/privilege/internal/dbus" value="required" /> + <param name="urn:AGL:permission:afm:system:widget" value="required" /> </feature> </widget> |