/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
// INTERNAL INCLUDES
#include <dali/devel-api/adaptor-framework/environment-variable.h>
#include <dali/devel-api/adaptor-framework/window-devel.h>
+#include <dali/internal/accessibility/bridge/accessibility-common.h>
#include <dali/internal/accessibility/bridge/bridge-accessible.h>
#include <dali/internal/accessibility/bridge/bridge-action.h>
+#include <dali/internal/accessibility/bridge/bridge-application.h>
#include <dali/internal/accessibility/bridge/bridge-collection.h>
#include <dali/internal/accessibility/bridge/bridge-component.h>
#include <dali/internal/accessibility/bridge/bridge-editable-text.h>
-#include <dali/internal/accessibility/bridge/bridge-hypertext.h>
#include <dali/internal/accessibility/bridge/bridge-hyperlink.h>
+#include <dali/internal/accessibility/bridge/bridge-hypertext.h>
#include <dali/internal/accessibility/bridge/bridge-object.h>
#include <dali/internal/accessibility/bridge/bridge-selection.h>
#include <dali/internal/accessibility/bridge/bridge-socket.h>
+#include <dali/internal/accessibility/bridge/bridge-table.h>
+#include <dali/internal/accessibility/bridge/bridge-table-cell.h>
#include <dali/internal/accessibility/bridge/bridge-text.h>
#include <dali/internal/accessibility/bridge/bridge-value.h>
-#include <dali/internal/accessibility/bridge/bridge-application.h>
-#include <dali/internal/accessibility/bridge/dummy-atspi.h>
+#include <dali/internal/accessibility/bridge/dummy/dummy-atspi.h>
#include <dali/internal/adaptor/common/adaptor-impl.h>
#include <dali/internal/system/common/environment-variables.h>
namespace // unnamed namespace
{
-
const int RETRY_INTERVAL = 1000;
} // unnamed namespace
public BridgeApplication,
public BridgeHypertext,
public BridgeHyperlink,
- public BridgeSocket
+ public BridgeSocket,
+ public BridgeTable,
+ public BridgeTableCell
{
- DBus::DBusClient mAccessibilityStatusClient;
- DBus::DBusClient mRegistryClient;
- DBus::DBusClient mDirectReadingClient;
- bool mIsScreenReaderEnabled = false;
- bool mIsEnabled = false;
- std::unordered_map<int32_t, std::function<void(std::string)>> mDirectReadingCallbacks;
+ DBus::DBusClient mAccessibilityStatusClient{};
+ DBus::DBusClient mRegistryClient{};
+ DBus::DBusClient mDirectReadingClient{};
+ bool mIsScreenReaderEnabled{false};
+ bool mIsEnabled{false};
+ std::unordered_map<int32_t, std::function<void(std::string)>> mDirectReadingCallbacks{};
Dali::Actor mHighlightedActor;
- std::function<void(Dali::Actor)> mHighlightClearAction;
- Dali::CallbackBase* mIdleCallback = NULL;
+ std::function<void(Dali::Actor)> mHighlightClearAction{nullptr};
+ Dali::CallbackBase* mIdleCallback{};
Dali::Timer mInitializeTimer;
Dali::Timer mReadIsEnabledTimer;
Dali::Timer mReadScreenReaderEnabledTimer;
Dali::Timer mForceUpTimer;
+ std::string mPreferredBusName;
public:
- BridgeImpl()
- {
- }
+ BridgeImpl() = default;
/**
* @copydoc Dali::Accessibility::Bridge::Emit()
LOG() << "Direct reading command failed (" << msg.getError().message << ")\n";
}
},
- true);
+ true);
}
/**
LOG() << "Direct reading command failed (" << msg.getError().message << ")\n";
}
},
- false);
+ false);
}
/**
LOG() << "Direct reading command failed (" << msg.getError().message << ")\n";
}
},
- alsoNonDiscardable);
+ alsoNonDiscardable);
}
/**
mDirectReadingCallbacks.emplace(std::get<2>(msg), callback);
}
},
- text,
- discardable);
+ text,
+ discardable);
}
/**
mDisabledSignal.Emit();
UnembedSocket(mApplication.GetAddress(), {AtspiDbusNameRegistry, "root"});
+ ReleaseBusName(mPreferredBusName);
}
mHighlightedActor = {};
mHighlightClearAction = {};
BridgeAccessible::ForceDown();
- mRegistryClient = {};
- mDirectReadingClient = {};
+ mRegistryClient = {};
+ mDirectReadingClient = {};
mDirectReadingCallbacks.clear();
mApplication.mChildren.clear();
ClearTimer();
{
Dali::Adaptor::Get().RemoveIdle(mIdleCallback);
}
- mAccessibilityStatusClient = {};
- mDbusServer = {};
- mConnectionPtr = {};
+ mAccessibilityStatusClient = {};
+ mDbusServer = {};
+ mConnectionPtr = {};
}
bool ForceUpTimerCallback()
BridgeHypertext::RegisterInterfaces();
BridgeHyperlink::RegisterInterfaces();
BridgeSocket::RegisterInterfaces();
+ BridgeTable::RegisterInterfaces();
+ BridgeTableCell::RegisterInterfaces();
RegisterOnBridge(&mApplication);
}
});
+ RequestBusName(mPreferredBusName);
+
auto parentAddress = EmbedSocket(mApplication.GetAddress(), {AtspiDbusNameRegistry, "root"});
mApplication.mParent.SetAddress(std::move(parentAddress));
mEnabledSignal.Emit();
}
/**
+ * @brief Sends a signal to dbus that the window is minimized.
+ *
+ * @param[in] window The window to be minimized
+ * @see BridgeObject::Emit()
+ */
+ void EmitMinimize(Dali::Window window)
+ {
+ auto windowAccessible = mApplication.GetWindowAccessible(window);
+ if(windowAccessible)
+ {
+ windowAccessible->Emit(WindowEvent::MINIMIZE, 0);
+ }
+ }
+
+ /**
+ * @brief Sends a signal to dbus that the window is restored.
+ *
+ * @param[in] window The window to be restored
+ * @param[in] detail Restored window state
+ * @see BridgeObject::Emit()
+ */
+ void EmitRestore(Dali::Window window, Dali::Accessibility::WindowRestoreType detail)
+ {
+ auto windowAccessible = mApplication.GetWindowAccessible(window);
+ if(windowAccessible)
+ {
+ windowAccessible->Emit(WindowEvent::RESTORE, static_cast<unsigned int>(detail));
+ }
+ }
+
+ /**
+ * @brief Sends a signal to dbus that the window is maximized.
+ *
+ * @param[in] window The window to be maximized
+ * @see BridgeObject::Emit()
+ */
+ void EmitMaximize(Dali::Window window)
+ {
+ auto windowAccessible = mApplication.GetWindowAccessible(window);
+ if(windowAccessible)
+ {
+ windowAccessible->Emit(WindowEvent::MAXIMIZE, 0);
+ }
+ }
+
+ /**
* @copydoc Dali::Accessibility::Bridge::WindowShown()
*/
void WindowShown(Dali::Window window) override
}
/**
+ * @copydoc Dali::Accessibility::Bridge::WindowMinimized()
+ */
+ void WindowMinimized(Dali::Window window) override
+ {
+ if(IsUp())
+ {
+ EmitMinimize(window);
+ }
+ }
+
+ /**
+ * @copydoc Dali::Accessibility::Bridge::WindowRestored()
+ */
+ void WindowRestored(Dali::Window window, WindowRestoreType detail) override
+ {
+ if(IsUp())
+ {
+ EmitRestore(window, detail);
+ }
+ }
+
+ /**
+ * @copydoc Dali::Accessibility::Bridge::WindowMaximized()
+ */
+ void WindowMaximized(Dali::Window window) override
+ {
+ if(IsUp())
+ {
+ EmitMaximize(window);
+ }
+ }
+
+ /**
* @copydoc Dali::Accessibility::Bridge::SuppressScreenReader()
*/
void SuppressScreenReader(bool suppress) override
void ReadScreenReaderEnabledProperty()
{
// can be true because of SuppressScreenReader before init
- if (!mAccessibilityStatusClient)
+ if(!mAccessibilityStatusClient)
{
return;
}
void EmitScreenReaderEnabledSignal()
{
- if (mIsScreenReaderEnabled)
+ if(mIsScreenReaderEnabled)
{
mScreenReaderEnabledSignal.Emit();
}
{
mAccessibilityStatusClient = DBus::DBusClient{A11yDbusName, A11yDbusPath, A11yDbusStatusInterface, DBus::ConnectionType::SESSION};
- if (!mAccessibilityStatusClient)
+ if(!mAccessibilityStatusClient)
{
DALI_LOG_ERROR("Accessibility Status DbusClient is not ready\n");
return false;
bool InitializeTimerCallback()
{
- if ( InitializeAccessibilityStatusClient() )
+ if(InitializeAccessibilityStatusClient())
{
ReadAndListenProperties();
return false;
bool OnIdleSignal()
{
- if ( InitializeAccessibilityStatusClient() )
+ if(InitializeAccessibilityStatusClient())
{
ReadAndListenProperties();
mIdleCallback = NULL;
*/
void Initialize() override
{
- if ( InitializeAccessibilityStatusClient() )
+ if(InitializeAccessibilityStatusClient())
{
ReadAndListenProperties();
return;
}
// Initialize failed. Try it again on Idle
- if( Dali::Adaptor::IsAvailable() )
+ if(Dali::Adaptor::IsAvailable())
{
Dali::Adaptor& adaptor = Dali::Adaptor::Get();
- if( NULL == mIdleCallback )
+ if(NULL == mIdleCallback)
{
- mIdleCallback = MakeCallback( this, &BridgeImpl::OnIdleSignal );
- adaptor.AddIdle( mIdleCallback, true );
+ mIdleCallback = MakeCallback(this, &BridgeImpl::OnIdleSignal);
+ adaptor.AddIdle(mIdleCallback, true);
}
}
}
{
auto client = CreateSocketClient(socket);
- client.method<void(std::string)>("Embedded").call(ATSPI_PREFIX_PATH + plug.GetPath());
+ client.method<void(std::string)>("Embedded").asyncCall([](DBus::ValueOrError<void>) {}, ATSPI_PREFIX_PATH + plug.GetPath());
}
void UnembedSocket(const Address& plug, const Address& socket) override
{
auto client = CreateSocketClient(socket);
- client.method<void(Address)>("Unembed").call(plug);
+ client.method<void(Address)>("Unembed").asyncCall([](DBus::ValueOrError<void>) {}, plug);
+ }
+
+ void SetSocketOffset(ProxyAccessible* socket, std::int32_t x, std::int32_t y) override
+ {
+ AddCoalescableMessage(CoalescableMessages::SET_OFFSET, socket, 1.0f, [=]() {
+ auto client = CreateSocketClient(socket->GetAddress());
+
+ client.method<void(std::int32_t, std::int32_t)>("SetOffset").asyncCall([](DBus::ValueOrError<void>) {}, x, y);
+ });
+ }
+
+ void SetExtentsOffset(std::int32_t x, std::int32_t y) override
+ {
+ if(mData)
+ {
+ mData->mExtentsOffset = {x, y};
+ }
+ }
+
+ void SetPreferredBusName(std::string_view preferredBusName) override
+ {
+ if(preferredBusName == mPreferredBusName)
+ {
+ return;
+ }
+
+ std::string oldPreferredBusName = std::move(mPreferredBusName);
+ mPreferredBusName = std::string{preferredBusName};
+
+ if(IsUp())
+ {
+ ReleaseBusName(oldPreferredBusName);
+ RequestBusName(mPreferredBusName);
+ }
+ // else: request/release will be handled by ForceUp/ForceDown, respectively
}
private:
{
return {socket.GetBus(), ATSPI_PREFIX_PATH + socket.GetPath(), Accessible::GetInterfaceName(AtspiInterface::SOCKET), mConnectionPtr};
}
+
+ void RequestBusName(const std::string& busName)
+ {
+ if(busName.empty())
+ {
+ return;
+ }
+
+ DBus::requestBusName(mConnectionPtr, busName);
+ }
+
+ void ReleaseBusName(const std::string& busName)
+ {
+ if(busName.empty())
+ {
+ return;
+ }
+
+ DBus::releaseBusName(mConnectionPtr, busName);
+ }
}; // BridgeImpl
namespace // unnamed namespace
{
-
bool INITIALIZED_BRIDGE = false;
/**
bridge->WindowShown(window);
}
}
+
+std::string Bridge::MakeBusNameForWidget(std::string_view widgetInstanceId)
+{
+ // The bus name should consist of dot-separated alphanumeric elements, e.g. "com.example.BusName123".
+ // Allowed characters in each element: "[A-Z][a-z][0-9]_", but no element may start with a digit.
+
+ static const char prefix[] = "com.samsung.dali.widget_";
+ static const char underscore = '_';
+
+ std::stringstream tmp;
+
+ tmp << prefix;
+
+ for(char ch : widgetInstanceId)
+ {
+ tmp << (std::isalnum(ch) ? ch : underscore);
+ }
+
+ return tmp.str();
+}