/*
* Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:
*
*/
#include "t_hsappkeyhandler.h"
#include <QtTest/QtTest>
#include <QScopedPointer>
#include <QValueSpaceSubscriber>
#include <hb/hbcore/hbsymbianvariant.h>
#include <tspropertydefs.h>
#include <homescreendomainpskeys.h>
#include "hsappkeyplugin.h"
QTM_USE_NAMESPACE
namespace {
_LIT(KTsPluginName, "com.nokia.taskswitcher.tsdevicedialogplugin/1.0");
}
// -----------------------------------------------------------------------------
// CONSTRUCTOR
// -----------------------------------------------------------------------------
//
T_HsAppKeyHandler::T_HsAppKeyHandler(QObject *parent) :
QObject(parent),
mCHsAppKeyPluginInstance(0),
mDialog(0)
{
}
// -----------------------------------------------------------------------------
// INIT AND CLEANUP
// -----------------------------------------------------------------------------
//
void T_HsAppKeyHandler::init()
{
TRAPD(errNo, mCHsAppKeyPluginInstance = CHsAppKeyPlugin::NewL());
QCOMPARE(errNo, KErrNone);
QVERIFY(mCHsAppKeyPluginInstance);
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
//
void T_HsAppKeyHandler::cleanup()
{
delete mCHsAppKeyPluginInstance;
mCHsAppKeyPluginInstance = 0;
delete mDialog;
mDialog = 0;
}
// -----------------------------------------------------------------------------
// TEST CASES
// -----------------------------------------------------------------------------
//
void T_HsAppKeyHandler::callDataReceived()
{
// just call unused part of HbDeviceDialogMonitor interface
CHbSymbianVariantMap *dummy;
TRAPD(errNo, dummy = CHbSymbianVariantMap::NewL());
QCOMPARE(errNo, KErrNone);
QVERIFY(dummy);
mCHsAppKeyPluginInstance->DataReceived(*dummy);
delete dummy;
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
//
void T_HsAppKeyHandler::testProvideKeyEvents()
{
RArray<TKeyEvent> keyEventArray;
CleanupClosePushL(keyEventArray);
TRAPD(errNo, mCHsAppKeyPluginInstance->ProvideKeyEventsL(keyEventArray));
QCOMPARE(errNo, KErrNone);
QCOMPARE(keyEventArray.Count(), 2);
TKeyEvent shortPress = keyEventArray[0];
QCOMPARE(shortPress.iCode, static_cast<TUint>(EKeyApplication0));
QCOMPARE(shortPress.iScanCode, static_cast<TInt>(EStdKeyApplication0));
QCOMPARE(shortPress.iModifiers, static_cast<TUint>(0));
QCOMPARE(shortPress.iRepeats, 0);
TKeyEvent longPress = keyEventArray[0];
QCOMPARE(longPress.iCode, static_cast<TUint>(EKeyApplication0));
QCOMPARE(longPress.iScanCode, static_cast<TInt>(EStdKeyApplication0));
QCOMPARE(longPress.iModifiers, static_cast<TUint>(0));
QCOMPARE(longPress.iRepeats, 0);
CleanupStack::PopAndDestroy(&keyEventArray);
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
//
void T_HsAppKeyHandler::testDeviceDialogClosed()
{
// @todo: verify that calling this method closes task switcher
mCHsAppKeyPluginInstance->DeviceDialogClosed(0);
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
//
void T_HsAppKeyHandler::testHandleKeyEventIgnoresKeysOtherThanAppKey()
{
TInt errNo(KErrNone);
TKeyResponse keyResponse(EKeyWasNotConsumed);
TKeyEvent invalidKeyEvent;
invalidKeyEvent.iCode = !EKeyApplication0;
TRAP(errNo, keyResponse = mCHsAppKeyPluginInstance->HandleKeyEventL(invalidKeyEvent, EEventNull));
QCOMPARE(errNo, KErrNone);
QCOMPARE(keyResponse, EKeyWasNotConsumed);
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
//
void T_HsAppKeyHandler::testHandleKeyEventConsumesEverySecondEventForAppKey()
{
TInt errNo(KErrNone);
TKeyResponse keyResponse(EKeyWasNotConsumed);
// verify that for every supported key we consume every second event and ignore the others
RArray<TKeyEvent> keyEventArray;
CleanupClosePushL(keyEventArray);
TRAP(errNo, mCHsAppKeyPluginInstance->ProvideKeyEventsL(keyEventArray));
QCOMPARE(errNo, KErrNone);
for (TInt i(0); i != keyEventArray.Count(); ++i) {
TKeyEvent keyEvent = keyEventArray[i];
// first event ignored
TRAP(errNo, keyResponse = mCHsAppKeyPluginInstance->HandleKeyEventL(keyEvent, EEventNull));
QCOMPARE(errNo, KErrNone);
QCOMPARE(keyResponse, EKeyWasNotConsumed);
// second event consumed
TRAP(errNo, keyResponse = mCHsAppKeyPluginInstance->HandleKeyEventL(keyEvent, EEventNull));
QCOMPARE(errNo, KErrNone);
QCOMPARE(keyResponse, EKeyWasConsumed);
}
CleanupStack::PopAndDestroy(&keyEventArray);
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
//
void T_HsAppKeyHandler::testShortPressSwitchesBetweenHsAndApplibWhenTsIsNotVisible()
{
// verify preconditions
QCOMPARE(isTaskSwitcherVisible(), false);
QValueSpaceSubscriber hsStateGetter(QString("%1/%2").arg(HsStatePSKeyPath).arg(HsStatePSKeySubPath));
QVERIFY(hsStateGetter.isConnected());
// make sure we start from homescreen
if (hsStateGetter.value().toInt() != EHomeScreenIdleState) {
QVERIFY(makeShortPress());
}
QVariant initialState = hsStateGetter.value();
QVERIFY(makeShortPress());
QVERIFY(hsStateGetter.value() != initialState);
QVERIFY(makeShortPress());
QVERIFY(hsStateGetter.value() == initialState);
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
//
void T_HsAppKeyHandler::testLongPressShowsTaskSwitcher()
{
// verify preconditions
QCOMPARE(isTaskSwitcherVisible(), false);
QVERIFY(makeLongPress());
QCOMPARE(isTaskSwitcherVisible(), true);
// second longpress does nothing
QVERIFY(makeLongPress());
QCOMPARE(isTaskSwitcherVisible(), true);
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
//
void T_HsAppKeyHandler::testShortPressDismissesTaskSwitcherShownByLongpress()
{
// verify preconditions
QCOMPARE(isTaskSwitcherVisible(), false);
QVERIFY(makeLongPress());
QCOMPARE(isTaskSwitcherVisible(), true);
QVERIFY(makeShortPress());
QCOMPARE(isTaskSwitcherVisible(), false);
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
//
void T_HsAppKeyHandler::testLongpressDoesNothingIfTaskSwitcherIsShownByOtherComponent()
{
// verify preconditions
QCOMPARE(isTaskSwitcherVisible(), false);
QVERIFY(!mDialog);
QVERIFY(showTaskSwitcher());
QCOMPARE(isTaskSwitcherVisible(), true);
QVERIFY(makeLongPress());
QCOMPARE(isTaskSwitcherVisible(), true);
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
//
void T_HsAppKeyHandler::testShortPressDismissesTaskSwitcherShownByOtherComponent()
{
// verify preconditions
QCOMPARE(isTaskSwitcherVisible(), false);
QVERIFY(!mDialog);
QVERIFY(showTaskSwitcher());
QCOMPARE(isTaskSwitcherVisible(), true);
// after short press the TaskSwitcher will call DeviceDialogClosed callback
// of MHbDeviceDialogObserver, which should delete and clear mDialog member.
QVERIFY(makeShortPress());
QTest::qWait(1000);
QCOMPARE(isTaskSwitcherVisible(), false);
QVERIFY(!mDialog);
}
// -----------------------------------------------------------------------------
// HELPER MEHTODS
// -----------------------------------------------------------------------------
//
bool T_HsAppKeyHandler::makeShortPress()
{
TKeyEvent shortpress = {EKeyApplication0, EStdKeyApplication0, 0, 0};
return sendKeyEventTwice(shortpress);
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
//
bool T_HsAppKeyHandler::makeLongPress()
{
TKeyEvent longpress = {EKeyApplication0, EStdKeyApplication0, 0, 1};
return sendKeyEventTwice(longpress);
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
//
bool T_HsAppKeyHandler::sendKeyEventTwice(TKeyEvent keyEvent)
{
Q_ASSERT(mCHsAppKeyPluginInstance);
TKeyResponse keyResponse(EKeyWasNotConsumed);
// send key event twice (HandleKeyEventL accepts every second event)
TRAPD(errNo,
mCHsAppKeyPluginInstance->HandleKeyEventL(keyEvent, EEventNull);
keyResponse = mCHsAppKeyPluginInstance->HandleKeyEventL(keyEvent, EEventNull);
);
return (KErrNone == errNo) && (EKeyWasConsumed == keyResponse);
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
//
bool T_HsAppKeyHandler::isTaskSwitcherVisible()
{
QValueSpaceSubscriber tsVisibilityGetter(QString("%1/%2").arg(TsProperty::KTsPath).arg(TsProperty::KVisibilityPath));
Q_ASSERT(tsVisibilityGetter.isConnected());
QVariant tsVisibility = tsVisibilityGetter.value();
Q_ASSERT(tsVisibility.isValid());
return tsVisibility.toBool();
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
//
bool T_HsAppKeyHandler::showTaskSwitcher()
{
mDialog = CHbDeviceDialogSymbian::NewL();
QScopedPointer<CHbSymbianVariantMap> params(CHbSymbianVariantMap::NewL());
return KErrNone == mDialog->Show(KTsPluginName, *params, this);
}
// ---------------------------------------------------------------------------
// MHbDeviceDialogObserver implementation
// ---------------------------------------------------------------------------
//
void T_HsAppKeyHandler::DataReceived(CHbSymbianVariantMap &/*aData*/)
{
//no implementation required
}
void T_HsAppKeyHandler::DeviceDialogClosed(TInt /*aCompletionCode*/)
{
delete mDialog;
mDialog = 0;
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
//
QTEST_MAIN(T_HsAppKeyHandler)