📄 voipapp.cpp
字号:
UINT uVirtKey,
BOOL fKeyup
)
{
HotKeys_t::HotKeyId_e HotkeyName = HotKeys_t::GetHotKeyName(HotkeyId);
ASSERT(uVirtKey == HotKeys_t::GetHotKey(HotkeyName));
switch (HotkeyName)
{
case HotKeys_t::vkVoicemail:
return OnVoicemailPress(fKeyup);
case HotKeys_t::vkHold:
return OnHoldPress(fKeyup);
case HotKeys_t::vkRedial:
return OnRedialPress(fKeyup);
case HotKeys_t::vkTransfer:
return OnTransferPress(fKeyup);
case HotKeys_t::vkMute:
return OnMutePress(fKeyup);
case HotKeys_t::vkHookSwitch:
case HotKeys_t::vkSpeaker:
return OnHookModeChange(
HotkeyName,
fKeyup
);
default:
ASSERT(FALSE);
return -1;
}
return -1;
}
/*------------------------------------------------------------------------------
VoIPApp_t::OnHookModeChange
Handles the hookstate being switched
Parameters:
HotkeyIndex: which hotkey was selected
Returns (HRESULT): indicating success or failure
------------------------------------------------------------------------------*/
HRESULT VoIPApp_t::OnHookModeChange(
HotKeys_t::HotKeyId_e HotkeyName,
BOOL KeyIsUp
)
{
VoIPAudioMode vamNew;
HRESULT hr = S_OK;
BOOL fInformUI = FALSE;
HookswitchHotkeyState hhs;
if (HotkeyName == HotKeys_t::vkHookSwitch)
{
//NOTE: The hook switch is inverted
hhs = KeyIsUp ?
e_hhsHookDown :
e_hhsHookUp;
m_HookSwitchIsUp = !KeyIsUp;
}
else if (HotkeyName == HotKeys_t::vkSpeaker)
{
//we only care about keydown events for the speaker phone button
if (KeyIsUp)
{
return S_FALSE;
}
hhs = e_hhsSpeakerToggle;
}
else
{
//This should never happen
ASSERT(FALSE);
return E_UNEXPECTED;
}
//Transition from old state to new
/*
OLD: Idle EVENT: HookswitchUp NEW: Handset
OLD: Handset EVENT: HookswitchUp NEW: IMPOSSIBLE!
OLD: Speaker EVENT: HookswitchUp NEW: Handset
OLD: Idle EVENT: HookswitchDown NEW: IMPOSSIBLE!
OLD: Handset EVENT: HookswitchDown NEW: Idle
OLD: Speaker EVENT: HookswitchDown NEW: No change - speaker
OLD: Idle EVENT: SpeakerToggle NEW: SpeakerPhone
OLD: Handset EVENT: SpeakerToggle NEW: SpeakerPhone
OLD: Speaker EVENT: SpeakerToggle NEW: if old hook state was UP then go back to handset
otherwise goto idle
*/
switch (hhs)
{
case e_hhsHookUp:
{
if (m_AudioMode == e_vamIdle || m_AudioMode == e_vamSpeakerPhone)
{
vamNew = e_vamHandset;
}
else
{
RETAILMSG(1, (L"The audio mode was set to HANDSET and then HANDSET was lifted off the hook. This should be impossible"));
return S_FALSE;
}
}
break;
case e_hhsHookDown:
{
if (m_AudioMode == e_vamHandset)
{
vamNew = e_vamIdle;
}
else if (m_AudioMode == e_vamSpeakerPhone)
{
//if the old mode was speaker phone then this is a no-op
return S_FALSE;
}
else
{
RETAILMSG(1, (L"The audio mode was set to IDLE and then HANDSET was placed on the hook. This should be impossible"));
return S_FALSE;
}
}
break;
case e_hhsSpeakerToggle:
{
if (m_AudioMode == e_vamIdle || m_AudioMode == e_vamHandset)
{
vamNew = e_vamSpeakerPhone;
}
else
{
vamNew = (m_HookSwitchIsUp) ? e_vamHandset : e_vamIdle;
}
}
break;
default:
ASSERT(FALSE);
hr = E_UNEXPECTED;
}
ASSERT(m_AudioMode != vamNew);
//if we are newly onhook - we need to disconnect calls/stop tones BEFORE
//setting the new hardware audio mode
if (vamNew == e_vamIdle)
{
hr = OnNewlyOnHook();
fInformUI = TRUE;
}
//otherwise we need to set the new audio mode before doing anything else
else
{
//if the old mode was IDLE, then we are newly off hook
if (m_AudioMode == e_vamIdle)
{
hr = OnNewlyOffHook();
fInformUI = TRUE;
}
}
m_AudioMode = vamNew;
if (fInformUI)
{
m_UIManager.OnHookModeChange(m_AudioMode == e_vamIdle);
}
return hr;
}
/*------------------------------------------------------------------------------
VoIPApp_t::OnNewlyOffHook
Handles the phone being placed off hook
Returns (HRESULT):
------------------------------------------------------------------------------*/
HRESULT VoIPApp_t::OnNewlyOffHook()
{
if (m_CallList.size() == 0)
{
return S_FALSE;
}
CComPtr<Call_t> cpCall;
HRESULT hr = S_OK;
//if the first call is an incoming call, answer it
FindCallWithStatus(
RTCSS_INCOMING,
&cpCall
);
if (cpCall != NULL)
{
hr = cpCall->DoPhoneVerb(PH_VERB_ACCEPT_INCOMING);
return hr;
}
//if the first call is an call in progress, do nothing
FindCallWithStatus(
RTCSS_INPROGRESS,
&cpCall
);
if (cpCall != NULL)
{
return hr;
}
//if the first call is a call in holding, unhold it
FindCallWithStatus(
RTCSS_HOLD,
&cpCall
);
if (cpCall != NULL)
{
hr = cpCall->DoPhoneVerb(PH_VERB_UNHOLD);
return hr;
}
return hr;
}
/*------------------------------------------------------------------------------
VoIPApp_t::OnNewlyOnHook
Handles the phone being placed on hook
Returns (HRESULT):
------------------------------------------------------------------------------*/
HRESULT VoIPApp_t::OnNewlyOnHook()
{
StopActiveTone();
if (m_CallList.size() == 0)
{
return S_FALSE;
}
HRESULT hr = S_OK;
for (CallList_t::iterator Group = m_CallList.begin(); Group != m_CallList.end(); Group++)
{
hr = static_cast<Call_t*>(*Group)->DoPhoneVerb(PH_VERB_END);
if (FAILED(hr))
{
PHONEAPP_DEBUGMSG(ZONE_PHONEAPP_ERROR, (L"Failed at ending a call group, hr = 0x%x", hr));
}
}
return hr;
}
/*------------------------------------------------------------------------------
VoIPApp_t::OnHoldPress
Handles the Hold Hotkey being pressed
Returns (HRESULT): indicating success or failure
------------------------------------------------------------------------------*/
HRESULT
VoIPApp_t::OnHoldPress(
BOOL fKeyup
)
{
if (fKeyup)
{
//don't care about keyup events
return S_FALSE;
}
bool Handled = false;
HRESULT hr = m_UIManager.OnHold(&Handled);
if (SUCCEEDED(hr) || Handled)
{
return hr;
}
CComPtr<Call_t> cpCall;
//If there is a connected call, place the call on hold
FindCallWithStatus(
RTCSS_CONNECTED,
&cpCall
);
if (cpCall != NULL)
{
return cpCall->DoPhoneVerb(PH_VERB_HOLD);
}
//If the state and user selection does not have to do with a holding call,
//forcibly unhold the first held call we can find
FindCallWithStatus(
RTCSS_HOLD,
&cpCall
);
if (cpCall != NULL)
{
return cpCall->DoPhoneVerb(PH_VERB_UNHOLD);
}
return S_FALSE;
}
/*------------------------------------------------------------------------------
VoIPApp_t::OnTransferPress
Handle the Hotkey Transfer being pressed.
Returns (HRESULT): indicating success or failure
------------------------------------------------------------------------------*/
HRESULT
VoIPApp_t::OnTransferPress(
BOOL fKeyup
)
{
if (fKeyup)
{
//don't care about keyup events
return S_FALSE;
}
bool Ignored = false;
return m_UIManager.OnTransfer(&Ignored);
}
/*------------------------------------------------------------------------------
VoIPApp_t::AuthenticateAction
Authenticate the user with the PIN dialog if the
device is locked
Parameters:
action: Action to take when the user is authenticated
Returns (HRESULT):
------------------------------------------------------------------------------*/
HRESULT
VoIPApp_t::AuthenticateAction(
ProtectedAction_e action
)
{
//are we already waiting for authentication? If
//so, simply update what we are waiting for...
if (m_PendingAuthAction != ActionInvalid)
{
m_PendingAuthAction = action;
return S_OK;
}
PH_AUTHENTICATE_USER_PARAMETERS Params = {0};
Params.StructSize = sizeof(Params);
Params.NotificationMessage = WM_AUTH_COMPLETE;
Params.NotificationWindow = m_NotificationWindow;
//Ask the homescreen to authenticate the user...
HRESULT hr = PHAuthenticateUser(&Params);
if (FAILED(hr))
{
ASSERT(FALSE);
return hr;
}
switch (Params.Result)
{
case AuthInProgress:
//remember the action and wait...
m_PendingAuthAction = action;
return S_OK;
case AuthSucceeded:
//device is not locked, continue to perform the action
return OnUserAuthenticated(action);
default:
//Huh?!
ASSERT(FALSE);
return E_FAIL;
}
}
/*------------------------------------------------------------------------------
VoIPApp_t::OnUserAuthenticated
Perform the real action now that the user is authenticated
Parameters:
Action:
Returns (HRESULT):
------------------------------------------------------------------------------*/
HRESULT
VoIPApp_t::OnUserAuthenticated(
ProtectedAction_e Action
)
{
switch (Action)
{
case ActionRedial:
return Redial();
case ActionVoicemail:
return DialVoicemail();
default:
ASSERT(FALSE);
return E_INVALIDARG;
}
}
/*------------------------------------------------------------------------------
VoIPApp_t::OnAuthRequestComplete
Notification we receive when our authentication request is
completed or canceled
Parameters:
result: The result from the request
------------------------------------------------------------------------------*/
HRESULT
VoIPApp_t::OnAuthRequestComplete(
AuthenticationResult_e result
)
{
//are we still waiting?
if (m_PendingAuthAction == ActionInvalid)
{
return S_OK;
}
HRESULT hr = S_OK;
if (result == AuthSucceeded)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -