summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Olshevskyi <i.olshevskyi@samsung.com>2017-08-09 12:01:34 +0300
committerIgor Olshevskyi <i.olshevskyi@samsung.com>2017-08-11 17:14:01 +0300
commit1085f5ad876240377c36a5fa78ec1d840673380f (patch)
tree59550b81e64ba0fca9ccf58efc5686680dd7799a
parent7df53dad9dd42453662f08fa381e2ee953f7e662 (diff)
downloadcall-ui-1085f5ad876240377c36a5fa78ec1d840673380f.tar.gz
call-ui-1085f5ad876240377c36a5fa78ec1d840673380f.tar.bz2
call-ui-1085f5ad876240377c36a5fa78ec1d840673380f.zip
TizenRefApp-9083 [Call UI] Implement Screen Reader highlight logic for KeypadPage
Change-Id: Ib8143cab96a0111dfd6f9b96bf282b22df9fb1e0
-rw-r--r--inc/presenters/KeypadPage.h16
-rw-r--r--project_def.prop2
-rw-r--r--src/presenters/AccessoryPresenter.cpp6
-rw-r--r--src/presenters/KeypadPage.cpp217
-rw-r--r--src/view/common.h1
5 files changed, 205 insertions, 37 deletions
diff --git a/inc/presenters/KeypadPage.h b/inc/presenters/KeypadPage.h
index 027ce64..2ca6a1b 100644
--- a/inc/presenters/KeypadPage.h
+++ b/inc/presenters/KeypadPage.h
@@ -79,6 +79,19 @@ namespace callui {
void registerCallbacks();
void unregisterCallbacks();
+ // Screen Reader
+ ucl::Result createAtspiHighlightHelper();
+ Elm_Interface_Atspi_Accessible *onAtspiHighlight(
+ Elm_Interface_Atspi_Accessible *ao,
+ Elm_Atspi_Relation_Type flowRelation);
+ ucl::ElmWidget *getFirstButton();
+ ucl::ElmWidget *getLastButton();
+ void registerVolumeControlAo();
+ void onVolumeControlScreenReaderReadStart(
+ ucl::Widget &widget,
+ void *eventInfo);
+
+
// Page
virtual void onBackKey() override final;
@@ -94,6 +107,9 @@ namespace callui {
Ecore_Timer *m_vcTimer;
AudioStateType m_audioState;
+
+ // Screen Reader
+ AtspiHighlightHelperSRef m_atspiHelper;
};
}
diff --git a/project_def.prop b/project_def.prop
index 1fe3c17..7bc0ea9 100644
--- a/project_def.prop
+++ b/project_def.prop
@@ -9,7 +9,7 @@ type = app
profile = wearable-4.0
# C/CPP Sources
-USER_SRCS = ucl/src/gui/WidgetItem.cpp src/presenters/InstanceManager.cpp ucl/src/appfw/UIApp.cpp src/model/VoiceControlStateProvider.cpp src/presenters/AcceptDialog.cpp ucl/src/gui/NaviItem.cpp ucl/src/gui/Layout.cpp src/model/IncomingCall.cpp src/presenters/Page.cpp src/resources.cpp src/presenters/DeviceStatePresenter.cpp src/model/ContactInfoProvider.cpp ucl/src/gui/Genlist.cpp ucl/src/gui/Window.cpp src/types.cpp src/presenters/RejectMsgPresenter.cpp src/model/ConnectionStateSource.cpp src/presenters/AccessoryPresenter.cpp src/model/ContactInfo.cpp src/model/EndCall.cpp src/presenters/MainPage.cpp src/view/helpers.cpp ucl/src/mvp/ListItemPresenter.cpp ucl/src/util/types/Result.cpp ucl/src/mvp/ListPresenter.cpp ucl/src/misc/Variant.cpp src/model/CallUI.cpp ucl/src/mvp/GuiPresenter.cpp src/view/VolumeControl.cpp src/view/Slider.cpp src/model/CallInfo.cpp ucl/src/gui/ElmWidget.cpp src/model/SimSlotStateSource.cpp src/presenters/AcceptRejectPresenter.cpp ucl/src/gui/EdjeWidget.cpp ucl/src/gui/Naviframe.cpp src/model/CallManager.cpp ucl/src/misc/Timeout.cpp src/presenters/Instance.cpp ucl/src/gui/Widget.cpp src/model/ActiveCall.cpp src/model/RejectMsgProvider.cpp src/presenters/MoreOptionsPresenter.cpp ucl/src/appfw/SysEventProvider.cpp src/presenters/CallInfoPresenter.cpp src/model/BatteryStateSource.cpp src/model/CallClient.cpp src/model/VoiceControlStateSource.cpp src/model/RssiStateSource.cpp src/model/HdVoiceStateSource.cpp ucl/src/util/logging.cpp src/model/IndicatorStateProvider.cpp src/presenters/KeypadPage.cpp src/presenters/helpers.cpp src/presenters/MotionSensorPresenter.cpp src/main.cpp src/model/MsgClient.cpp src/presenters/IndicatorPresenter.cpp ucl/src/appfw/helpers.cpp src/model/CallUIBuilder.cpp src/presenters/CallStatusPresenter.cpp src/model/ConferenceCallInfo.cpp src/model/HeldCall.cpp src/model/SoundManager.cpp src/model/BluetoothManager.cpp src/model/RejectMsg.cpp src/view/AcceptRejectWidget.cpp ucl/src/appfw/InstanceManagerBase.cpp
+USER_SRCS = ucl/src/gui/WidgetItem.cpp src/presenters/InstanceManager.cpp ucl/src/appfw/UIApp.cpp src/model/VoiceControlStateProvider.cpp src/presenters/AcceptDialog.cpp ucl/src/gui/NaviItem.cpp ucl/src/gui/Layout.cpp src/model/IncomingCall.cpp src/presenters/Page.cpp src/resources.cpp src/presenters/DeviceStatePresenter.cpp src/model/ContactInfoProvider.cpp ucl/src/gui/Genlist.cpp ucl/src/gui/Window.cpp src/types.cpp src/presenters/RejectMsgPresenter.cpp src/model/ConnectionStateSource.cpp src/presenters/AccessoryPresenter.cpp src/model/ContactInfo.cpp src/model/EndCall.cpp src/presenters/MainPage.cpp src/view/helpers.cpp ucl/src/mvp/ListItemPresenter.cpp ucl/src/util/types/Result.cpp ucl/src/mvp/ListPresenter.cpp ucl/src/misc/Variant.cpp src/model/CallUI.cpp ucl/src/mvp/GuiPresenter.cpp src/view/VolumeControl.cpp src/view/Slider.cpp src/model/CallInfo.cpp ucl/src/gui/ElmWidget.cpp src/model/SimSlotStateSource.cpp src/presenters/AcceptRejectPresenter.cpp ucl/src/gui/EdjeWidget.cpp ucl/src/gui/Naviframe.cpp src/model/CallManager.cpp ucl/src/misc/Timeout.cpp src/presenters/Instance.cpp ucl/src/gui/Widget.cpp src/model/ActiveCall.cpp src/model/RejectMsgProvider.cpp src/presenters/MoreOptionsPresenter.cpp ucl/src/appfw/SysEventProvider.cpp src/presenters/CallInfoPresenter.cpp src/model/BatteryStateSource.cpp src/model/CallClient.cpp src/model/VoiceControlStateSource.cpp src/model/RssiStateSource.cpp src/model/HdVoiceStateSource.cpp ucl/src/util/logging.cpp src/model/IndicatorStateProvider.cpp src/presenters/KeypadPage.cpp src/presenters/helpers.cpp src/presenters/MotionSensorPresenter.cpp src/main.cpp src/model/MsgClient.cpp src/presenters/IndicatorPresenter.cpp ucl/src/appfw/helpers.cpp src/model/CallUIBuilder.cpp src/presenters/AtspiHighlightHelper.cpp src/presenters/CallStatusPresenter.cpp src/model/ConferenceCallInfo.cpp src/model/HeldCall.cpp src/model/SoundManager.cpp src/model/BluetoothManager.cpp src/model/RejectMsg.cpp src/view/AcceptRejectWidget.cpp ucl/src/appfw/InstanceManagerBase.cpp
# EDC Sources
USER_EDCS =
diff --git a/src/presenters/AccessoryPresenter.cpp b/src/presenters/AccessoryPresenter.cpp
index 1774f0f..7e15a90 100644
--- a/src/presenters/AccessoryPresenter.cpp
+++ b/src/presenters/AccessoryPresenter.cpp
@@ -51,8 +51,6 @@ namespace callui { namespace { namespace impl {
constexpr EdjeSignal SIGNAL_TURN_ON {"turn.on"};
constexpr EdjeSignal SIGNAL_TURN_OFF {"turn.off"};
-
- constexpr SmartEvent EVENT_ACCESS_READ_START {"access,read,start"};
}}}
namespace callui {
@@ -806,7 +804,7 @@ namespace callui {
{
auto decrBtn = m_vc->getDecreaseBtn();
if (decrBtn) {
- decrBtn->addEventHandler(impl::EVENT_ACCESS_READ_START,
+ decrBtn->addEventHandler(ATSPI_HIGHLIGHTED,
WEAK_DELEGATE(AccessoryPresenter::
onVolumeControlScreenReaderReadStart,
asWeak(*this)));
@@ -814,7 +812,7 @@ namespace callui {
auto incrBtn = m_vc->getIncreaseBtn();
if (incrBtn) {
- incrBtn->addEventHandler(impl::EVENT_ACCESS_READ_START,
+ incrBtn->addEventHandler(ATSPI_HIGHLIGHTED,
WEAK_DELEGATE(AccessoryPresenter::
onVolumeControlScreenReaderReadStart,
asWeak(*this)));
diff --git a/src/presenters/KeypadPage.cpp b/src/presenters/KeypadPage.cpp
index d2f512f..04f0ebe 100644
--- a/src/presenters/KeypadPage.cpp
+++ b/src/presenters/KeypadPage.cpp
@@ -17,6 +17,8 @@
#include "presenters/KeypadPage.h"
#include "view/VolumeControl.h"
+#include "presenters/AtspiHighlightHelper.h"
+
#include "resources.h"
#include "common.h"
@@ -156,59 +158,64 @@ namespace callui {
unregisterCallbacks();
}
+ Result KeypadPage::doPrepare(NaviItem &item)
+ {
+ FAIL_RETURN(createWidget(), "createWidget() failed!");
+
+ FAIL_RETURN(createEntry(), "createEntry() failed!");
+
+ FAIL_RETURN(createButtons(), "createButtons() failed!");
+
+ FAIL_RETURN(createVolumeControl(), "createVolumeControl() failed!");
+
+ registerCallbacks();
+
+ updateVolume(m_sm->getVolume());
+
+ FAIL_RETURN(createAtspiHighlightHelper(),
+ "createAtspiHighlightHelper() failed!");
+
+ item = getNaviframe().push(*m_widget);
+ if (!item) {
+ LOG_RETURN(RES_FAIL, "Naviframe::push() failed!");
+ }
+
+ return RES_OK;
+ }
+
void KeypadPage::onBtnPressed(Widget &widget, void *eventInfo)
{
- impl::ButtonInfo *btn =
+ impl::ButtonInfo *info =
static_cast<impl::ButtonInfo*>(widget.getData(impl::BTN_DATA_KEY));
- ILOG("button pressed: %c", *(btn->str));
+ DLOG("Button pressed [%c]", *(info->str));
- if (btn->type == impl::OperationType::DTMF) {
- elm_entry_entry_append(*m_entry, btn->str);
+ if (info->type == impl::OperationType::DTMF) {
+ elm_entry_entry_append(*m_entry, info->str);
elm_entry_cursor_end_set(*m_entry);
- startDtmf(*(btn->str));
+ startDtmf(*(info->str));
}
}
void KeypadPage::onBtnUnpressed(Widget &widget, void *eventInfo)
{
- impl::ButtonInfo *btn =
+ impl::ButtonInfo *info =
static_cast<impl::ButtonInfo*>(widget.getData(impl::BTN_DATA_KEY));
- ILOG("button unpressed: %c", *(btn->str));
+ DLOG("Button unpressed [%c]", *(info->str));
stopDtmf();
}
void KeypadPage::onBtnClicked(Widget &widget, void *eventInfo)
{
- impl::ButtonInfo *btn =
+ impl::ButtonInfo *info =
static_cast<impl::ButtonInfo*>(widget.getData(impl::BTN_DATA_KEY));
- if(btn->type == impl::OperationType::VOLUME) {
- ILOG("button clicked: volume");
+ if(info->type == impl::OperationType::VOLUME) {
+ DLOG("Button clicked [volume]");
show(*m_vc);
startVCTimer();
- }
- }
-
- Result KeypadPage::doPrepare(NaviItem &item)
- {
- FAIL_RETURN(createWidget(), "createWidget() failed!");
-
- FAIL_RETURN(createEntry(), "createEntry() failed!");
-
- FAIL_RETURN(createButtons(), "createButtons() failed!");
-
- FAIL_RETURN(createVolumeControl(), "createVolumeControl() failed!");
- registerCallbacks();
-
- updateVolume(m_sm->getVolume());
-
- item = getNaviframe().push(*m_widget);
- if (!item) {
- LOG_RETURN(RES_FAIL, "Naviframe::push() failed!");
+ elm_atspi_component_highlight_grab(*m_vc);
}
-
- return RES_OK;
}
Result KeypadPage::createWidget()
@@ -222,6 +229,8 @@ namespace callui {
LOG_RETURN(RES_FAIL, "Layout::build() failed!");
}
+ setDeactivatorSink(m_widget);
+
return RES_OK;
}
@@ -263,6 +272,7 @@ namespace callui {
}
buttonSRef = makeShared<StyledWidget>(button);
+ buttonSRef->bindToEo();
buttonSRef->setData(impl::BTN_DATA_KEY, &(impl::buttonsInfo[i]));
buttonSRef->setStyle(impl::buttonsInfo[i].style);
@@ -280,6 +290,22 @@ namespace callui {
asWeak(*this)));
}
+ // Screen Reader
+ elm_atspi_accessible_name_cb_set(*buttonSRef,
+ [](void *data, Evas_Object *obj) -> char *
+ {
+ impl::ButtonInfo *info =
+ static_cast<impl::ButtonInfo*>(asWidget(obj)->
+ getData(impl::BTN_DATA_KEY));
+ if (info->type == impl::OperationType::DTMF) {
+ return strdup(info->str);
+ } else {
+ return strdup(AO_STR_VOLUME.translate());
+ }
+ return nullptr;
+ },
+ this);
+
m_widget->setContent(button, impl::buttonsInfo[i].swlPart);
show(*buttonSRef);
}
@@ -326,6 +352,8 @@ namespace callui {
m_vc->resize(w, h);
hide(*m_vc);
+ registerVolumeControlAo();
+
return RES_OK;
}
@@ -381,6 +409,12 @@ namespace callui {
m_vc->setIncreaseBtnEnable(true);
m_vc->setDecreaseBtnEnable(true);
}
+
+ // Screen Reader
+ if (m_vc->isVisible()) {
+ elm_atspi_bridge_utils_say(std::to_string(cur).c_str(),
+ EINA_FALSE, nullptr, nullptr);
+ }
}
void KeypadPage::onAudioStateChanged(AudioStateType state)
@@ -417,7 +451,12 @@ namespace callui {
{
stopVCTimer();
- m_vcTimer = ecore_timer_add(CALL_VC_TIMER_INTERVAL,
+ auto timerInterval = CALL_VC_TIMER_INTERVAL;
+ if (elm_atspi_bridge_utils_is_screen_reader_enabled()) {
+ timerInterval = CALL_VC_SCREEN_READER_TIMER_INTERVAL;
+ }
+
+ m_vcTimer = ecore_timer_add(timerInterval,
CALLBACK_B(KeypadPage::onVCTimerCb),
this);
}
@@ -503,4 +542,118 @@ namespace callui {
m_sm->delVolumeStateHandler(DELEGATE(
KeypadPage::onVolumeLevelChanged, this));
}
+
+ // Screen Reader
+ Result KeypadPage::createAtspiHighlightHelper()
+ {
+ m_atspiHelper = AtspiHighlightHelper::newInstance(*this, getWindow());
+ if (!m_atspiHelper) {
+ LOG_RETURN(RES_FAIL,
+ "AtspiHighlightHelper::newInstance() failed!");
+ }
+
+ m_atspiHelper->setRelationEventHandler(WEAK_DELEGATE(
+ KeypadPage::onAtspiHighlight, asWeak(*this)));
+
+ m_atspiHelper->registerWidget(*getFirstButton());
+ m_atspiHelper->registerWidget(*getLastButton());
+ m_atspiHelper->registerWidget(*m_vc.get());
+ m_atspiHelper->registerWidget(*m_vc->getDecreaseBtn());
+ m_atspiHelper->registerWidget(*m_vc->getIncreaseBtn());
+ m_atspiHelper->registerWidget(*m_vc->getValueTxtAo());
+
+ return RES_OK;
+ }
+
+ Elm_Interface_Atspi_Accessible *KeypadPage::onAtspiHighlight(
+ Elm_Interface_Atspi_Accessible *ao,
+ Elm_Atspi_Relation_Type flowRelation)
+ {
+ DLOG("FlowRelation [%s]",
+ flowRelation == ELM_ATSPI_RELATION_FLOWS_FROM ?
+ "FROM" : "TO");
+
+ auto firstBtn = getFirstButton();
+ auto lastBtn = getLastButton();
+ auto vcLayout = m_vc.get();
+ auto vcDecrVolumeBtn = m_vc->getDecreaseBtn();
+ auto vcIncrVolumeBtn = m_vc->getIncreaseBtn();
+ auto vcVolumeValueAo = m_vc->getValueTxtAo();
+
+ if (ao == *firstBtn) {
+ if (flowRelation == ELM_ATSPI_RELATION_FLOWS_TO) {
+ return nullptr;
+ }
+ } else if (ao == *lastBtn) {
+ if (flowRelation == ELM_ATSPI_RELATION_FLOWS_FROM) {
+ return nullptr;
+ }
+ } else if (ao == *vcLayout) {
+ if (flowRelation == ELM_ATSPI_RELATION_FLOWS_TO) {
+ return *vcDecrVolumeBtn;
+ }
+ } else if (ao == *vcDecrVolumeBtn) {
+ if (flowRelation == ELM_ATSPI_RELATION_FLOWS_TO) {
+ return *vcVolumeValueAo;
+ } else {
+ return *vcLayout;
+ }
+ } else if (ao == *vcVolumeValueAo) {
+ if (flowRelation == ELM_ATSPI_RELATION_FLOWS_TO) {
+ return *vcIncrVolumeBtn;
+ } else {
+ return *vcDecrVolumeBtn;
+ }
+ } else if (ao == *vcIncrVolumeBtn) {
+ if (flowRelation == ELM_ATSPI_RELATION_FLOWS_FROM) {
+ return *vcVolumeValueAo;
+ }
+ } else if (ao == getWindow()) {
+ return *firstBtn;
+ } else {
+ LOG_RETURN_VALUE(RES_FAIL, nullptr, "Unknown object!");
+ }
+
+ return ao;
+ }
+
+ ElmWidget *KeypadPage::getFirstButton()
+ {
+ return dynamicWidgetCast<ElmWidget>(
+ m_widget->getContent(impl::buttonsInfo[0].swlPart));
+ }
+
+ ElmWidget *KeypadPage::getLastButton()
+ {
+ return dynamicWidgetCast<ElmWidget>(
+ m_widget->getContent(impl::buttonsInfo[(
+ impl::KEYPAD_BTN_MAX_COUNT - 1)].swlPart));
+ }
+
+ void KeypadPage::registerVolumeControlAo()
+ {
+ auto decrBtn = m_vc->getDecreaseBtn();
+
+ if (decrBtn) {
+ decrBtn->addEventHandler(ATSPI_HIGHLIGHTED,
+ WEAK_DELEGATE(KeypadPage::
+ onVolumeControlScreenReaderReadStart,
+ asWeak(*this)));
+ }
+
+ auto incrBtn = m_vc->getIncreaseBtn();
+ if (incrBtn) {
+ incrBtn->addEventHandler(ATSPI_HIGHLIGHTED,
+ WEAK_DELEGATE(KeypadPage::
+ onVolumeControlScreenReaderReadStart,
+ asWeak(*this)));
+ }
+ }
+
+ void KeypadPage::onVolumeControlScreenReaderReadStart(
+ Widget &widget,
+ void *eventInfo)
+ {
+ restartVCTimer();
+ }
}
diff --git a/src/view/common.h b/src/view/common.h
index 6e6cd0b..7c795fe 100644
--- a/src/view/common.h
+++ b/src/view/common.h
@@ -36,6 +36,7 @@
namespace callui {
constexpr ucl::SmartEvent BTN_CLICKED {"clicked"};
+ constexpr ucl::SmartEvent ATSPI_HIGHLIGHTED {"atspi,highlighted"};
}
#endif // __CALLUI_VIEW_COMMON_H__