From 254676322463778319e4a1b572d6c76f9c256393 Mon Sep 17 00:00:00 2001 From: ninerider Date: Fri, 19 Feb 2010 10:48:27 +0100 Subject: Remote lib extensions for Windows Mobile device power operations. Function to change the power mode and to reset the device were added. The reset is needed to put the device in a defined state after an error has occurred. The unattended power mode ensures that the reset can be effected and that the device will not go to sleep. Reviewed by: Joerg --- tools/qtestlib/wince/remotelib/commands.cpp | 86 +++++++++++++++++++++++++++++ tools/qtestlib/wince/remotelib/commands.h | 3 + 2 files changed, 89 insertions(+) diff --git a/tools/qtestlib/wince/remotelib/commands.cpp b/tools/qtestlib/wince/remotelib/commands.cpp index 4244424..88bf9e6 100644 --- a/tools/qtestlib/wince/remotelib/commands.cpp +++ b/tools/qtestlib/wince/remotelib/commands.cpp @@ -39,6 +39,9 @@ ** ****************************************************************************/ #include "commands.h" +#include +#include + #define CLEAN_FAIL(a) {delete appName; \ delete arguments; \ @@ -124,3 +127,86 @@ bool qRemoteExecute(const wchar_t* program, const wchar_t* arguments, int *retur } return true; } +/** +\brief Reset the device. +*/ +int qRemoteSoftReset(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream* stream) +{ + //POWER_STATE_ON On state + //POWER_STATE_OFF Off state + //POWER_STATE_CRITICAL Critical state + //POWER_STATE_BOOT Boot state + //POWER_STATE_IDLE Idle state + //POWER_STATE_SUSPEND Suspend state + //POWER_STATE_RESET Reset state + + DWORD returnValue = SetSystemPowerState(0, POWER_STATE_RESET, POWER_FORCE); + return returnValue; +} + +/** +\brief Toggle the unattended powermode of the device +*/ +int qRemoteToggleUnattendedPowerMode(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream* stream) +{ + if (!stream) + return -1; + + DWORD bytesRead; + int toggleVal = 0; + int returnValue = S_OK; + + if (S_OK != stream->Read(&toggleVal, sizeof(toggleVal), &bytesRead)) + return -2; + + //PPN_REEVALUATESTATE 0x0001 Reserved. Set dwData to zero (0). + //PPN_POWERCHANGE 0x0002 Reserved. Set dwData to zero (0). + //PPN_UNATTENDEDMODE 0x0003 Set dwData to TRUE or FALSE. + //PPN_SUSPENDKEYPRESSED or + //PPN_POWERBUTTONPRESSED 0x0004 Reserved. Set dwData to zero (0). + //PPN_SUSPENDKEYRELEASED 0x0005 Reserved. Set dwData to zero (0). + //PPN_APPBUTTONPRESSED 0x0006 Reserved. Set dwData to zero (0). + //PPN_OEMBASE Greater than or equal to 0x10000 + //You can define higher values, such as 0x10001, 0x10002, and so on. + // Reserved. Set dwData to zero (0). + returnValue = PowerPolicyNotify(PPN_UNATTENDEDMODE, toggleVal); + + if (S_OK != stream->Write(&returnValue, sizeof(returnValue), &bytesRead)) + return -3; + else + return S_OK; +} + +/** +\brief Virtually press the power button of the device +*/ +int qRemotePowerButton(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream* stream) +{ + if (!stream) + return -1; + + DWORD bytesRead; + int toggleVal = 0; + int returnValue = S_OK; + + if (S_OK != stream->Read(&toggleVal, sizeof(toggleVal), &bytesRead)) + return -2; + + //PPN_REEVALUATESTATE 0x0001 Reserved. Set dwData to zero (0). + //PPN_POWERCHANGE 0x0002 Reserved. Set dwData to zero (0). + //PPN_UNATTENDEDMODE 0x0003 Set dwData to TRUE or FALSE. + //PPN_SUSPENDKEYPRESSED or + //PPN_POWERBUTTONPRESSED 0x0004 Reserved. Set dwData to zero (0). + //PPN_SUSPENDKEYRELEASED 0x0005 Reserved. Set dwData to zero (0). + //PPN_APPBUTTONPRESSED 0x0006 Reserved. Set dwData to zero (0). + //PPN_OEMBASE Greater than or equal to 0x10000 + //You can define higher values, such as 0x10001, 0x10002, and so on. + // Reserved. Set dwData to zero (0). + returnValue = PowerPolicyNotify(PPN_POWERBUTTONPRESSED, 0); + + if (S_OK != stream->Write(&returnValue, sizeof(returnValue), &bytesRead)) + return -3; + else + return S_OK; +} + diff --git a/tools/qtestlib/wince/remotelib/commands.h b/tools/qtestlib/wince/remotelib/commands.h index c5cc926..8f202c8 100644 --- a/tools/qtestlib/wince/remotelib/commands.h +++ b/tools/qtestlib/wince/remotelib/commands.h @@ -45,6 +45,9 @@ extern "C" { int __declspec(dllexport) qRemoteLaunch(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream*); + int __declspec(dllexport) qRemoteSoftReset(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream* stream); + int __declspec(dllexport) qRemoteToggleUnattendedPowerMode(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream* stream); + int __declspec(dllexport) qRemotePowerButton(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream* stream); bool __declspec(dllexport) qRemoteExecute(const wchar_t* program, const wchar_t* arguments = NULL, int *returnValue = NULL , DWORD* error = NULL, int timeout = -1); } -- cgit v0.12 From 1d75abb9a481b058f5251b83446aa0e171217786 Mon Sep 17 00:00:00 2001 From: ninerider Date: Fri, 19 Feb 2010 10:50:47 +0100 Subject: Cetest extensions for Windows Mobile device power operations. Options to reset (-reset) and change the power mode (-wake) of the device were added. The reset is needed to put the device in a defined state after an error has occurred. The unattended power mode ensures that the reset can be effected and that the device will not go to sleep. Reviewed by: Joerg --- .../qtestlib/wince/cetest/activesyncconnection.cpp | 139 +++++++++++++++++++++ tools/qtestlib/wince/cetest/activesyncconnection.h | 3 + tools/qtestlib/wince/cetest/main.cpp | 48 +++++++ 3 files changed, 190 insertions(+) diff --git a/tools/qtestlib/wince/cetest/activesyncconnection.cpp b/tools/qtestlib/wince/cetest/activesyncconnection.cpp index 56fb173..98062ed 100644 --- a/tools/qtestlib/wince/cetest/activesyncconnection.cpp +++ b/tools/qtestlib/wince/cetest/activesyncconnection.cpp @@ -443,6 +443,145 @@ bool ActiveSyncConnection::execute(QString program, QString arguments, int timeo return result; } +bool ActiveSyncConnection::setDeviceAwake(bool activate, int *returnValue) +{ + if (!isConnected()) { + qWarning("Cannot execute, connect to device first!"); + return false; + } + bool result = false; + + // If we want to wait, we have to use CeRapiInvoke, as CeCreateProcess has no way to wait + // until the process ends. The lib must have been build and also deployed already. + if (!isConnected() && !connect()) + return false; + + HRESULT res = S_OK; + + //SYSTEM_POWER_STATUS_EX systemPowerState; + + //res = CeGetSystemPowerStatusEx(&systemPowerState, true); + + QString dllLocation = "\\Windows\\QtRemote.dll"; + QString functionName = "qRemoteToggleUnattendedPowerMode"; + + DWORD outputSize; + BYTE* output; + IRAPIStream *stream; + int returned = 0; + int toggle = int(activate); + + res = CeRapiInvoke(dllLocation.utf16(), functionName.utf16(), 0, 0, &outputSize, &output, &stream, 0); + if (S_OK != res) { + DWORD ce_error = CeGetLastError(); + if (S_OK != ce_error) { + qWarning("Error invoking %s on %s: %s", qPrintable(functionName), + qPrintable(dllLocation), strwinerror(ce_error).constData()); + } else { + qWarning("Error: %s on %s unexpectedly returned %d", qPrintable(functionName), + qPrintable(dllLocation), res); + } + } else { + DWORD written; + + if (S_OK != stream->Write(&toggle, sizeof(toggle), &written)) { + qWarning(" Could not write toggle option to process"); + return false; + } + + if (S_OK != stream->Read(&returned, sizeof(returned), &written)) { + qWarning(" Could not access return value of process"); + } + else + result = true; + } + + if (returnValue) + *returnValue = returned; + + return result; +} + +bool ActiveSyncConnection::resetDevice() +{ + if (!isConnected()) { + qWarning("Cannot execute, connect to device first!"); + return false; + } + + bool result = false; + if (!isConnected() && !connect()) + return false; + + QString dllLocation = "\\Windows\\QtRemote.dll"; + QString functionName = "qRemoteSoftReset"; + + DWORD outputSize; + BYTE* output; + IRAPIStream *stream; + + int returned = 0; + + HRESULT res = CeRapiInvoke(dllLocation.utf16(), functionName.utf16(), 0, 0, &outputSize, &output, &stream, 0); + if (S_OK != res) { + DWORD ce_error = CeGetLastError(); + if (S_OK != ce_error) { + qWarning("Error invoking %s on %s: %s", qPrintable(functionName), + qPrintable(dllLocation), strwinerror(ce_error).constData()); + } else { + qWarning("Error: %s on %s unexpectedly returned %d", qPrintable(functionName), + qPrintable(dllLocation), res); + } + } else { + result = true; + } + return result; +} + +bool ActiveSyncConnection::toggleDevicePower(int *returnValue) +{ + if (!isConnected()) { + qWarning("Cannot execute, connect to device first!"); + return false; + } + + bool result = false; + if (!isConnected() && !connect()) + return false; + + QString dllLocation = "\\Windows\\QtRemote.dll"; + QString functionName = "qRemotePowerButton"; + + DWORD outputSize; + BYTE* output; + IRAPIStream *stream; + int returned = 0; + + HRESULT res = CeRapiInvoke(dllLocation.utf16(), functionName.utf16(), 0, 0, &outputSize, &output, &stream, 0); + if (S_OK != res) { + DWORD ce_error = CeGetLastError(); + if (S_OK != ce_error) { + qWarning("Error invoking %s on %s: %s", qPrintable(functionName), + qPrintable(dllLocation), strwinerror(ce_error).constData()); + } else { + qWarning("Error: %s on %s unexpectedly returned %d", qPrintable(functionName), + qPrintable(dllLocation), res); + } + } else { + DWORD written; + if (S_OK != stream->Read(&returned, sizeof(returned), &written)) { + qWarning(" Could not access return value of process"); + } + else { + result = true; + } + } + + if (returnValue) + *returnValue = returned; + return result; +} + bool ActiveSyncConnection::createDirectory(const QString &path, bool deleteBefore) { if (deleteBefore) diff --git a/tools/qtestlib/wince/cetest/activesyncconnection.h b/tools/qtestlib/wince/cetest/activesyncconnection.h index 1891514..4502fc7 100644 --- a/tools/qtestlib/wince/cetest/activesyncconnection.h +++ b/tools/qtestlib/wince/cetest/activesyncconnection.h @@ -79,6 +79,9 @@ public: bool createDirectory(const QString&, bool deleteBefore=false); bool execute(QString program, QString arguments = QString(), int timeout = -1, int *returnValue = NULL); + bool resetDevice(); + bool toggleDevicePower(int *returnValue = NULL); + bool setDeviceAwake(bool activate, int *returnValue = NULL); private: bool connected; }; diff --git a/tools/qtestlib/wince/cetest/main.cpp b/tools/qtestlib/wince/cetest/main.cpp index 146cc5a..9fe5f02 100644 --- a/tools/qtestlib/wince/cetest/main.cpp +++ b/tools/qtestlib/wince/cetest/main.cpp @@ -45,6 +45,9 @@ # include "activesyncconnection.h" #endif +const int SLEEP_AFTER_RESET = 60000; // sleep for 1 minute +const int SLEEP_RECONNECT = 2000; // sleep for 2 seconds before trying another reconnect + #include "deployment.h" #include #include @@ -123,6 +126,8 @@ void usage() " -debug : Test debug version[default]\n" " -release : Test release version\n" " -libpath : Remote path to deploy Qt libraries to\n" + " -reset : Reset device before starting a test\n" + " -awake : Device does not go sleep mode\n" " -qt-delete : Delete the Qt libraries after execution\n" " -project-delete : Delete the project file(s) after execution\n" " -delete : Delete everything deployed after execution\n" @@ -152,6 +157,8 @@ int main(int argc, char **argv) int timeout = -1; bool cleanupQt = false; bool cleanupProject = false; + bool deviceReset = false; + bool keepAwake = false; for (int i=1; i