* limitations under the License.
*/
-/*
-#define CU_BTN_VOLUME_EFF_DEFAULT_SIZE 160 160
-#define CU_BTN_VOLUME_EFF_PRESSED_SIZE 144 144
-#define CU_BTN_VOLUME_ICON_SIZE 64 64
-
-#define CU_BTN_VOLUME_CONTROL(_name, _icon)
- group { "elm/button/base/"_name;
- images {
- image: "w_call_button_press_circle.png" COMP;
- image: _icon COMP;
- }
- parts {
- image { "image.bg";
- nomouse;
- scale;
- desc { "default";
- fixed: 1 1;
- min: CU_BTN_VOLUME_EFF_DEFAULT_SIZE;
- image.normal: "w_call_button_press_circle.png";
- color: 255 255 255 0;
- }
- desc { "pressed_effect";
- inherit: "default";
- min: CU_BTN_VOLUME_EFF_PRESSED_SIZE;
- color: 255 255 255 33;
- }
- desc { "pressed";
- inherit: "pressed_effect";
- min: CU_BTN_VOLUME_EFF_DEFAULT_SIZE;
- }
- }
- image { "icon";
- scale;
- desc { "default";
- min: CU_BTN_VOLUME_ICON_SIZE;
- max: CU_BTN_VOLUME_ICON_SIZE;
- image.normal: _icon;
- }
- }
- }
- programs {
- program {
- signal: "mouse,clicked,*";
- source: "icon";
- action: SIGNAL_EMIT "elm,action,click" "";
- }
- program {
- signal: "mouse,down,*";
- source: "icon";
- sequence {
- action: STATE_SET "pressed_effect";
- target: "image.bg";
- action: STATE_SET "pressed";
- target: "image.bg";
- transition: TRANSITION_GLIDE(0.3);
- }
- }
- program {
- signal: "mouse,up,*";
- source: "icon";
- action: STATE_SET "default";
- target: "image.bg";
- transition: LINEAR 0.535;
- }
- }
-*/
-
group { "elm/layout/callui/accessory";
parts {
swallow { "swl.volume_control"
}
}
spacer { "pad.top";
- scale;
- desc { "default";
+ scale;
+ desc { "default";
min: CU_VOLUME_PAD_TOP_MIN;
fixed: 0 1;
rel1 { relative: 0.0 0.0; to: "sizer"; }
rel2 { relative: 1.0 0.0; to: "sizer"; }
align: 0.0 0.0;
- }
- }
- spacer { "pad.bottom";
- scale;
+ }
+ }
+ spacer { "pad.bottom";
+ scale;
desc { "default";
min: CU_VOLUME_PAD_BOTTOM_MIN;
fixed: 0 1;
rel2 { relative: 1.0 1.0; to: "sizer"; }
align: 0.0 1.0;
}
- }
- spacer { "action_zone";
- scale;
- desc { "default";
- min: CU_VOLUME_ACTION_ZONE_MIN;
- max: CU_VOLUME_ACTION_ZONE_MIN;
- fixed: 1 1;
- rel1 { relative: 0.0 1.0; to_y: "pad.top"; }
- rel2 { relative: 1.0 1.0; to_y: "pad.top"; }
- align: 0.5 0.0;
- }
- }
- spacer { "txt.value.pad.bottom";
- scale;
+ }
+ spacer { "action_zone";
+ scale;
+ desc { "default";
+ min: CU_VOLUME_ACTION_ZONE_MIN;
+ max: CU_VOLUME_ACTION_ZONE_MIN;
+ fixed: 1 1;
+ rel1 { relative: 0.0 1.0; to_y: "pad.top"; }
+ rel2 { relative: 1.0 1.0; to_y: "pad.top"; }
+ align: 0.5 0.0;
+ }
+ }
+ spacer { "txt.value.pad.bottom";
+ scale;
desc { "default";
min: CU_VOLUME_ACTION_BTN_MIN;
fixed: 0 1;
}
}
swallow { "swl.minus";
- scale;
- desc { "default";
- min: CU_VOLUME_ACTION_BTN_SIZE;
- max: CU_VOLUME_ACTION_BTN_SIZE;
- fixed: 1 1;
- rel1 { relative: 0.0 0.0; to: "action_zone"; }
- rel2 { relative: 0.0 1.0; to: "action_zone"; }
- align: 0.0 0.5;
- }
- desc { "hide";
+ scale;
+ desc { "default";
+ min: CU_VOLUME_ACTION_BTN_SIZE;
+ max: CU_VOLUME_ACTION_BTN_SIZE;
+ fixed: 1 1;
+ rel1 { relative: 0.0 0.0; to: "action_zone"; }
+ rel2 { relative: 0.0 1.0; to: "action_zone"; }
+ align: 0.0 0.5;
+ }
+ desc { "hide";
hid;
}
}
swallow { "swl.plus";
- scale;
- desc { "default";
- min: CU_VOLUME_ACTION_BTN_SIZE;
- max: CU_VOLUME_ACTION_BTN_SIZE;
- fixed: 1 1;
- rel1 { relative: 1.0 0.0; to: "action_zone"; }
- rel2 { relative: 1.0 1.0; to: "action_zone"; }
- align: 1.0 0.5;
- }
- desc { "hide";
+ scale;
+ desc { "default";
+ min: CU_VOLUME_ACTION_BTN_SIZE;
+ max: CU_VOLUME_ACTION_BTN_SIZE;
+ fixed: 1 1;
+ rel1 { relative: 1.0 0.0; to: "action_zone"; }
+ rel2 { relative: 1.0 1.0; to: "action_zone"; }
+ align: 1.0 0.5;
+ }
+ desc { "hide";
hid;
}
- }
+ }
spacer { "txt.info.zone";
scale;
- desc { "default";
- min: CU_VOLUME_INFO_TXT_ZONE_MIN;
- fixed: 1 1;
- rel1 { relative: 0.5 0.0; to_y: "pad.bottom"; }
+ desc { "default";
+ min: CU_VOLUME_INFO_TXT_ZONE_MIN;
+ fixed: 1 1;
+ rel1 { relative: 0.5 0.0; to_y: "pad.bottom"; }
rel2 { relative: 0.5 0.0; to_y: "pad.bottom"; }
align: 0.5 1.0;
}
}
textblock { "txt.info";
scale;
- desc { "default";
- min: CU_VOLUME_INFO_TXT_MIN;
- fixed: 1 1;
- rel1 { relative: 0.5 0.5; to_y: "txt.info.zone"; }
+ desc { "default";
+ min: CU_VOLUME_INFO_TXT_MIN;
+ fixed: 1 1;
+ rel1 { relative: 0.5 0.5; to_y: "txt.info.zone"; }
rel2 { relative: 0.5 0.5; to_y: "txt.info.zone"; }
text.style: "volume_info";
}
virtual bool getMuteState() const = 0;
virtual ucl::Result startDtmf(const unsigned char dtmfDigit) = 0;
virtual ucl::Result stopDtmf() = 0;
- virtual void addAudioStateChangeHandler(AudioStateHandler handler) = 0;
- virtual void removeAudioStateChangeHandler(AudioStateHandler handler) = 0;
- virtual void addMuteStateChangeHandler(MuteStateHandler handler) = 0;
- virtual void removeMuteStateChangeHandler(MuteStateHandler handler) = 0;
+ virtual void addAudioStateHandler(AudioStateHandler handler) = 0;
+ virtual void removeAudioStateHandler(AudioStateHandler handler) = 0;
+ virtual void addMuteStateHandler(MuteStateHandler handler) = 0;
+ virtual void removeMuteStateHandler(MuteStateHandler handler) = 0;
+ virtual void addVolumeStateHandler(VolumeLevelHandler handler) = 0;
+ virtual void removeVolumeStateHandler(VolumeLevelHandler handler) = 0;
+ virtual int getMaxVolume() const = 0;
+ virtual int getVolume() const = 0;
+ virtual ucl::Result setVolume(int value) = 0;
};
}
using AudioStateHandler = ucl::Delegate<void(AudioStateType)>;
using MuteStateHandler = ucl::Delegate<void(bool)>;
+ using VolumeLevelHandler = ucl::Delegate<void(int)>;
using ConfMemberList = std::vector<IConferenceCallInfoSCRef>;
using RejectMsgList = std::vector<IRejectMsgSRef>;
--- /dev/null
+/*
+ * Copyright 2017 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * 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 __CALLUI_PRESENTERS_ACCESSORY_PRESENTER_H__
+#define __CALLUI_PRESENTERS_ACCESSORY_PRESENTER_H__
+
+#include "Presenter.h"
+
+#include "ucl/gui/Layout.h"
+
+#include "types.h"
+
+namespace callui {
+
+ class AccessoryPresenter final : public Presenter {
+ public:
+ class Builder {
+ public:
+ Builder();
+ Builder &setSoundManager(const ISoundManagerSRef &sm);
+ AccessoryPresenterSRef build(ucl::ElmWidget &parent) const;
+
+ private:
+ ISoundManagerSRef m_sm;
+ };
+
+ public:
+ virtual ~AccessoryPresenter();
+
+ ucl::Widget &getWidget();
+ void hideVolumeControls();
+
+ private:
+ friend class ucl::RefCountObj<AccessoryPresenter>;
+ AccessoryPresenter(ucl::RefCountObjBase &rc,
+ const ISoundManagerSRef &sm);
+
+ ucl::Result prepare(ucl::ElmWidget &parent);
+
+ ucl::Result createWidget(ucl::ElmWidget &parent);
+ ucl::Result createVolumeControl();
+ void registerCallbacks();
+ void unregisterCallbacks();
+ void onVolumeControlEventCb(VolumeControlEvent event);
+ Eina_Bool onRotaryEvent(Eext_Rotary_Event_Info *info);
+
+ void tryIncreaseVolume();
+ void tryDecreaseVolume();
+
+ void onAudioStateChanged(AudioStateType state);
+ void onVolumeLevelChanged(int value);
+
+ Eina_Bool onVCTimerCb();
+ void startVCTimer();
+ void restartVCTimer();
+ void stopVCTimer();
+
+ void updateVolume(int value);
+
+ private:
+ ucl::LayoutSRef m_widget;
+ VolumeControlSRef m_vc;
+ ISoundManagerSRef m_sm;
+ Ecore_Timer *m_vcTimer;
+ AudioStateType m_audioState;
+ };
+}
+
+
+
+#endif // __CALLUI_PRESENTERS_ACCESSORY_PRESENTER_H__
ucl::Result createCallInfoPresenter(CallMode mode);
+ ucl::Result createAccessoryPresenter();
+
ucl::Result createBottomBtn(const ucl::ElmStyle &style);
void onBottomBtnClicked(ucl::Widget &widget, void *eventInfo);
CallInfoPresenterSRef m_callInfoPrs;
AcceptRejectPresenterSRef m_acceptRejectPrs;
RejectMsgPresenterSRef m_rmPrs;
+ AccessoryPresenterSRef m_accessoryPrs;
CallMode m_mode;
Ecore_Timer *m_ecTimer;
bool m_ecTimerBtnReq;
UCL_DECLARE_REF_ALIASES(RejectMsgPresenter);
+ UCL_DECLARE_REF_ALIASES(AccessoryPresenter);
+
using AcceptDialogHandler = ucl::WeakDelegate<bool(AcceptDialog &, AcceptDialogEvent)>;
using RejectMsgStateHandler = ucl::WeakDelegate<void(RejectMsgState)>;
using RejectMsgSelectHandler = ucl::WeakDelegate<void(const IRejectMsgSRef &rm)>;
extern const ucl::TString STR_CALL_ENDED;
extern const ucl::TString STR_DECLINE_MESSAGES;
+
+ extern const ucl::TString STR_VOLUME;
}
#endif // __CALLUI_RESOURCES_H__
--- /dev/null
+/*
+ * Copyright 2017 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * 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 "BluetoothManager.h"
+
+#include <bluetooth.h>
+#include <bluetooth_internal.h>
+#include <bluetooth_extension.h>
+#include <sound_manager.h>
+
+#include "common.h"
+
+namespace callui { namespace { namespace impl {
+
+ using namespace ucl;
+
+ constexpr auto BT_VOLUME_MAX = 15;
+
+}}}
+
+namespace callui {
+
+ using namespace ucl;
+
+ BluetoothManagerSRef BluetoothManager::newInstance()
+ {
+ auto result = makeShared<BluetoothManager>();
+ FAIL_RETURN_VALUE(result->prepare(), {}, "result->prepare() failed!");
+ return result;
+ }
+
+ BluetoothManager::BluetoothManager():
+ m_btInitialized(false),
+ m_btAudioInitialized(false)
+ {
+ }
+
+ BluetoothManager::~BluetoothManager()
+ {
+ unregisterAudioHandling();
+
+ bt_deinitialize();
+ }
+
+ Result BluetoothManager::prepare()
+ {
+ if (BT_ERROR_NONE != bt_initialize()) {
+ LOG_RETURN(RES_FAIL, "BT initialize failed");
+ }
+ m_btInitialized = true;
+
+ FAIL_RETURN(registerAudioHandling(),
+ "registerAudioHandling() failed");
+
+ return RES_OK;
+ }
+
+ int BluetoothManager::getVolume()
+ {
+ auto vol = 0;
+ auto ret = bt_ag_get_speaker_gain(&vol);
+ if (ret != BT_ERROR_NONE) {
+ LOG_RETURN_VALUE(RES_FAIL, -1, "bt_ag_get_speaker_gain() failed!");
+ }
+ DLOG("BT Volume level [%d]", vol);
+ return vol;
+ }
+
+ int BluetoothManager::getMaxVolume()
+ {
+ return impl::BT_VOLUME_MAX;
+ }
+
+ Result BluetoothManager::setVolume(int volume)
+ {
+ auto ret = bt_ag_notify_speaker_gain(volume);
+ if (ret != BT_ERROR_NONE) {
+ LOG_RETURN(RES_FAIL, "bt_ag_notify_speaker_gain() failed!");
+ }
+ return RES_OK;
+ }
+
+ void BluetoothManager::setVolumeStateHandler(
+ const BluetoothVolumeHandler &handler)
+ {
+ m_handler = handler;
+ }
+
+ Result BluetoothManager::registerAudioHandling()
+ {
+ auto ret = bt_audio_initialize();
+ if (ret != BT_ERROR_NONE) {
+ LOG_RETURN(RES_FAIL, "bt_audio_initialize() failed");
+ }
+ m_btAudioInitialized = true;
+
+ ret = bt_ag_set_speaker_gain_changed_cb(
+ CALLBACK_B(BluetoothManager::onVolumeChanged), this);
+ if (ret != BT_ERROR_NONE) {
+ LOG_RETURN(RES_FAIL, "bt_ag_set_speaker_gain_changed_cb() failed");
+ }
+
+ return RES_OK;
+ }
+
+ void BluetoothManager::unregisterAudioHandling()
+ {
+ bt_ag_unset_speaker_gain_changed_cb();
+
+ if (m_btAudioInitialized) {
+ bt_audio_deinitialize();
+ m_btAudioInitialized = false;
+ }
+ }
+
+ void BluetoothManager::onVolumeChanged(int volume)
+ {
+ sound_type_e soundType = SOUND_TYPE_SYSTEM;
+ auto ret = sound_manager_get_current_sound_type(&soundType);
+ if (ret != SOUND_MANAGER_ERROR_NONE) {
+ LOG_RETURN_VOID(RES_FAIL, "sound_manager_get_current_sound_type() failed");
+ }
+
+ bool isSCOOpened = false;
+ ret = bt_ag_is_sco_opened(&isSCOOpened);
+ if (ret != BT_ERROR_NONE) {
+ LOG_RETURN_VOID(RES_FAIL, "sound_manager_get_current_sound_type() failed");
+ }
+
+ if (isSCOOpened && soundType == SOUND_TYPE_CALL) {
+ if (m_handler) {
+ m_handler(volume);
+ }
+ }
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2017 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * 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 __CALLUI_MODEL_BLUETOOTH_MANAGER_H__
+#define __CALLUI_MODEL_BLUETOOTH_MANAGER_H__
+
+#include "implTypes.h"
+
+namespace callui {
+
+ class BluetoothManager final {
+ public:
+ static BluetoothManagerSRef newInstance();
+ virtual ~BluetoothManager();
+
+ int getVolume();
+ int getMaxVolume();
+ ucl::Result setVolume(int volume);
+
+ void setVolumeStateHandler(const BluetoothVolumeHandler &handler);
+
+ private:
+ friend class ucl::RefCountObj<BluetoothManager>;
+ BluetoothManager();
+
+ ucl::Result prepare();
+
+ ucl::Result registerAudioHandling();
+ void unregisterAudioHandling();
+ void onVolumeChanged(int volume);
+
+ private:
+ BluetoothVolumeHandler m_handler;
+ bool m_btInitialized;
+ bool m_btAudioInitialized;
+ };
+
+}
+
+#endif // __CALLUI_MODEL_BLUETOOTH_MANAGER_H__
#include "BatteryStateSource.h"
#include "SimSlotStateSource.h"
#include "HdVoiceStateSource.h"
+#include "BluetoothManager.h"
#include "common.h"
Result Call::prepare()
{
+ m_btManager = BluetoothManager::newInstance();
+ if (!m_btManager) {
+ ELOG("BluetoothManager::newInstance() failed!");
+ }
+
auto callClient = CallClient::newInstance();
if (!callClient) {
LOG_RETURN(RES_FAIL, "Client::newInstance() failed!");
LOG_RETURN(RES_FAIL, "CallManager::newInstance() failed!");
}
- m_soundManager = SoundManager::newInstance(callClient);
+ m_soundManager = SoundManager::newInstance(callClient, m_btManager);
if (!m_soundManager) {
LOG_RETURN(RES_FAIL, "SoundManage::newInstance() failed!");
}
private:
CallManagerSRef m_callManager;
SoundManagerSRef m_soundManager;
+ BluetoothManagerSRef m_btManager;
ICallListenerWRef m_listener;
SimSlotStateSourceSRef m_simSlotStSrc;
HdVoiceStateSourceSRef m_hdCallStSrc;
ucl::Result CallClient::prepare()
{
cm_client_h client;
- FAIL_RETURN_VALUE(convertCMResult(cm_init(&client)), {}, "cm_init() failed!");
+ FAIL_RETURN(convertCMResult(cm_init(&client)), "cm_init() failed!");
m_client = client;
return RES_OK;
#include "SoundManager.h"
#include "CallClient.h"
+#include "BluetoothManager.h"
#include "common.h"
using namespace ucl;
- SoundManager::SoundManager(const CallClientSRef &client):
- m_client(client)
+ SoundManager::SoundManager(RefCountObjBase &rc,
+ const CallClientSRef &client,
+ const BluetoothManagerSRef &btManager):
+ RefCountAware(&rc),
+ m_client(client),
+ m_btManager(btManager),
+ m_deviceVolumeCbID(-1)
{
}
SoundManager::~SoundManager()
{
+ if (m_deviceVolumeCbID >= 0) {
+ sound_manager_remove_volume_changed_cb(m_deviceVolumeCbID);
+ }
cm_unset_audio_state_changed_cb(*m_client);
cm_unset_mute_status_cb(*m_client);
}
- SoundManagerSRef SoundManager::newInstance(const CallClientSRef &client)
+ SoundManagerSRef SoundManager::newInstance(const CallClientSRef &client,
+ const BluetoothManagerSRef &btManager)
{
- auto result = makeShared<SoundManager>(client);
+ auto result = makeShared<SoundManager>(client, btManager);
FAIL_RETURN_VALUE(result->prepare(), {}, "result->prepare() failed!");
return result;
}
ILOG("Ignore. Unhandled state [%d]", state);
return;
}
-
m_audioStateEvent.dispatch(convertCMAudioState(state));
}
Result SoundManager::prepare()
{
- Result res = convertCMResult(cm_set_audio_state_changed_cb(*m_client, CALLBACK_B(SoundManager::audioStateChangedCb), this));
+ Result res = convertCMResult(cm_set_audio_state_changed_cb(*m_client,
+ CALLBACK_B(SoundManager::audioStateChangedCb), this));
FAIL_RETURN(res, "cm_set_audio_state_changed_cb() failed!");
- res = convertCMResult(cm_set_mute_status_cb(*m_client, CALLBACK_B(SoundManager::muteStateChangedCb), this));
- FAIL_RETURN(res, "__callui_mute_state_changed_cb() failed!");
+ res = convertCMResult(cm_set_mute_status_cb(*m_client,
+ CALLBACK_B(SoundManager::muteStateChangedCb), this));
+ FAIL_RETURN(res, "cm_set_mute_status_cb() failed!");
+
+ FAIL_RETURN(registerVolumeCallbacks(),
+ "registerVolumeCallbacks() failed!");
return res;
}
+ Result SoundManager::registerVolumeCallbacks()
+ {
+ int ret = sound_manager_add_volume_changed_cb(
+ CALLBACK_B(SoundManager::onDeviceVolumeChanged),
+ this,
+ &m_deviceVolumeCbID);
+ if (ret != SOUND_MANAGER_ERROR_NONE) {
+ LOG_RETURN(RES_FAIL,
+ "sound_manager_add_volume_changed_cb() failed");
+ }
+
+ if (m_btManager) {
+ m_btManager->setVolumeStateHandler(
+ WEAK_DELEGATE(SoundManager::onBluetoothVolumeChanged,
+ asWeak(*this)));
+ }
+
+ return RES_OK;
+ }
+
Result SoundManager::setSpeakerState(bool isEnable)
{
if (isEnable) {
{
cm_audio_state_type_e state = CM_AUDIO_STATE_NONE_E;
Result res = convertCMResult(cm_get_audio_state(*m_client, &state));
- FAIL_RETURN_VALUE(res, AudioStateType::NONE, "cm_get_audio_state() failed!");
+ FAIL_RETURN_VALUE(res, AudioStateType::NONE,
+ "cm_get_audio_state() failed!");
return convertCMAudioState(state);
}
return convertCMResult(cm_stop_dtmf(*m_client));
}
- void SoundManager::addAudioStateChangeHandler(AudioStateHandler handler)
+ void SoundManager::addAudioStateHandler(AudioStateHandler handler)
{
m_audioStateEvent += handler;
}
- void SoundManager::removeAudioStateChangeHandler(AudioStateHandler handler)
+ void SoundManager::removeAudioStateHandler(AudioStateHandler handler)
{
m_audioStateEvent -= handler;
}
- void SoundManager::addMuteStateChangeHandler(MuteStateHandler handler)
+ void SoundManager::addMuteStateHandler(MuteStateHandler handler)
{
m_muteStateEvent += handler;
}
- void SoundManager::removeMuteStateChangeHandler(MuteStateHandler handler)
+ void SoundManager::removeMuteStateHandler(MuteStateHandler handler)
{
m_muteStateEvent -= handler;
}
+ void SoundManager::addVolumeStateHandler(
+ VolumeLevelHandler handler)
+ {
+ m_volumeLevelEvent += handler;
+ }
+
+ void SoundManager::removeVolumeStateHandler(
+ VolumeLevelHandler handler)
+ {
+ m_volumeLevelEvent -= handler;
+ }
+
+ int SoundManager::getMaxVolume() const
+ {
+ int maxVol = 0;
+ if (getAudioState() == AudioStateType::BT) {
+ if (m_btManager) {
+ maxVol = m_btManager->getMaxVolume();
+ } else {
+ ELOG("BT is not set");
+ }
+ } else {
+ auto ret = sound_manager_get_max_volume(SOUND_TYPE_CALL, &maxVol);
+ if (ret != SOUND_MANAGER_ERROR_NONE) {
+ LOG_RETURN_VALUE(RES_FAIL, 0,
+ "Get max volume failed. ret[%d]", ret);
+ }
+ }
+ DLOG("Max volume [%d]", maxVol);
+ return maxVol;
+ }
+
+ int SoundManager::getVolume() const
+ {
+ int vol = 0;
+ if (getAudioState() == AudioStateType::BT) {
+ if (m_btManager) {
+ vol = m_btManager->getVolume();
+ } else {
+ ELOG("BT is not set");
+ }
+ } else {
+ auto ret = sound_manager_get_volume(SOUND_TYPE_CALL, &vol);
+ if (ret != SOUND_MANAGER_ERROR_NONE) {
+ LOG_RETURN_VALUE(RES_FAIL, 0,
+ "Get volume failed. ret[%d]", ret);
+ }
+ }
+ DLOG("Current volume [%d]", vol);
+ return vol;
+ }
+
+ Result SoundManager::setVolume(int value)
+ {
+ if (getAudioState() == AudioStateType::BT) {
+ if (m_btManager) {
+ return m_btManager->setVolume(value);
+ } else {
+ LOG_RETURN(RES_FAIL, "BT is not set");
+ }
+ } else {
+ auto ret = sound_manager_set_volume(SOUND_TYPE_CALL, value);
+ if (ret != SOUND_MANAGER_ERROR_NONE) {
+ LOG_RETURN(RES_FAIL,
+ "sound_manager_set_volume() failed. ret[%d]", ret);
+ }
+ }
+ return RES_OK;
+ }
+
+
+ void SoundManager::onDeviceVolumeChanged(sound_type_e type, unsigned int volume)
+ {
+ DLOG("Volume [%d]", volume);
+ if (type != SOUND_TYPE_CALL) {
+ ILOG("Ignored. Not type Call.");
+ return;
+ }
+
+ if (getAudioState() != AudioStateType::BT) {
+ m_volumeLevelEvent.dispatch(volume);
+ }
+ }
+
+ void SoundManager::onBluetoothVolumeChanged(int volume)
+ {
+ DLOG("Volume [%d]", volume);
+
+ if (getAudioState() == AudioStateType::BT) {
+ m_volumeLevelEvent.dispatch(volume);
+ }
+ }
+
}
#define __CALLUI_MODEL_SOUND_MANAGER_H__
#include <call-manager-ext.h>
+#include <sound_manager.h>
#include "model/ISoundManager.h"
namespace callui {
- class SoundManager final : public ISoundManager {
+ class SoundManager final :
+ public ucl::RefCountAware,
+ public ISoundManager {
public:
- static SoundManagerSRef newInstance(const CallClientSRef &client);
+ static SoundManagerSRef newInstance(const CallClientSRef &client,
+ const BluetoothManagerSRef &btManager);
virtual ~SoundManager();
// ISoundManager
virtual bool getMuteState() const override final;
virtual ucl::Result startDtmf(const unsigned char dtmfDigit) override final;
virtual ucl::Result stopDtmf() override final;
- virtual void addAudioStateChangeHandler(AudioStateHandler handler) override final;
- virtual void removeAudioStateChangeHandler(AudioStateHandler handler) override final;
- virtual void addMuteStateChangeHandler(MuteStateHandler handler) override final;
- virtual void removeMuteStateChangeHandler(MuteStateHandler handler) override final;
+ virtual void addAudioStateHandler(AudioStateHandler handler) override final;
+ virtual void removeAudioStateHandler(AudioStateHandler handler) override final;
+ virtual void addMuteStateHandler(MuteStateHandler handler) override final;
+ virtual void removeMuteStateHandler(MuteStateHandler handler) override final;
+ virtual void addVolumeStateHandler(VolumeLevelHandler handler) override final;
+ virtual void removeVolumeStateHandler(VolumeLevelHandler handler) override final;
+ virtual int getMaxVolume() const override final;
+ virtual int getVolume() const override final;
+ virtual ucl::Result setVolume(int value) override final;
private:
friend class ucl::RefCountObj<SoundManager>;
- SoundManager(const CallClientSRef &client);
+ SoundManager(ucl::RefCountObjBase &rc,
+ const CallClientSRef &client,
+ const BluetoothManagerSRef &btManager);
ucl::Result prepare();
+ ucl::Result registerVolumeCallbacks();
+
void audioStateChangedCb(cm_audio_state_type_e state);
void muteStateChangedCb(cm_mute_status_e status);
+ void onBluetoothVolumeChanged(int volume);
+ void onDeviceVolumeChanged(sound_type_e type, unsigned int volume);
+
private:
CallClientSRef m_client;
+ BluetoothManagerSRef m_btManager;
AudioStateEvent m_audioStateEvent;
MuteStateEvent m_muteStateEvent;
+ VolumeLevelEvent m_volumeLevelEvent;
+ int m_deviceVolumeCbID;
};
}
UCL_DECLARE_REF_ALIASES(SimSlotStateSource);
UCL_DECLARE_REF_ALIASES(HdVoiceStateSource);
+ UCL_DECLARE_REF_ALIASES(BluetoothManager);
+
using AudioStateEvent = ucl::Event<AudioStateHandler>;
using MuteStateEvent = ucl::Event<MuteStateHandler>;
+ using VolumeLevelEvent = ucl::Event<VolumeLevelHandler>;
using StateChangeHandler = ucl::WeakDelegate<void()>;
+
+ using BluetoothVolumeHandler = ucl::WeakDelegate<void(int)>;
}
#endif // __CALLUI_MODEL_IMPL_TYPES_H__
// IncomingCallPresenter::Builder
AcceptRejectPresenter::Builder::Builder():
- m_callMask(0)
+ m_callMask(CALL_FLAG_NONE)
{
}
m_popup->dispose();
}
- delRotaryEventHandler(CALLBACK_A(
- AcceptRejectPresenter::onRotaryEvent), this);
+ delRotaryEventHandler(
+ CALLBACK_A(AcceptRejectPresenter::onRotaryEvent), this);
}
Result AcceptRejectPresenter::prepare(ElmWidget &parent)
--- /dev/null
+/*
+ * Copyright 2017 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * 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 "presenters/AccessoryPresenter.h"
+
+#include "model/ISoundManager.h"
+#include "view/VolumeControl.h"
+#include "resources.h"
+#include "common.h"
+
+namespace callui { namespace { namespace impl {
+
+ using namespace ucl;
+
+ constexpr auto CALL_VC_TIMER_INTERVAL = 1.5;
+ constexpr auto VOLUME_LEVEL_MIN = 1;
+
+ constexpr LayoutTheme LAYOUT_ACCESSORY_WIDGET
+ {"layout", "callui", "accessory"};
+
+ constexpr EdjePart PART_SWL_VOLUME_CONTROL {"swl.volume_control"};
+
+}}}
+
+namespace callui {
+
+ using namespace ucl;
+
+ AccessoryPresenter::Builder::Builder()
+ {
+ }
+
+ AccessoryPresenter::Builder &AccessoryPresenter::Builder::setSoundManager(const ISoundManagerSRef &sm)
+ {
+ m_sm = sm;
+ return *this;
+ }
+
+ AccessoryPresenterSRef AccessoryPresenter::Builder::build(ElmWidget &parent) const
+ {
+ if (!m_sm) {
+ LOG_RETURN_VALUE(RES_FAIL, {}, "Sound manager is NULL");
+ }
+
+ auto result = makeShared<AccessoryPresenter>(m_sm);
+ FAIL_RETURN_VALUE(result->prepare(parent), {}, "result->prepare() failed!");
+ return result;
+ }
+
+ AccessoryPresenter::AccessoryPresenter(RefCountObjBase &rc,
+ const ISoundManagerSRef &sm):
+ Presenter(rc),
+ m_sm(sm),
+ m_vcTimer(nullptr),
+ m_audioState(m_sm->getAudioState())
+ {
+
+ }
+
+ AccessoryPresenter::~AccessoryPresenter()
+ {
+ stopVCTimer();
+ unregisterCallbacks();
+ }
+
+ Result AccessoryPresenter::prepare(ElmWidget &parent)
+ {
+ FAIL_RETURN(Presenter::prepare(parent), "Presenter::prepare() failed");
+
+ FAIL_RETURN(createWidget(parent), "createWidget() failed");
+
+ FAIL_RETURN(createVolumeControl(), "createVolumeControl() failed");
+
+ registerCallbacks();
+
+ return RES_OK;
+ }
+
+ Widget &AccessoryPresenter::getWidget()
+ {
+ return *m_widget;
+ }
+
+ void AccessoryPresenter::hideVolumeControls()
+ {
+ stopVCTimer();
+ m_vc->hideControls();
+ }
+
+ Result AccessoryPresenter::createWidget(ElmWidget &parent)
+ {
+ m_widget = Layout::Builder().
+ setTheme(impl::LAYOUT_ACCESSORY_WIDGET).
+ setIsOwner(true).
+ build(parent);
+ if (!m_widget) {
+ LOG_RETURN(RES_FAIL, "Layout::build() failed!");
+ }
+
+ return RES_OK;
+ }
+
+ Result AccessoryPresenter::createVolumeControl()
+ {
+ m_vc = VolumeControl::Builder().
+ setInfoText(STR_VOLUME).
+ setMaxSliderValue(m_sm->getMaxVolume()).
+ setShowControls(false).
+ setEventHandler(WEAK_DELEGATE(
+ AccessoryPresenter::onVolumeControlEventCb,
+ asWeak(*this))).
+ build(*m_widget);
+ if (!m_vc) {
+ LOG_RETURN(RES_FAIL, "VolumeControl::build() failed");
+ }
+ updateVolume(m_sm->getVolume());
+
+ m_widget->setContent(*m_vc, impl::PART_SWL_VOLUME_CONTROL);
+
+ return RES_OK;
+ }
+
+ void AccessoryPresenter::registerCallbacks()
+ {
+ addRotaryEventHandler(CALLBACK_A(
+ AccessoryPresenter::onRotaryEvent), this);
+
+ m_sm->addAudioStateHandler(DELEGATE(
+ AccessoryPresenter::onAudioStateChanged, this));
+
+ m_sm->addVolumeStateHandler(DELEGATE(
+ AccessoryPresenter::onVolumeLevelChanged, this));
+ }
+
+ void AccessoryPresenter::unregisterCallbacks()
+ {
+ delRotaryEventHandler(
+ CALLBACK_A(AccessoryPresenter::onRotaryEvent), this);
+
+ m_sm->removeAudioStateHandler(DELEGATE(
+ AccessoryPresenter::onAudioStateChanged, this));
+
+ m_sm->removeVolumeStateHandler(DELEGATE(
+ AccessoryPresenter::onVolumeLevelChanged, this));
+ }
+
+ Eina_Bool AccessoryPresenter::onVCTimerCb()
+ {
+ m_vc->hideControls();
+ m_vcTimer = nullptr;
+
+ return ECORE_CALLBACK_CANCEL;
+ }
+
+ void AccessoryPresenter::startVCTimer()
+ {
+ stopVCTimer();
+
+ m_vcTimer = ecore_timer_add(impl::CALL_VC_TIMER_INTERVAL,
+ CALLBACK_B(AccessoryPresenter::onVCTimerCb),
+ this);
+ }
+
+ void AccessoryPresenter::restartVCTimer()
+ {
+ if (m_vcTimer) {
+ ecore_timer_reset(m_vcTimer);
+ }
+ }
+
+ void AccessoryPresenter::stopVCTimer()
+ {
+ if (m_vcTimer) {
+ ecore_timer_del(m_vcTimer);
+ m_vcTimer = nullptr;
+ }
+ }
+
+ Eina_Bool AccessoryPresenter::onRotaryEvent(Eext_Rotary_Event_Info *info)
+ {
+ if (m_vcTimer) {
+ restartVCTimer();
+ } else {
+ m_vc->showControls();
+ startVCTimer();
+ }
+
+ if (info->direction == EEXT_ROTARY_DIRECTION_CLOCKWISE) {
+ tryIncreaseVolume();
+ } else {
+ tryDecreaseVolume();
+ }
+
+ return EINA_TRUE;
+ }
+
+ void AccessoryPresenter::onVolumeControlEventCb(VolumeControlEvent event)
+ {
+ restartVCTimer();
+
+ switch (event) {
+ case VolumeControlEvent::INCREASE:
+ tryIncreaseVolume();
+ break;
+ case VolumeControlEvent::DECREASE:
+ tryDecreaseVolume();
+ break;
+ default:
+ break;
+ }
+ }
+
+ void AccessoryPresenter::tryIncreaseVolume()
+ {
+ auto max = m_sm->getMaxVolume();
+ auto cur = m_sm->getVolume();
+
+ if (max != cur) {
+ m_sm->setVolume(cur + 1);
+ }
+ }
+
+ void AccessoryPresenter::tryDecreaseVolume()
+ {
+ auto cur = m_sm->getVolume();
+
+ if (cur - 1 >= impl::VOLUME_LEVEL_MIN) {
+ m_sm->setVolume(cur - 1);
+ }
+ }
+
+ void AccessoryPresenter::onAudioStateChanged(AudioStateType state)
+ {
+ if ((m_audioState != AudioStateType::BT &&
+ state == AudioStateType::BT) ||
+ (m_audioState == AudioStateType::BT &&
+ state != AudioStateType::BT)) {
+ m_audioState = state;
+ m_vc->setSliderValue(0);
+ m_vc->setMaxSliderValue(m_sm->getMaxVolume());
+ updateVolume(m_sm->getVolume());
+ }
+ }
+
+ void AccessoryPresenter::updateVolume(int value)
+ {
+ m_vc->setSliderValue(value);
+
+ auto max = m_sm->getMaxVolume();
+ auto cur = m_sm->getVolume();
+
+ if (cur == max) {
+ m_vc->setIncreaseBtnEnable(false);
+ m_vc->setDecreaseBtnEnable(true);
+ } else if (cur <= impl::VOLUME_LEVEL_MIN) {
+ m_vc->setIncreaseBtnEnable(true);
+ m_vc->setDecreaseBtnEnable(false);
+ } else {
+ m_vc->setIncreaseBtnEnable(true);
+ m_vc->setDecreaseBtnEnable(true);
+ }
+ }
+
+ void AccessoryPresenter::onVolumeLevelChanged(int value)
+ {
+ updateVolume(value);
+ }
+}
+
#include "presenters/AcceptRejectPresenter.h"
#include "presenters/CallInfoPresenter.h"
#include "presenters/RejectMsgPresenter.h"
+#include "presenters/AccessoryPresenter.h"
#include "resources.h"
#include "common.h"
constexpr ElmStyle STYLE_BB_END_CALL {"callui/end_call"};
constexpr ElmStyle STYLE_BB_RECALL {"callui/call_back"};
-
- constexpr SmartEvent EVENT_CLICKED {"clicked"};
}}}
namespace callui {
requestExit();
break;
default:
+ if (m_accessoryPrs) {
+ m_accessoryPrs->hideVolumeControls();
+ }
break;
}
}
elm_button_add(*m_widget), true);
m_bottomBtn->setStyle(style);
- m_bottomBtn->addEventHandler(impl::EVENT_CLICKED,
+ m_bottomBtn->addEventHandler(BTN_CLICKED,
WEAK_DELEGATE(MainPage::onBottomBtnClicked,
asWeak(*this)));
m_bottomBtn.reset();
if (m_mode == CallMode::INCOMING) {
+ m_accessoryPrs.reset();
FAIL_RETURN_VOID(processIncomingCall(),
"processIncomingCall() failed!");
} else {
m_rmLy.reset();
if (m_mode == CallMode::END) {
+ m_accessoryPrs.reset();
startEndCallTimer();
} else {
+ createAccessoryPresenter();
createBottomBtn(impl::STYLE_BB_END_CALL);
}
}
"createCallInfoPresenter() failed!");
}
+ Result MainPage::createAccessoryPresenter()
+ {
+ if (m_accessoryPrs) {
+ return RES_OK;
+ }
+
+ m_accessoryPrs = AccessoryPresenter::Builder().
+ setSoundManager(m_call->getSoundManager()).
+ build(*m_widget);
+
+ if (!m_accessoryPrs) {
+ LOG_RETURN(RES_FAIL,
+ "AccessoryPresenter::build() failed!");
+ }
+
+ m_widget->setContent(m_accessoryPrs->getWidget().getEo(),
+ impl::PART_SWL_OVERLAY);
+
+ return RES_OK;
+ }
+
Result MainPage::createAcceptRejectPresenter()
{
if (m_acceptRejectPrs) {
if (!m_acceptRejectPrs) {
LOG_RETURN(RES_FAIL,
- "AcceptRejectPresenter::Builder().build() failed!");
+ "AcceptRejectPresenter::build() failed!");
}
m_widget->setContent(m_acceptRejectPrs->getWidget().getEo(),
#include "../common.h"
+#include "../view/common.h"
+
#endif // __CALLUI_PRESENTERS_COMMON_H__
const ucl::TString STR_CALL_ENDED {"Call ended"};
const ucl::TString STR_DECLINE_MESSAGES {"Decline messages"};
+
+ const ucl::TString STR_VOLUME {"Volume"};
}
namespace callui {
constexpr ucl::SmartEvent BTN_CLICKED {"clicked"};
- constexpr ucl::SmartEvent POPUP_DELETE {"delete"};
}
#endif // __CALLUI_VIEW_COMMON_H__
<privileges>
<privilege>http://tizen.org/privilege/telephony</privilege>
<privilege>http://tizen.org/privilege/telephony.admin</privilege>
- <privilege>http://tizen.org/privilege/keygrab</privilege>
<privilege>http://tizen.org/privilege/appmanager.launch</privilege>
<privilege>http://tizen.org/privilege/window.priority.set</privilege>
<privilege>http://tizen.org/privilege/systemsettings.admin</privilege>
<privilege>http://tizen.org/privilege/contact.read</privilege>
+ <privilege>http://tizen.org/privilege/volume.set</privilege>
<privilege>http://tizen.org/privilege/message.write</privilege>
<privilege>http://tizen.org/privilege/notification</privilege>
<privilege>http://tizen.org/privilege/display</privilege>