From 84a80191d51b0774f89d849cb9095b0ee907f12a Mon Sep 17 00:00:00 2001 From: Martin Wolf Date: Fri, 12 Feb 2010 18:20:11 +0200 Subject: Added Qt resource client --- debian/resourceqt-client.install | 1 + libresourceqt.pro | 1 + resourceqt-client/client.cpp | 475 ++++++++++++++++++++++++++++++++ resourceqt-client/client.h | 62 +++++ resourceqt-client/resourceqt-client.cpp | 203 ++++++++++++++ resourceqt-client/resourceqt-client.pro | 24 ++ 6 files changed, 766 insertions(+) create mode 100644 debian/resourceqt-client.install create mode 100644 resourceqt-client/client.cpp create mode 100644 resourceqt-client/client.h create mode 100644 resourceqt-client/resourceqt-client.cpp create mode 100644 resourceqt-client/resourceqt-client.pro diff --git a/debian/resourceqt-client.install b/debian/resourceqt-client.install new file mode 100644 index 0000000..fc612f0 --- /dev/null +++ b/debian/resourceqt-client.install @@ -0,0 +1 @@ +usr/bin/resourceqt-client \ No newline at end of file diff --git a/libresourceqt.pro b/libresourceqt.pro index 7801d61..c5814e4 100644 --- a/libresourceqt.pro +++ b/libresourceqt.pro @@ -7,5 +7,6 @@ TEMPLATE = subdirs SUBDIRS = libdbus-qeventloop \ libresourceqt \ + resourceqt-client \ tests diff --git a/resourceqt-client/client.cpp b/resourceqt-client/client.cpp new file mode 100644 index 0000000..28d4169 --- /dev/null +++ b/resourceqt-client/client.cpp @@ -0,0 +1,475 @@ +#include +#include + +#include +#include +#include + +#include "client.h" + +Client::Client(QString appClass) : QObject() +{ + applicationClass = appClass; + resourceSet = NULL; + + standardInput = new QTextStream(stdin, QFile::ReadOnly); + mainTimerID = startTimer(0); +} + +Client::~Client() +{ + killTimer(mainTimerID); + + if( resourceSet != NULL ) + { + delete resourceSet; + resourceSet = NULL; + } + + if( standardInput != NULL ) + { + delete standardInput; + standardInput = NULL; + } +} + +uint32_t Client::parseResourceList(QString resourceListStr) +{ + struct + { + uint32_t resourceType; + const char* resourceName; + } + resourceDef[] = + { + { RES_AUDIO_PLAYBACK , "AudioPlayback" }, + { RES_VIDEO_PLAYBACK , "VideoPlayback" }, + { RES_AUDIO_RECORDING, "AudioRecording" }, + { RES_VIDEO_RECORDING, "VideoRecording" }, + { RES_VIBRA , "Vibra" }, + { RES_LEDS , "Leds" }, + { RES_BACKLIGHT , "BackLight" }, + { RES_SYSTEM_BUTTON , "SystemButton" }, + { RES_LOCK_BUTTON , "LockButton" }, + { RES_SCALE_BUTTON , "ScaleButton" }, + { RES_SNAP_BUTTON , "SnapButton" }, + { RES_LENS_COVER , "LensCover" }, + { 0 , NULL } + }; + + uint32_t resourceList = 0; + + if( resourceListStr.isEmpty() || resourceListStr.isNull() ) + { + return 0; + } + else + { + QStringList resList = resourceListStr.split(",", QString::SkipEmptyParts); + + for( int i = 0; i < resList.count(); i++ ) + { + int pos = 0; + while( resourceDef[pos].resourceName != NULL ) + { + if( resList[i] == resourceDef[pos].resourceName ) + break; + + pos++; + } + + if( !resourceDef[pos].resourceName ) + { + const char* res = qPrintable(resList[i]); + printf("Ignoring invalid resource name '%s'\n", res); + } + else + { + resourceList |= resourceDef[pos].resourceType; + } + } + } + + return resourceList; +} + +void Client::showPrompt() +{ + printf("res-client> "); + fflush(stdout); +} + +void Client::updateSet(uint32_t list, uint32_t optional, bool remove) +{ + uint32_t resources[] = + { + RES_AUDIO_PLAYBACK, RES_VIDEO_PLAYBACK, RES_AUDIO_RECORDING, RES_VIDEO_RECORDING, + RES_VIBRA, RES_LEDS, RES_BACKLIGHT, RES_SYSTEM_BUTTON, RES_LOCK_BUTTON, + RES_SCALE_BUTTON, RES_SNAP_BUTTON, RES_LENS_COVER, 0 + }; + + int pos = 0; + while( resources[pos] ) + { + if( list & resources[pos] ) + { + Resource* resource = NULL; + ResourceType res = getResourceType(resources[pos]); + bool opt = (optional & resources[pos]) == resources[pos]; + + if( remove ) + { + if( !resourceSet->contains(res) ) + { + continue; + } + + if( optional ) + { + resource = resourceSet->resource(res); + resource->setOptional(false); + } + else + { + resourceSet->deleteResource(res); + } + } + else + { + if( resourceSet->contains(res) ) + { + resource = resourceSet->resource(res); + if( resource->isOptional() != opt ) + { + resource->setOptional(opt); + } + + continue; + } + + resource = allocateResource(res, opt); + if( resource ) + { + resourceSet->addResource(resource); + } + } + } + + pos++; + } +} + +bool Client::initialize(uint32_t all, uint32_t optional) +{ + resourceSet = new ResourceSet(applicationClass); + if( resourceSet == NULL ) + { + return false; + } + + updateSet(all, optional, false); + + if( !connect(resourceSet, SIGNAL(resourcesGranted(QList)), this, SLOT(resourceAcquiredHandler(QList))) ) + { + return false; + } + + if( !connect(resourceSet, SIGNAL(resourcesDenied()), this, SLOT(resourceDeniedHandler())) ) + { + return false; + } + + if( !connect(resourceSet, SIGNAL(lostResources()), this, SLOT(resourceLostHandler())) ) + { + return false; + } + + showPrompt(); + + return true; +} + +Resource* Client::allocateResource(ResourceType resource, bool optional) +{ + Resource* retValue = NULL; + + switch( resource ) + { + case AudioPlaybackType: + retValue = new AudioResource(); + break; + case VideoPlaybackType: + retValue = new VideoResource(); + break; + case AudioRecorderType: + retValue = new AudioRecorderResource(); + break; + case VideoRecorderType: + retValue = new VideoRecorderResource(); + break; + case VibraType: + retValue = new VibraResource(); + break; + case LedsType: + retValue = new LedsResource(); + break; + case BacklightType: + retValue = new BacklightResource(); + break; + case SystemButtonType: + retValue = new SystemButtonResource(); + break; + case LockButtonType: + retValue = new LockButtonResource(); + break; + case ScaleButtonType: + retValue = new ScaleButtonResource(); + break; + case SnapButtonType: + retValue = new SnapButtonResource(); + break; + case LensCoverType: + retValue = new LensCoverResource(); + break; + case NumberOfTypes: + return NULL; + } + + if( retValue ) + { + retValue->setOptional(optional); + } + else + { + printf("Unknown resource type - %d\n", resource); + } + + return retValue; +} + +ResourceType Client::getResourceType(uint32_t resource) +{ + switch( resource ) + { + case RES_AUDIO_PLAYBACK: + return AudioPlaybackType; + case RES_VIDEO_PLAYBACK: + return VideoPlaybackType; + case RES_AUDIO_RECORDING: + return AudioRecorderType; + case RES_VIDEO_RECORDING: + return VideoRecorderType; + case RES_VIBRA: + return VibraType; + case RES_LEDS: + return LedsType; + case RES_BACKLIGHT: + return BacklightType; + case RES_SYSTEM_BUTTON: + return SystemButtonType; + case RES_LOCK_BUTTON: + return LockButtonType; + case RES_SCALE_BUTTON: + return ScaleButtonType; + case RES_SNAP_BUTTON: + return SnapButtonType; + case RES_LENS_COVER: + return LensCoverType; + } + + return NumberOfTypes; +} + +void Client::showResources(const QList resList) +{ + const char* resTypes[] = + { + "AudioPlayback", "VideoPlayback", "AudioRecorder", "VideoRecorder", "Vibra", + "Leds", "Backlight", "SystemButton", "LockButton", "ScaleButton", "SnapButton", + "LensCover" + }; + + for( int i = 0; i < resList.count(); i++ ) + { + printf("\t%s\n", resTypes[resList[i]]); + } +} + +void Client::showResources(const QList resList) +{ + const char* resTypes[] = + { + "AudioPlayback", "VideoPlayback", "AudioRecorder", "VideoRecorder", "Vibra", + "Leds", "Backlight", "SystemButton", "LockButton", "ScaleButton", "SnapButton", + "LensCover" + }; + + for( int i = 0; i < resList.count(); i++ ) + { + Resource* r = resList[i]; + printf("\t%s%s%s\n", resTypes[r->type()], + r->isOptional() ? " (optional)" : "", + r->isGranted() ? "(granted)" : ""); + } +} + +void Client::resourceAcquiredHandler(const QList& resList) +{ + printf("\nManager grants access to these resources:\n"); + showResources(resList); + showPrompt(); +} + +void Client::resourceDeniedHandler() +{ + printf("\nManager denies access to resources!\n"); + showPrompt(); +} + +void Client::resourceLostHandler() +{ + printf("\nLost resources from manager!\n"); + showPrompt(); +} + +void Client::timerEvent(QTimerEvent*) +{ + bool quitFlag = false; + + fd_set stdinfd; + FD_ZERO(&stdinfd); + FD_SET(0, &stdinfd); + timeval tv; + tv.tv_sec = 0; + tv.tv_usec = 0; + + int ready = select(1, &stdinfd, NULL, NULL, &tv); + if( ready > 0 ) + { + QString line = standardInput->readLine(); + if( !line.isNull() ) + { + QStringList params = line.split(" "); + if( params[0] == "quit" ) + { + quitFlag = true; + QMetaObject::invokeMethod(QCoreApplication::instance(), "quit"); + } + else if( params[0] == "help" ) + { + printf("Available commands:\n"); + printf("\t help \tprint this help message\n"); + printf("\t quit \texit application\n"); + printf("\t acquire\tacquire required resources\n"); + printf("\t release\trelease resources\n"); + printf("\t update\tupdate modified resource set after add or remove command\n"); + printf("\t add reslist [-o]\tadd reosurce list, if -o provided, set as optional\n"); + printf("\t remove reslist [-o]\tremove reosurce list, if -o provided, removed only optional flag\n"); + printf("\t audio \tnot implemented ....\n"); + printf("\t show \tshow resources\n"); + } + else if( params[0] == "show" ) + { + if( !resourceSet ) + { + printf("Show failed!\n"); + } + else + { + QList list = resourceSet->resources(); + if( !list.count() ) + { + printf("Resource set is empty, use add command to add some ...\n"); + } + else + { + printf("Resource set:\n"); + showResources(list); + } + } + } + else if( params[0] == "acquire" ) + { + if( !resourceSet || !resourceSet->acquire() ) + { + printf("Acquire failed!\n"); + } + } + else if( params[0] == "release" ) + { + if( !resourceSet || !resourceSet->release() ) + { + printf("Release failed!\n"); + } + } + else if( params[0] == "add" ) + { + if( !resourceSet ) + { + printf("Update failed!\n"); + } + else if( params.count() == 1 || params[1].isEmpty() || params[1].isNull() ) + { + printf("List of desired resources is missing. See help ...\n"); + } + else + { + uint32_t temp = Client::parseResourceList(params[1]); + if( params.count() > 2 && params[2] == "-o" ) + { + updateSet(temp, temp, false); + } + else + { + updateSet(temp, 0, false); + } + } + } + else if( params[0] == "remove" ) + { + if( !resourceSet || params.count() == 1 ) + { + printf("Update failed!\n"); + } + else if( params.count() == 1 || params[1].isEmpty() || params[1].isNull() ) + { + printf("List of desired resources is missing. See help ...\n"); + } + else + { + uint32_t temp = Client::parseResourceList(params[1]); + if( params.count() > 2 && params[2] == "-o" ) + { + updateSet(temp, temp, true); + } + else + { + updateSet(temp, 0, true); + } + } + } + else if( params[0] == "update" ) + { + if( !resourceSet || !resourceSet->update() ) + { + printf("Update failed!\n"); + } + } + else if( params[0] == "audio" ) + { + printf("Not yet implemented!\n"); + } + else if( !params[0].isEmpty() ) + { + QByteArray ba = line.toLatin1(); + const char *c_line = ba.data(); + printf("unknown command '%s'\n", c_line); + } + + if( !quitFlag ) + { + showPrompt(); + } + } + } +} diff --git a/resourceqt-client/client.h b/resourceqt-client/client.h new file mode 100644 index 0000000..3399d02 --- /dev/null +++ b/resourceqt-client/client.h @@ -0,0 +1,62 @@ +#ifndef _CLIENT_H_ +#define _CLIENT_H_ + +#include +#include + +#include + +using namespace ResourcePolicy; + +#define RES_AUDIO_PLAYBACK (1<<0) +#define RES_VIDEO_PLAYBACK (1<<1) +#define RES_AUDIO_RECORDING (1<<2) +#define RES_VIDEO_RECORDING (1<<3) +#define RES_VIBRA (1<<4) +#define RES_LEDS (1<<5) +#define RES_BACKLIGHT (1<<6) +#define RES_SYSTEM_BUTTON (1<<7) +#define RES_LOCK_BUTTON (1<<8) +#define RES_SCALE_BUTTON (1<<9) +#define RES_SNAP_BUTTON (1<<10) +#define RES_LENS_COVER (1<<11) + +class Client : public QObject +{ + Q_OBJECT + +public: + Client(QString appClass); + ~Client(); + + bool initialize(uint32_t all, uint32_t optional); + static uint32_t parseResourceList(QString resourceListStr); + +private slots: + void resourceAcquiredHandler(const QList& resList); + void resourceDeniedHandler(); + void resourceLostHandler(); + +protected: + void timerEvent(QTimerEvent *e); + +private: + QTextStream* standardInput; + int mainTimerID; + + uint32_t resourcesAll; + uint32_t resourcesOptional; + QString applicationClass; + + ResourceSet* resourceSet; + + Resource* allocateResource(ResourceType resource, bool optional); + ResourceType getResourceType(uint32_t resource); + + void showPrompt(); + void showResources(const QList resList); + void showResources(const QList resList); + void updateSet(uint32_t list, uint32_t optional, bool remove); +}; + +#endif diff --git a/resourceqt-client/resourceqt-client.cpp b/resourceqt-client/resourceqt-client.cpp new file mode 100644 index 0000000..f17ebaf --- /dev/null +++ b/resourceqt-client/resourceqt-client.cpp @@ -0,0 +1,203 @@ +#include +#include +#include +#include +#include +#include +#include +#include "client.h" + +class CommandLineParser +{ +public: + CommandLineParser(int argc, char** argv) + { + exitCode = 0; + exitFlag = false; + exeName = strdup(basename(argv[0])); + + resourcesAll = 0; + resourcesOptional = 0; + + parseArguments(argc, argv); + } + + ~CommandLineParser() + { + if( exeName != NULL ) + { + delete exeName; + exeName = NULL; + } + } + +public: + bool exitFlag; + int exitCode; + + uint32_t resourcesAll; + uint32_t resourcesOptional; + QString applicationClass; + + void printMessage(const char *fmt, ...) + { + va_list ap; + char fmtbuf[512]; + + snprintf(fmtbuf, sizeof(fmtbuf), "%s\n", fmt); + va_start(ap, fmt); + vprintf(fmtbuf, ap); + va_end(ap); + } + +private: + char* exeName; + + void printError(const char *fmt, ...) + { + va_list ap; + char fmtbuf[512]; + + snprintf(fmtbuf, sizeof(fmtbuf), "%s\n", fmt); + va_start(ap, fmt); + vprintf(fmtbuf, ap); + va_end(ap); + + exitCode = errno; + exitFlag = true; + } + + void parseArguments(int argc, char** argv) + { + int option; + + while( (option = getopt(argc, argv, "hf:s:")) != -1 ) + { + switch (option) + { + case 'h': + usage(0); + return; + case 'f': + printf("-f - not implemented!\n"); + //config.mode = parseModeValues(optarg, 1); + break; + case 'o': + resourcesOptional = Client::parseResourceList(optarg); + break; + default: + usage(EINVAL); + return; + } + } + + if( (optind != argc - 2) && (optind != argc - 1) ) + { + usage(EINVAL); + return; + } + else + { + applicationClass = parseClassString(argv[optind]); + if( argc > optind + 1 ) + resourcesAll = Client::parseResourceList(argv[optind+1]); + else + resourcesAll = 0; + } + + if( !resourcesAll ) + { + printMessage("No resources found, use add command to add some ..."); + } + + if( (resourcesAll | resourcesOptional) != resourcesAll ) + { + printError("optional resources are not subset of all resources"); + } + } + + char* parseClassString(char *str) + { + if( strcmp(str, "call" ) && + strcmp(str, "camera" ) && + strcmp(str, "ringtone" ) && + strcmp(str, "alarm" ) && + strcmp(str, "navigator" ) && + strcmp(str, "game" ) && + strcmp(str, "player" ) && + strcmp(str, "event" ) && + strcmp(str, "background") ) + { + printError("invalid class '%s'", str); + return NULL; + } + + return str; + } + + void usage(int theExitCode) + { + printf("usage: %s [-h] [-t] [-v] [-f mode-values]" + "[-o optional-resources] [-s shared-resources -m shared-mask] " + "class all-resources\n", + exeName); + printf("\toptions:\n"); + printf("\t h\tprint this help message and exit\n"); + printf("\t f\tmode values. See 'modes' below for the " + "\n\t\tsyntax of \n"); + printf("\t o\toptional resources. See 'resources' below for the " + "syntax of\n\t\t\n"); + printf("\tclass:\n"); + printf("\t\tcall\t - for native or 3rd party telephony\n"); + printf("\t\tcamera\t - for photo applications\n"); + printf("\t\tringtone - for ringtones\n"); + printf("\t\talarm\t - for alarm clock\n"); + printf("\t\tnavigator - for mapping applications\n"); + printf("\t\tgame\t - for gaming\n"); + printf("\t\tplayer\t - for media playback/recording\n"); + printf("\t\tevent\t - for messaging and other event notifications\n"); + printf("\t\tbackground - for thumbnailing etc\n"); + printf("\tresources:\n"); + printf("\t comma separated list of the following resources\n"); + printf("\t\tAudioPlayback\n"); + printf("\t\tVideoPlayback\n"); + printf("\t\tAudioRecording\n"); + printf("\t\tVideoRecording\n"); + printf("\t\tVibra\n"); + printf("\t\tLeds\n"); + printf("\t\tBackLight\n"); + printf("\t\tSystemButton\n"); + printf("\t\tLockButton\n"); + printf("\t\tScaleButton\n"); + printf("\t\tSnapButton\n"); + printf("\t\tLensCover\n"); + printf("\t no whitespace allowed in the resource list.\n"); + printf("\tmodes:\n"); + printf("\t comma separated list of the following modes\n"); + printf("\t\tAutoRelease\n"); + printf("\t\tAlwaysReply\n"); + fflush(stdout); + + exitCode = theExitCode; + exitFlag = true; + } +}; + +int main(int argc, char *argv[]) +{ + CommandLineParser parser(argc, argv); + + if( parser.exitFlag ) + return parser.exitCode; + + QCoreApplication app(argc, argv); + + Client client(parser.applicationClass); + if( !client.initialize(parser.resourcesAll, parser.resourcesOptional) ) + { + parser.printMessage("initialization failed!"); + return EINVAL; + } + + return app.exec(); +} diff --git a/resourceqt-client/resourceqt-client.pro b/resourceqt-client/resourceqt-client.pro new file mode 100644 index 0000000..b01041c --- /dev/null +++ b/resourceqt-client/resourceqt-client.pro @@ -0,0 +1,24 @@ +include(../common.pri) + +TEMPLATE = app +TARGET = resourceqt-client +MOC_DIR = .moc +OBJECTS_DIR = .obj +DEPENDPATH += . +QT = core +CONFIG += console +CONFIG -= app_bundle + +INCLUDEPATH += $${LIBRESOURCEINC} +QMAKE_CXXFLAGS += -Wall +LIBS += -L../libresourceqt/build -lresourceqt + +# Input +HEADERS = client.h +SOURCES += resourceqt-client.cpp client.cpp + +QMAKE_DISTCLEAN += -r .moc .obj + +# Install options +target.path = /usr/bin/ +INSTALLS = target -- cgit v1.2.3