Implementing app launch and app surface control workflow. Using WindowManager to...
authorBocklage, Jens <Jens_Bocklage@mentor.com>
Fri, 30 Sep 2016 12:31:09 +0000 (14:31 +0200)
committerBocklage, Jens <Jens_Bocklage@mentor.com>
Fri, 30 Sep 2016 12:31:09 +0000 (14:31 +0200)
Defining three layouts. Adding combobox selection feature to popup widget.

Known issue: IVI-shell is currently disabled in AGL due to issues (porting to Yocto 2.1.1).

Signed-off-by: Bocklage, Jens <Jens_Bocklage@mentor.com>
HomeScreen/src/layouthandler.cpp [new file with mode: 0644]
HomeScreen/src/layouthandler.h [new file with mode: 0644]
interfaces/include/windowmanager.hpp [new file with mode: 0644]
interfaces/src/windowmanager.cpp [new file with mode: 0644]
interfaces/windowmanager.xml [new file with mode: 0644]

diff --git a/HomeScreen/src/layouthandler.cpp b/HomeScreen/src/layouthandler.cpp
new file mode 100644 (file)
index 0000000..a4d0f91
--- /dev/null
@@ -0,0 +1,180 @@
+#include "layouthandler.h"
+
+LayoutHandler::LayoutHandler(QObject *parent) :
+    QObject(parent),
+    mp_dBusWindowManagerProxy(0),
+    mp_dBusPopupProxy(0),
+    m_visibleApps(),
+    m_invisibleApps(),
+    m_requestsToBeVisibleApps()
+{
+    qDBusRegisterMetaType<SimplePoint>();
+    qDBusRegisterMetaType<QList<SimplePoint> >();
+    qDBusRegisterMetaType<SimpleRect>();
+    qDBusRegisterMetaType<QList<SimpleRect> >();
+
+    qDebug("D-Bus: connect to org.agl.windowmanager /windowmanager");
+    mp_dBusWindowManagerProxy = new org::agl::windowmanager("org.agl.windowmanager",
+                                              "/windowmanager",
+                                              QDBusConnection::sessionBus(),
+                                              0);
+    qDebug("D-Bus: connect to org.agl.homescreen /Popup");
+    mp_dBusPopupProxy = new org::agl::popup("org.agl.homescreen",
+                                              "/Popup",
+                                              QDBusConnection::sessionBus(),
+                                              0);
+}
+
+LayoutHandler::~LayoutHandler()
+{
+    delete mp_dBusPopupProxy;
+    delete mp_dBusWindowManagerProxy;
+}
+
+void LayoutHandler::setUpLayers()
+{
+    qDebug("setUpLayers");
+    QList<SimpleRect> surfaceAreas;
+    SimpleRect surfaceArea;
+
+    const int SCREEN_WIDTH = 1080;
+    const int SCREEN_HEIGHT = 1080;
+
+    const int STATUSBAR_HEIGHT = 60;
+    const int STATUSBAR_WIDTH = SCREEN_WIDTH;
+    const int STATUSBAR_X = 0;
+    const int STATUSBAR_Y = 0;
+    const int CONTROLBAR_HEIGHT = 60;
+    const int CONTROLBAR_WIDTH = SCREEN_WIDTH;
+    const int CONTROLBAR_X = 0;
+    const int CONTROLBAR_Y = SCREEN_HEIGHT - CONTROLBAR_HEIGHT;
+
+
+    // layout 1:
+    // one app surface, statusbar, control bar
+    surfaceArea.x = 0;
+    surfaceArea.y = STATUSBAR_HEIGHT;
+    surfaceArea.width = SCREEN_WIDTH;
+    surfaceArea.height = SCREEN_HEIGHT - STATUSBAR_HEIGHT - CONTROLBAR_HEIGHT;
+
+    surfaceAreas.append(surfaceArea);
+
+    mp_dBusWindowManagerProxy->addLayout(1, "one app", surfaceAreas);
+
+
+    surfaceAreas.clear();
+
+    // layout 2:
+    // two app surfaces (one on top of the other), statusbar, control bar
+
+    // top surface
+    surfaceArea.x = 0;
+    surfaceArea.y = STATUSBAR_HEIGHT;
+    surfaceArea.width = SCREEN_WIDTH;
+    surfaceArea.height = (SCREEN_HEIGHT - STATUSBAR_HEIGHT - CONTROLBAR_HEIGHT) / 2;
+
+    surfaceAreas.append(surfaceArea);
+
+    // bottom surface
+    surfaceArea.x = 0;
+    surfaceArea.y = STATUSBAR_HEIGHT / 2;
+    surfaceArea.width = SCREEN_WIDTH;
+    surfaceArea.height = (SCREEN_HEIGHT - STATUSBAR_HEIGHT - CONTROLBAR_HEIGHT) / 2;
+
+    surfaceAreas.append(surfaceArea);
+
+    mp_dBusWindowManagerProxy->addLayout(2, "top on bottom", surfaceAreas);
+
+
+    surfaceAreas.clear();
+
+    // layout 3:
+    // two app surfaces (one besides the other), statusbar, control bar
+
+    // left surface
+    surfaceArea.x = 0;
+    surfaceArea.y = STATUSBAR_HEIGHT;
+    surfaceArea.width = SCREEN_WIDTH / 2;
+    surfaceArea.height = SCREEN_HEIGHT - STATUSBAR_HEIGHT - CONTROLBAR_HEIGHT;
+
+    surfaceAreas.append(surfaceArea);
+
+    // right surface
+    surfaceArea.x = SCREEN_WIDTH / 2;
+    surfaceArea.y = STATUSBAR_HEIGHT;
+    surfaceArea.width = SCREEN_WIDTH / 2;
+    surfaceArea.height = SCREEN_HEIGHT - STATUSBAR_HEIGHT - CONTROLBAR_HEIGHT;
+
+    surfaceAreas.append(surfaceArea);
+
+    mp_dBusWindowManagerProxy->addLayout(3, "side by side", surfaceAreas);
+
+}
+
+void LayoutHandler::makeMeVisible(int pid)
+{
+    qDebug("makeMeVisible %d", pid);
+    m_requestsToBeVisibleApps.append(pid);
+
+    qDebug("m_visibleApps %d", m_visibleApps.size());
+    qDebug("m_invisibleApps %d", m_invisibleApps.size());
+    qDebug("m_requestsToBeVisibleApps %d", m_requestsToBeVisibleApps.size());
+
+    QList<int> availableLayouts = mp_dBusWindowManagerProxy->getAvailableLayouts(m_visibleApps.size() + m_requestsToBeVisibleApps.size());
+    if (0 == availableLayouts.size())
+    {
+        // no layout fits the need!
+        // replace the last app
+        qDebug("no layout fits the need!");
+        qDebug("replace the last app");
+
+        m_invisibleApps.append(m_visibleApps.last());
+        m_visibleApps.removeLast();
+
+        for (int i = 0; i < m_visibleApps.size(); ++i)
+        {
+            mp_dBusWindowManagerProxy->setSurfaceToLayoutArea(i, i);
+        }
+    }
+    if (1 == availableLayouts.size())
+    {
+        // switch to new layout
+        qDebug("switch to new layout %d", availableLayouts.at(0));
+        m_visibleApps.append(m_requestsToBeVisibleApps);
+        m_requestsToBeVisibleApps.clear();
+
+        mp_dBusWindowManagerProxy->setLayoutById(availableLayouts.at(0));
+        for (int i = 0; i < m_visibleApps.size(); ++i)
+        {
+            mp_dBusWindowManagerProxy->setSurfaceToLayoutArea(i, i);
+        }
+    }
+    if (1 < availableLayouts.size())
+    {
+        // more than one layout possible! Ask user.
+        qDebug("more than one layout possible! Ask user.");
+
+        QStringList choices;
+        for (int i = 0; i < availableLayouts.size(); ++i)
+        {
+            choices.append(mp_dBusWindowManagerProxy->getLayoutName(availableLayouts.at(i)));
+        }
+
+        mp_dBusPopupProxy->showPopupComboBox("Select Layout", choices);
+
+    }
+}
+
+void LayoutHandler::setLayoutByName(QString layoutName)
+{
+    // switch to new layout
+    qDebug("setLayout: switch to new layout %s", layoutName.toStdString().c_str());
+    m_visibleApps.append(m_requestsToBeVisibleApps);
+    m_requestsToBeVisibleApps.clear();
+
+    mp_dBusWindowManagerProxy->setLayoutByName(layoutName);
+    for (int i = 0; i < m_visibleApps.size(); ++i)
+    {
+        mp_dBusWindowManagerProxy->setSurfaceToLayoutArea(i, i);
+    }
+}
diff --git a/HomeScreen/src/layouthandler.h b/HomeScreen/src/layouthandler.h
new file mode 100644 (file)
index 0000000..62e4fb5
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef LAYOUTHANDLER_H
+#define LAYOUTHANDLER_H
+
+#include <QObject>
+#include "windowmanager_proxy.h"
+#include "popup_proxy.h"
+
+class LayoutHandler : public QObject
+{
+    Q_OBJECT
+public:
+    explicit LayoutHandler(QObject *parent = 0);
+    ~LayoutHandler();
+
+    void setUpLayers();
+
+signals:
+
+public slots:
+    void makeMeVisible(int pid);
+    void setLayoutByName(QString layoutName);
+
+private:
+    org::agl::windowmanager *mp_dBusWindowManagerProxy;
+    org::agl::popup *mp_dBusPopupProxy;
+
+    QList<int> m_visibleApps;
+    QList<int> m_invisibleApps;
+    QList<int> m_requestsToBeVisibleApps;
+
+};
+
+#endif // LAYOUTHANDLER_H
diff --git a/interfaces/include/windowmanager.hpp b/interfaces/include/windowmanager.hpp
new file mode 100644 (file)
index 0000000..b587b70
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2016 Mentor Graphics Development (Deutschland) GmbH
+ *
+ * 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 WINDOWMANAGER_H
+#define WINDOWMANAGER_H
+
+#include <QtDBus>
+
+class SimplePoint
+{
+public:
+    SimplePoint();
+    virtual ~SimplePoint();
+
+       int x;
+       int y;
+
+    friend QDBusArgument &operator <<(QDBusArgument &argument, const SimplePoint &mSimplePoint);
+    friend const QDBusArgument &operator >>(const QDBusArgument &argument, SimplePoint &mSimplePoint);
+};
+
+
+class SimpleRect
+{
+public:
+    SimpleRect();
+    virtual ~SimpleRect();
+
+       int x;
+       int y;
+       int width;
+       int height;
+
+    friend QDBusArgument &operator <<(QDBusArgument &argument, const SimpleRect &mSimpleRect);
+    friend const QDBusArgument &operator >>(const QDBusArgument &argument, SimpleRect &mSimpleRect);
+};
+
+
+Q_DECLARE_METATYPE(SimplePoint)
+Q_DECLARE_METATYPE(QList<SimplePoint>)
+
+Q_DECLARE_METATYPE(SimpleRect)
+Q_DECLARE_METATYPE(QList<SimpleRect>)
+
+
+#endif // WINDOWMANAGER_H
diff --git a/interfaces/src/windowmanager.cpp b/interfaces/src/windowmanager.cpp
new file mode 100644 (file)
index 0000000..12f425e
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2016 Mentor Graphics Development (Deutschland) GmbH
+ *
+ * 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/windowmanager.hpp"
+
+SimplePoint::SimplePoint()
+{
+}
+
+SimplePoint::~SimplePoint()
+{
+}
+
+
+SimpleRect::SimpleRect()
+{
+}
+
+SimpleRect::~SimpleRect()
+{
+}
+
+QDBusArgument &operator <<(QDBusArgument &argument, const SimplePoint &mSimplePoint)
+{
+       argument.beginStructure();
+       argument << mSimplePoint.x;
+       argument << mSimplePoint.y;
+       argument.endStructure();
+
+       return argument;
+}
+
+const QDBusArgument &operator >>(const QDBusArgument &argument, SimplePoint &mSimplePoint)
+{
+       argument.beginStructure();
+    argument >> mSimplePoint.x;
+    argument >> mSimplePoint.y;
+       argument.endStructure();
+       return argument;
+}
+
+QDBusArgument &operator <<(QDBusArgument &argument, const SimpleRect &mSimpleRect)
+{
+       argument.beginStructure();
+       argument << mSimpleRect.x;
+       argument << mSimpleRect.y;
+       argument << mSimpleRect.width;
+       argument << mSimpleRect.height;
+       argument.endStructure();
+
+       return argument;
+}
+
+const QDBusArgument &operator >>(const QDBusArgument &argument, SimpleRect &mSimpleRect)
+{
+       argument.beginStructure();
+    argument >> mSimpleRect.x;
+    argument >> mSimpleRect.y;
+    argument >> mSimpleRect.width;
+    argument >> mSimpleRect.height;
+       argument.endStructure();
+       return argument;
+}
+
diff --git a/interfaces/windowmanager.xml b/interfaces/windowmanager.xml
new file mode 100644 (file)
index 0000000..9c1e7fe
--- /dev/null
@@ -0,0 +1,52 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<!-- Copyright (C) 2016 Mentor Graphics Development (Deutschland) GmbH
+
+ 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. -->
+<node>
+  <interface name="org.agl.windowmanager">
+      <method name="addLayout">
+        <arg name="layoutId" type="i" direction="in"/>
+        <arg name="layoutName" type="s" direction="in"/>
+        <arg name="surfaceAreas" type="a(iiii)" direction="in"/>
+        <annotation name="org.qtproject.QtDBus.QtTypeName.In2" value="QList&lt;SimpleRect&gt;"/>
+        <arg name="error" type="i" direction="out"/>
+      </method>
+      <method name="getAvailableLayouts">
+        <arg name="numberOfAppSurfaces" type="i" direction="in"/>
+        <arg name="layoutIds" type="ai" direction="out"/>
+        <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QList&lt;int&gt;"/>
+      </method>
+      <method name="setLayoutById">
+        <arg name="layoutId" type="i" direction="in"/>
+      </method>
+      <method name="setLayoutByName">
+        <arg name="layoutName" type="s" direction="in"/>
+      </method>
+      <method name="getLayout">
+        <arg name="layoutId" type="i" direction="out"/>
+      </method>
+      <method name="setSurfaceToLayoutArea">
+        <arg name="surfaceId" type="i" direction="in"/>
+        <arg name="layoutAreaId" type="i" direction="in"/>
+      </method>
+      <method name="getAvailableSurfaces">
+        <arg name="surfacesAndPids" type="a(ii)" direction="out"/>
+        <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QList&lt;SimplePoint&gt;"/>
+      </method>
+      <method name="getLayoutName">
+        <arg name="layoutId" type="i" direction="in"/>
+        <arg name="layoutName" type="s" direction="out"/>
+      </method>
+  </interface>
+</node>
+