add appfwhandler app to access afm-main
authorwang_zhiqiang <wang_zhiqiang@dl.cn.nexty-ele.com>
Fri, 19 Oct 2018 01:26:27 +0000 (09:26 +0800)
committerwang_zhiqiang <wang_zhiqiang@dl.cn.nexty-ele.com>
Fri, 19 Oct 2018 01:26:27 +0000 (09:26 +0800)
Change-Id: Id3b53c439ec832269886c17281d27c7deeb34640

launcher/launcher.pro
launcher/src/appfwhandler.cpp [new file with mode: 0644]
launcher/src/appfwhandler.h [new file with mode: 0644]
package/config.xml

index 7fd1319..1130052 100644 (file)
@@ -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 (file)
index 0000000..7f92b9d
--- /dev/null
@@ -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 (file)
index 0000000..275afeb
--- /dev/null
@@ -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
index 1b5e9cf..d9b15cc 100644 (file)
@@ -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>