Merge branch 'master', remote branch 'origin'

pull/1/head
Jussi Lind 15 years ago
commit bc8c2c48fa

@ -15,6 +15,7 @@ usr/bin/fala_wl.launch
usr/bin/fala_wol
usr/bin/fala_wol.sh
usr/bin/fala_gettime
usr/bin/fala_gettime_ms
usr/bin/fala_pixelchanged
usr/share/dbus-1/services/com.nokia.fala_testapp.service
usr/share/dbus-1/services/com.nokia.fala_wl.service

@ -4,6 +4,7 @@ usr/share/applauncherd-testscripts/check_pipes.py
usr/share/applauncherd-testscripts/test-perf-mbooster.py
usr/share/applauncherd-testscripts/tc_theming.rb
usr/share/applauncherd-testscripts/test-perf.rb
usr/share/applauncherd-testscripts/get-coordinates.rb
usr/share/applauncherd-testscripts/utils.py
usr/share/applauncherd-testscripts/test-security.py
usr/share/applauncherd-testscripts/fala_wid

7
debian/changelog vendored

@ -1,3 +1,10 @@
applauncherd (0.15.2) unstable; urgency=low
* Fixes: NB#205006 - Redundant(?) booster-monitor processes takes a lot of memory
* Changed: Modified startup time tests to support command line starting and parameters
-- Alexey Shilov <alexey.shilov@nokia.com> Tue, 23 Nov 2010 17:10:56 +0200
applauncherd (0.15.1) stable; urgency=low
* Fixes: NB#201779 - cheap way how to load all libraries correct

@ -7,8 +7,8 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_HOME_DIRECTORY}/src/comm
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden")
# Set sources
set(SRC appdata.cpp booster.cpp boosterfactory.cpp monitorbooster.cpp connection.cpp daemon.cpp mbooster.cpp logger.cpp main.cpp qtbooster.cpp wrtbooster.cpp)
set(MOC_HDRS monitorbooster.h mbooster.h)
set(SRC appdata.cpp booster.cpp boosterfactory.cpp connection.cpp daemon.cpp mbooster.cpp logger.cpp main.cpp qtbooster.cpp wrtbooster.cpp)
set(MOC_HDRS mbooster.h wrtbooster.h)
qt4_wrap_cpp(MOC_SRC ${MOC_HDRS})
# Use webruntime if found

@ -22,7 +22,6 @@
#include "mbooster.h"
#include "qtbooster.h"
#include "wrtbooster.h"
#include "monitorbooster.h"
BoosterFactory::BoosterFactory()
{}
@ -41,10 +40,6 @@ Booster * BoosterFactory::create(char type)
{
return new WRTBooster();
}
else if (type == MonitorBooster::type())
{
return new MonitorBooster();
}
else
{
return NULL;
@ -65,10 +60,6 @@ void BoosterFactory::setProcessIdToBooster(char type, pid_t pid)
{
WRTBooster::setProcessId(pid);
}
else if (type == MonitorBooster::type())
{
MonitorBooster::setProcessId(pid);
}
}
char BoosterFactory::getBoosterTypeForPid(pid_t pid)
@ -85,10 +76,6 @@ char BoosterFactory::getBoosterTypeForPid(pid_t pid)
{
return WRTBooster::type();
}
else if (pid == MonitorBooster::processId())
{
return MonitorBooster::type();
}
else
{
return 0;
@ -111,7 +98,6 @@ pid_t BoosterFactory::getBoosterPidForType(char type)
}
else
{
// not used for MonitorBooster
return 0;
}
}

@ -24,7 +24,6 @@
#include "mbooster.h"
#include "qtbooster.h"
#include "wrtbooster.h"
#include "monitorbooster.h"
#include "boosterfactory.h"
#include <cstdlib>
@ -148,7 +147,6 @@ void Daemon::run()
forkBooster(MBooster::type());
forkBooster(QtBooster::type());
forkBooster(WRTBooster::type());
forkBooster(MonitorBooster::type());
// Main loop
while (true)
@ -160,58 +158,45 @@ void Daemon::run()
ssize_t count = read(m_pipefd[0], reinterpret_cast<void *>(&msg), 1);
if (count)
{
// Read and store the pid of invoker if the message was not from
// a monitor booster it won't send the pid.
if (msg != MonitorBooster::type())
{
// Read pid of peer invoker
pid_t invokerPid;
count = read(m_pipefd[0], reinterpret_cast<void *>(&invokerPid), sizeof(pid_t));
// Read pid of peer invoker
pid_t invokerPid;
count = read(m_pipefd[0], reinterpret_cast<void *>(&invokerPid), sizeof(pid_t));
if (count < static_cast<ssize_t>(sizeof(pid_t)))
{
Logger::logErrorAndDie(EXIT_FAILURE, "Daemon: pipe connection with booster failed");
}
else
{
Logger::logInfo("Daemon: invoker's pid: %d \n", invokerPid);
}
if (invokerPid != 0)
{
// Store booster - invoker pid pair
m_boosterPidToInvokerPid[BoosterFactory::getBoosterPidForType(msg)] = invokerPid;
}
// Read booster respawn delay
int delay;
count = read(m_pipefd[0], reinterpret_cast<void *>(&delay), sizeof(int));
if (count < static_cast<ssize_t>(sizeof(int)))
{
Logger::logErrorAndDie(EXIT_FAILURE, "Daemon: pipe connection with booster failed");
}
else
{
Logger::logInfo("Daemon: respawn delay: %d \n", delay);
}
if (count < static_cast<ssize_t>(sizeof(pid_t)))
{
Logger::logErrorAndDie(EXIT_FAILURE, "Daemon: pipe connection with booster failed");
}
else
{
Logger::logInfo("Daemon: invoker's pid: %d \n", invokerPid);
}
// Fork a new booster of the given type
if (invokerPid != 0)
{
// Store booster - invoker pid pair
m_boosterPidToInvokerPid[BoosterFactory::getBoosterPidForType(msg)] = invokerPid;
}
// 2nd param guarantees some time for the just launched application
// to start up before forking new booster. Not doing this would
// slow down the start-up significantly on single core CPUs.
// Read booster respawn delay
int delay;
count = read(m_pipefd[0], reinterpret_cast<void *>(&delay), sizeof(int));
forkBooster(msg, delay);
if (count < static_cast<ssize_t>(sizeof(int)))
{
Logger::logErrorAndDie(EXIT_FAILURE, "Daemon: pipe connection with booster failed");
}
// It was from a monitor booster, that means that theme / language has
// changed so we need to reset (kill) MBooster and WRTBooster.
else
{
// Kill MBooster and WRTBooster
killProcess(BoosterFactory::getBoosterPidForType(MBooster::type()));
killProcess(BoosterFactory::getBoosterPidForType(WRTBooster::type()));
Logger::logInfo("Daemon: respawn delay: %d \n", delay);
}
// Fork a new booster of the given type
// 2nd param guarantees some time for the just launched application
// to start up before forking new booster. Not doing this would
// slow down the start-up significantly on single core CPUs.
forkBooster(msg, delay);
}
else
{

@ -35,7 +35,7 @@ int MBooster::m_ProcessID = 0;
int MBooster::m_sighupFd[2];
struct sigaction MBooster::m_oldSigAction;
MBooster::MBooster()
MBooster::MBooster() : m_item(0)
{
// Install signals handler e.g. to exit cleanly if launcher dies.
// This is a problem because MBooster runs a Qt event loop.
@ -149,12 +149,22 @@ bool MBooster::readCommand()
// exit from event loop when invoker is ready to connect
connect(this, SIGNAL(connectionAccepted()), MApplication::instance() , SLOT(quit()));
// enable theme change handler
m_item = new MGConfItem(MEEGOTOUCH_THEME_GCONF_KEY, 0);
connect(m_item, SIGNAL(valueChanged()), this, SLOT(notifyThemeChange()));
// start another thread to listen connection from invoker
QtConcurrent::run(this, &MBooster::accept);
// Run event loop so MApplication and MApplicationWindow objects can receive notifications
MApplication::exec();
// disable theme change handler
disconnect(m_item, 0, this, 0);
delete m_item;
m_item = NULL;
// Restore signal handlers to previous values
restoreUnixSignalHandlers();
@ -174,6 +184,13 @@ bool MBooster::readCommand()
return true;
}
void MBooster::notifyThemeChange()
{
MApplication::quit();
::_exit(EXIT_SUCCESS);
}
void MBooster::accept()
{
if (m_conn->accept(m_app))

@ -23,6 +23,7 @@
#include "booster.h"
#include <QObject>
#include <QSocketNotifier>
#include <MGConfItem>
#include <tr1/memory>
using std::tr1::shared_ptr;
@ -118,6 +119,7 @@ private:
//! yet transformed into a running application
static const string m_temporaryProcessName;
//! wait for socket connection
void accept();
//! Socket pair used to get SIGHUP
@ -129,11 +131,18 @@ private:
//! Old sigaction struct
static struct sigaction m_oldSigAction;
//! GConf item to listen theme change
MGConfItem* m_item;
private slots:
//! Qt signal handler for SIGHUP.
void handleSigHup();
//! Qt signal handler for theme change
void notifyThemeChange();
signals:
void connectionAccepted();

@ -1,116 +0,0 @@
/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (directui@nokia.com)
**
** This file is part of applauncherd
**
** If you have questions regarding the use of this file, please contact
** Nokia at directui@nokia.com.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/
#include <QCoreApplication>
#include <QObject>
#include <cstdlib>
#include "monitorbooster.h"
#include "mbooster.h"
#include "wrtbooster.h"
#include "logger.h"
const string MonitorBooster::m_socketId = "";
int MonitorBooster::m_ProcessID = 0;
const string MonitorBooster::m_temporaryProcessName = "booster-monitor";
MonitorBooster::MonitorBooster()
{
// Add keys to listen to.
addKey(MEEGOTOUCH_THEME_GCONF_KEY);
addKey(MEEGOTOUCH_LANGUAGE_GCONF_KEY);
}
void MonitorBooster::addKey(const QString & key)
{
MGConfItem * item = new MGConfItem(key, 0);
m_gConfItems << QSharedPointer<MGConfItem>(item);
QObject::connect(item, SIGNAL(valueChanged()),
this, SLOT(notifyKeyChange()));
}
void MonitorBooster::run()
{
int argc = 0;
QCoreApplication(argc, 0).exec();
}
void MonitorBooster::initialize(int initialArgc, char ** initialArgv, int newPipeFd[2])
{
setPipeFd(newPipeFd);
// Clean-up all the env variables
clearenv();
// Rename process to temporary booster process name
renameProcess(initialArgc, initialArgv);
}
void MonitorBooster::notifyKeyChange()
{
// Signal the parent process that it can create a new
// waiting booster process and close write end
const char msg = boosterType();
ssize_t ret = write(pipeFd(1), reinterpret_cast<const void *>(&msg), 1);
if (ret == -1) {
Logger::logError("MonitorBooster: Couldn't send type message to launcher process\n");
}
}
char MonitorBooster::type()
{
return 'k';
}
const string & MonitorBooster::socketName()
{
return m_socketId;
}
const string & MonitorBooster::socketId() const
{
return m_socketId;
}
void MonitorBooster::setProcessId(int pid)
{
m_ProcessID = pid;
}
int MonitorBooster::processId()
{
return m_ProcessID;
}
const string & MonitorBooster::temporaryProcessName()
{
return m_temporaryProcessName;
}
const string & MonitorBooster::boosterTemporaryProcessName() const
{
return temporaryProcessName();
}
char MonitorBooster::boosterType() const
{
return type();
}

@ -1,107 +0,0 @@
/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (directui@nokia.com)
**
** This file is part of applauncherd
**
** If you have questions regarding the use of this file, please contact
** Nokia at directui@nokia.com.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/
#ifndef MONITORBOOSTER_H
#define MONITORBOOSTER_H
#include <QObject>
#include <QSharedPointer>
#include <MGConfItem>
#include "booster.h"
class QString;
/*! \class MonitorBooster
*
* MonitorBooster kills certain boosters e.g. when themeing or language changes.
* Daemon will then restart the boosters.
*/
class MonitorBooster : public QObject, public Booster
{
Q_OBJECT
public:
//! Constructor.
MonitorBooster();
/*!
* \brief Return the empty strung (not used in MonitorBooster).
* \return empty string.
*/
static const string & socketName();
//! Add a GConf key to trigger booster process termination
void addKey(const QString & key);
/*! Starts the killer. This will initialize a QCoreApplication, does
* not return. reimp.
*/
virtual void run();
//! \reimp
virtual char boosterType() const;
//! \reimp
virtual void initialize(int initialArgc, char ** initialArgv, int pipeFd[2]);
/*!
* \brief Return a unique character ('k') represtenting the type of MonitorBooster.
* \return Type character.
*/
static char type();
/*!
* \brief Keep booster pid, should be reset before booster run application's main() function
*/
static void setProcessId(int pid);
/*!
* \brief Return booster pid
*/
static int processId();
//! Return the artificial process name
static const string & temporaryProcessName();
//! \reimp
virtual const string & boosterTemporaryProcessName() const;
protected:
//! \reimp
virtual const string & socketId() const;
private Q_SLOTS:
//! Send message to main process that something has changed
void notifyKeyChange();
private:
static const string m_socketId;
static int m_ProcessID;
//! Process name to be used for booster
static const string m_temporaryProcessName;
QList<QSharedPointer<MGConfItem> > m_gConfItems;
};
#endif // MONITORBOOSTER_H

@ -19,6 +19,12 @@
#include "wrtbooster.h"
#include "logger.h"
#include "connection.h"
#include <QtConcurrentRun>
#include <MApplication>
#include <sys/socket.h>
#ifdef HAVE_MCOMPONENTCACHE
#include <mcomponentcache.h>
@ -31,6 +37,69 @@
const string WRTBooster::m_socketId = "/tmp/boostw";
const string WRTBooster::m_temporaryProcessName = "booster-w";
int WRTBooster::m_ProcessID = 0;
int WRTBooster::m_sighupFd[2];
struct sigaction WRTBooster::m_oldSigAction;
WRTBooster::WRTBooster() : m_item(0)
{
// Install signals handler e.g. to exit cleanly if launcher dies.
// This is a problem because WRTBooster runs a Qt event loop.
setupUnixSignalHandlers();
// Create socket pair for SIGTERM
if (::socketpair(AF_UNIX, SOCK_STREAM, 0, m_sighupFd))
{
Logger::logError("Couldn't create HUP socketpair");
}
else
{
// Install a socket notifier on the socket
m_snHup.reset(new QSocketNotifier(m_sighupFd[1], QSocketNotifier::Read, this));
connect(m_snHup.get(), SIGNAL(activated(int)), this, SLOT(handleSigHup()));
}
}
//
// All this signal handling code is taken from Qt's Best Practices:
// http://doc.qt.nokia.com/latest/unix-signals.html
//
void WRTBooster::hupSignalHandler(int)
{
char a = 1;
::write(m_sighupFd[0], &a, sizeof(a));
}
void WRTBooster::handleSigHup()
{
::_exit(EXIT_SUCCESS);
}
bool WRTBooster::setupUnixSignalHandlers()
{
struct sigaction hup;
hup.sa_handler = WRTBooster::hupSignalHandler;
sigemptyset(&hup.sa_mask);
hup.sa_flags |= SA_RESTART;
if (sigaction(SIGHUP, &hup, &m_oldSigAction) > 0)
{
return false;
}
return true;
}
bool WRTBooster::restoreUnixSignalHandlers()
{
if (sigaction(SIGHUP, &m_oldSigAction, 0) > 0)
{
return false;
}
return true;
}
const string & WRTBooster::socketId() const
{
@ -78,3 +147,61 @@ int WRTBooster::processId()
{
return m_ProcessID;
}
bool WRTBooster::readCommand()
{
// Setup the conversation channel with the invoker.
m_conn = new Connection(socketId());
// exit from event loop when invoker is ready to connect
connect(this, SIGNAL(connectionAccepted()), MApplication::instance() , SLOT(quit()));
// enable theme change handler
m_item = new MGConfItem(MEEGOTOUCH_THEME_GCONF_KEY, 0);
connect(m_item, SIGNAL(valueChanged()), this, SLOT(notifyThemeChange()));
// start another thread to listen connection from invoker
QtConcurrent::run(this, &WRTBooster::accept);
// Run event loop so MApplication and MApplicationWindow objects can receive notifications
MApplication::exec();
// disable theme change handler
disconnect(m_item, 0, this, 0);
delete m_item;
m_item = NULL;
// Restore signal handlers to previous values
restoreUnixSignalHandlers();
// Receive application data from the invoker
if(!m_conn->receiveApplicationData(m_app))
{
m_conn->close();
return false;
}
// Close the connection if exit status doesn't need
// to be sent back to invoker
if (!m_conn->isReportAppExitStatusNeeded())
{
m_conn->close();
}
return true;
}
void WRTBooster::notifyThemeChange()
{
MApplication::quit();
::_exit(EXIT_SUCCESS);
}
void WRTBooster::accept()
{
if (m_conn->accept(m_app))
{
emit connectionAccepted();
}
}

@ -21,6 +21,14 @@
#define WRTBOOSTER_H
#include "booster.h"
#include <MGConfItem>
#include <QObject>
#include <QSocketNotifier>
#include <tr1/memory>
using std::tr1::shared_ptr;
#include <signal.h>
/*!
\class WRTBooster
@ -30,12 +38,14 @@
similarly to MBooster. However, the cache content is optimized for
web runtime's use.
*/
class WRTBooster : public Booster
class WRTBooster : public QObject, public Booster
{
Q_OBJECT
public:
//! \brief Constructor
WRTBooster() {};
WRTBooster();
//! \brief Destructor
virtual ~WRTBooster() {};
@ -75,11 +85,25 @@ public:
*/
static int processId();
//! UNIX signal handler for SIGHUP
static void hupSignalHandler(int unused);
//! Setup UNIX signal handlers
static bool setupUnixSignalHandlers();
//! Restore UNIX signal handlers to previous values
static bool restoreUnixSignalHandlers();
protected:
//! \reimp
virtual const string & socketId() const;
//! \reimp
virtual bool readCommand();
private:
//! Disable copy-constructor
@ -96,6 +120,35 @@ private:
//! yet transformed into a running application
static const string m_temporaryProcessName;
//! wait for socket connection
void accept();
//! Socket pair used to get SIGHUP
static int m_sighupFd[2];
//! Socket notifier used for m_sighupFd
shared_ptr<QSocketNotifier> m_snHup;
//! Old sigaction struct
static struct sigaction m_oldSigAction;
//! GConf item to listen theme change
MGConfItem* m_item;
private slots:
//! Qt signal handler for SIGHUP.
void handleSigHup();
//! Qt signal handler for theme change
void notifyThemeChange();
signals:
void connectionAccepted();
#ifdef UNIT_TEST
friend class Ut_WRTBooster;
#endif

@ -46,6 +46,9 @@ add_subdirectory(Common/TestApps/themetest)
# Sub build: Common/TestApps/fala_gettime
add_subdirectory(Common/TestApps/fala_gettime)
# Sub build: Common/TestApps/fala_gettime_ms
add_subdirectory(Common/TestApps/fala_gettime_ms)
# Sub build: Common/TestApps/helloworld
add_subdirectory(Common/TestApps/helloworld)

@ -0,0 +1,13 @@
# Set sources
set(SRC fala_gettime_ms.cpp)
set(CMAKE_CXX_FLAGS "-O3")
# Link statically to minimize startup time.
set(CMAKE_EXE_LINKER_FLAGS "-static")
add_executable(fala_gettime_ms ${SRC})
# Install
install(PROGRAMS fala_gettime_ms DESTINATION /usr/bin/)

@ -0,0 +1,18 @@
#include <sys/time.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv) {
timeval tim;
gettimeofday(&tim, NULL);
if (argc > 0) {
printf("%d%03d %s\n",
static_cast<int>(tim.tv_sec), static_cast<int>(tim.tv_usec/1000), argv[1]);
} else {
printf("%d%03d\n",
static_cast<int>(tim.tv_sec), static_cast<int>(tim.tv_usec/1000));
}
return true;
}

@ -1,10 +1,10 @@
set(LAUNCHER ${CMAKE_HOME_DIRECTORY}/src/launcherlib)
# Set sources
set(SRC ut_boosterfactory.cpp ${LAUNCHER}/appdata.cpp ${LAUNCHER}/booster.cpp ${LAUNCHER}/mbooster.cpp ${LAUNCHER}/qtbooster.cpp ${LAUNCHER}/monitorbooster.cpp ${LAUNCHER}/wrtbooster.cpp ${LAUNCHER}/boosterfactory.cpp ${LAUNCHER}/connection.cpp ${LAUNCHER}/logger.cpp)
set(SRC ut_boosterfactory.cpp ${LAUNCHER}/appdata.cpp ${LAUNCHER}/booster.cpp ${LAUNCHER}/mbooster.cpp ${LAUNCHER}/qtbooster.cpp ${LAUNCHER}/wrtbooster.cpp ${LAUNCHER}/boosterfactory.cpp ${LAUNCHER}/connection.cpp ${LAUNCHER}/logger.cpp)
# Set moc headers
set(MOC_HDRS ut_boosterfactory.h ${LAUNCHER}/monitorbooster.h ${LAUNCHER}/mbooster.h)
set(MOC_HDRS ut_boosterfactory.h ${LAUNCHER}/mbooster.h ${LAUNCHER}/wrtbooster.h)
# Run moc
qt4_wrap_cpp(MOC_SRC ${MOC_HDRS})

@ -23,7 +23,6 @@
#include "mbooster.h"
#include "qtbooster.h"
#include "wrtbooster.h"
#include "monitorbooster.h"
void Ut_BoosterFactory::initTestCase()
{}
@ -45,14 +44,10 @@ void Ut_BoosterFactory::testCreate()
QVERIFY(dynamic_cast<WRTBooster *>(booster));
delete booster;
booster = BoosterFactory::create('k');
QVERIFY(dynamic_cast<MonitorBooster *>(booster));
delete booster;
for (int i = 0; i < 256; i++)
{
unsigned char t = static_cast<unsigned char>(i);
if (t != 'q' && t != 'm' && t != 'w' && t != 'k')
if (t != 'q' && t != 'm' && t != 'w')
{
QVERIFY(!BoosterFactory::create(t));
}
@ -76,19 +71,17 @@ void Ut_BoosterFactory::testGetBoosterTypeForPid()
BoosterFactory::setProcessIdToBooster('q', 1);
BoosterFactory::setProcessIdToBooster('m', 2);
BoosterFactory::setProcessIdToBooster('w', 3);
BoosterFactory::setProcessIdToBooster('k', 4);
QVERIFY(BoosterFactory::getBoosterTypeForPid(1) == 'q');
QVERIFY(BoosterFactory::getBoosterTypeForPid(2) == 'm');
QVERIFY(BoosterFactory::getBoosterTypeForPid(3) == 'w');
QVERIFY(BoosterFactory::getBoosterTypeForPid(4) == 'k');
QVERIFY(BoosterFactory::getBoosterTypeForPid(0) == 0);
for (int i = 0; i < 256; i++)
{
unsigned char t = static_cast<unsigned char>(i);
if (t != 'q' && t != 'm' && t != 'w' && t != 'k')
if (t != 'q' && t != 'm' && t != 'w')
{
BoosterFactory::setProcessIdToBooster(t, 1000);
QVERIFY(BoosterFactory::getBoosterTypeForPid(1000) == 0);
@ -101,17 +94,15 @@ void Ut_BoosterFactory::testGetBoosterPidForType()
BoosterFactory::setProcessIdToBooster('q', 145);
BoosterFactory::setProcessIdToBooster('m', 245);
BoosterFactory::setProcessIdToBooster('w', 345);
BoosterFactory::setProcessIdToBooster('k', 445);
QVERIFY(BoosterFactory::getBoosterPidForType('q') == 145);
QVERIFY(BoosterFactory::getBoosterPidForType('m') == 245);
QVERIFY(BoosterFactory::getBoosterPidForType('w') == 345);
QVERIFY(BoosterFactory::getBoosterPidForType('k') == 0); // shouldn't be used!!!
for (int i = 0; i < 256; i++)
{
unsigned char t = static_cast<unsigned char>(i);
if (t != 'q' && t != 'm' && t != 'w' && t != 'k')
if (t != 'q' && t != 'm' && t != 'w')
{
QVERIFY(BoosterFactory::getBoosterPidForType(t) == 0);
}

@ -1,10 +1,10 @@
set(LAUNCHER ${CMAKE_HOME_DIRECTORY}/src/launcherlib)
# Set sources
set(SRC ut_connection.cpp ${LAUNCHER}/appdata.cpp ${LAUNCHER}/booster.cpp ${LAUNCHER}/boosterfactory.cpp ${LAUNCHER}/monitorbooster.cpp ${LAUNCHER}/daemon.cpp ${LAUNCHER}/connection.cpp ${LAUNCHER}/logger.cpp ${LAUNCHER}/mbooster.cpp ${LAUNCHER}/qtbooster.cpp ${LAUNCHER}/wrtbooster.cpp)
set(SRC ut_connection.cpp ${LAUNCHER}/appdata.cpp ${LAUNCHER}/booster.cpp ${LAUNCHER}/boosterfactory.cpp ${LAUNCHER}/daemon.cpp ${LAUNCHER}/connection.cpp ${LAUNCHER}/logger.cpp ${LAUNCHER}/mbooster.cpp ${LAUNCHER}/qtbooster.cpp ${LAUNCHER}/wrtbooster.cpp)
# Set moc headers
set(MOC_HDRS ut_connection.h ${LAUNCHER}/monitorbooster.h ${LAUNCHER}/mbooster.h)
set(MOC_HDRS ut_connection.h ${LAUNCHER}/mbooster.h ${LAUNCHER}/wrtbooster.h)
# Set the program name define used in daemon.cpp
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DPROG_NAME_LAUNCHER=\\\"applauncherd\\\"")

@ -1,9 +1,9 @@
# Set sources
set(LAUNCHER ${CMAKE_HOME_DIRECTORY}/src/launcherlib)
set(SRC ut_daemon.cpp ${LAUNCHER}/appdata.cpp ${LAUNCHER}/booster.cpp ${LAUNCHER}/boosterfactory.cpp ${LAUNCHER}/monitorbooster.cpp ${LAUNCHER}/daemon.cpp ${LAUNCHER}/connection.cpp ${LAUNCHER}/logger.cpp ${LAUNCHER}/mbooster.cpp ${LAUNCHER}/qtbooster.cpp ${LAUNCHER}/wrtbooster.cpp)
set(SRC ut_daemon.cpp ${LAUNCHER}/appdata.cpp ${LAUNCHER}/booster.cpp ${LAUNCHER}/boosterfactory.cpp ${LAUNCHER}/daemon.cpp ${LAUNCHER}/connection.cpp ${LAUNCHER}/logger.cpp ${LAUNCHER}/mbooster.cpp ${LAUNCHER}/qtbooster.cpp ${LAUNCHER}/wrtbooster.cpp)
# Set moc headers
set(MOC_HDRS ut_daemon.h ${LAUNCHER}/monitorbooster.h ${LAUNCHER}/mbooster.h)
set(MOC_HDRS ut_daemon.h ${LAUNCHER}/mbooster.h ${LAUNCHER}/wrtbooster.h)
# Set the program name define used in daemon.cpp
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DPROG_NAME_LAUNCHER=\\\"applauncherd\\\"")

@ -5,7 +5,7 @@ set(SRC ut_wrtbooster.cpp ${LAUNCHER}/appdata.cpp ${LAUNCHER}/booster.cpp ${LAUN
${LAUNCHER}/logger.cpp ${LAUNCHER}/wrtbooster.cpp)
# Set moc headers
set(MOC_HDRS ut_wrtbooster.h)
set(MOC_HDRS ut_wrtbooster.h ${LAUNCHER}/wrtbooster.h)
# Run moc
qt4_wrap_cpp(MOC_SRC ${MOC_HDRS})

@ -9,6 +9,7 @@ install(FILES
install(PROGRAMS
ts_prestartapp.rb
tc_theming.rb
get-coordinates.rb
test-perf.rb
fala_wid
fala_xres_wl

@ -0,0 +1,106 @@
#!/usr/bin/ruby
# Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
# All rights reserved.
# Contact: Nokia Corporation (directui@nokia.com)
#
# This file is part of applauncherd.
#
# If you have questions regarding the use of this file, please contact
# Nokia at directui@nokia.com.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License version 2.1 as published by the Free Software Foundation
# and appearing in the file LICENSE.LGPL included in the packaging
# of this file.
#
# * Description: Performance Test for applauncherd
#
# * Objectives: test the startup time for applications
#
require 'tdriver'
require 'date'
require 'optparse'
include TDriverVerify
options = {}
optparse = OptionParser.new do|opts|
# Set a banner, displayed at the top
# of the help screen.
opts.banner = "Usage: get-coordinates.rb [options] "
options[:application] = nil
opts.on( '-a', '--application APP', 'Application name in application grid' ) do|app|
options[:application] = app
end
options[:grid] = false
opts.on( '-g', '--grid_only', 'Only make application grid visible, not find any coordinates ' ) do
options[:grid] = true
end
# This displays the help screen, all programs are
# assumed to have this option.
opts.on( '-h', '--help', 'Display this screen' ) do
puts opts
exit 0
end
end
optparse.parse!
if options[:application] == nil && !(options[:grid])
puts "Application name not defined!"
exit 1
end
pos = 0
appName=options[:application]
sut = TDriver.sut(:Id=> 'sut_qt_maemo')
appOnTop = sut.application()
while appOnTop.attribute('objectName') != 'meegotouchhome'
fullName = appOnTop.attribute('FullName')
# puts "Now killing #{fullName} from the top"
system "pkill #{fullName}"
appOnTop = sut.application()
end
# Application grid should be now visible
if options[:grid]
exit 0;
end
@meegoHome = sut.application(:name => 'meegotouchhome')
sleep(2)
if @meegoHome.test_object_exists?("LauncherButton", :text => appName)
icon = @meegoHome.LauncherButton(:name => "LauncherButton", :text => appName)
while icon.attribute('visibleOnScreen') == 'false' || @meegoHome.LauncherButton(:name => "LauncherButton", :text => appName).attribute('y').to_i > 400
@meegoHome.Launcher.MPannableViewport( :name => 'SwipePage' ).MWidget( :name => 'glass' ).gesture(:Up, 1, 300)
sleep(0.2)
icon.refresh
end
xpos = @meegoHome.LauncherButton(:name => "LauncherButton", :text => appName).attribute('x')
ypos = @meegoHome.LauncherButton(:name => "LauncherButton", :text => appName).attribute('y')
@pos = "#{xpos}x#{ypos}"
print @pos
exit 0
else
#icon does not
#raise error and exit
raise "Application not found in Application grid"
exit 1
end

@ -19,161 +19,185 @@
# * Objectives: test the startup time for applications
#
require 'tdriver'
#require 'tdriver'
require 'date'
require 'test/unit'
include TDriverVerify
require 'optparse'
class TC_PerformanceTests < Test::Unit::TestCase
COUNT = 3
APP_WITH_LAUNCHER = 'fala_wl'
APP_WITHOUT_LAUNCHER = 'fala_wol'
PIXELCHANGED_BINARY= '/usr/bin/fala_pixelchanged'
TEST_SCRIPT_LOCATION = '/usr/share/applauncherd-testscripts'
PIXELCHANGED_LOG = '/tmp/fala_pixelchanged.log'
@start_time = 0
@end_time = 0
@pos = 0
$path = string = `echo $PATH `
# method called before any test case
def setup
COUNT = 3
PIXELCHANGED_BINARY= '/usr/bin/fala_pixelchanged'
TEST_SCRIPT_LOCATION = '/usr/share/applauncherd-testscripts'
GET_COORDINATES_SCRIPT="#{TEST_SCRIPT_LOCATION}/get-coordinates.rb"
PIXELCHANGED_LOG = '/tmp/fala_pixelchanged.log'
FALA_GETTIME_BINARY = '/usr/bin/fala_gettime_ms'
@start_time = 0
@end_time = 0
@pos = 0
@options = {}
@sut = TDriver.sut(:Id=> 'sut_qt_maemo')
if $path.include?("scratchbox")
puts "Inside SB, Do Nothing to unlock"
else
system "mcetool --set-tklock-mode=unlocked"
$path = string = `echo $PATH `
# method called before any test case
def setup
optparse = OptionParser.new do|opts|
options = {}
# Set a banner, displayed at the top
# of the help screen.
opts.banner = "Usage: get-coordinates.rb [options] "
options[:application] = nil
opts.on( '-a', '--application APP', 'Application name in application grid' ) do|app|
options[:application] = app
end
# restart duihome so that qttasserver notices it
# NOTE: Remove the cludge after duihome -> meegotouchhome renaming is complete
if not system("/sbin/initctl restart xsession/duihome")
system("/sbin/initctl restart xsession/mthome")
end
options[:command] = nil
opts.on( '-c', '--command_line COMMAND', 'Start application from witc COMMAND from command line instead of grid.' ) do|command|
options[:command] = command
end
system("initctl stop xsession/sysuid")
system("initctl stop xsession/applifed")
options[:limit] = nil
opts.on( '-l', '--limit MILLISECONDS', 'Time limit in milliseconds. Slower startup will make test to fail.' ) do|milliseconds|
options[:limit] = milliseconds.to_i
end
opts.on( '-h', '--help', 'Display this screen' ) do
puts opts
exit 0
end
@options=options
end
end
optparse.parse!
if @options[:application] == nil && @options[:command] == nil
puts "Application not defined!"
exit 1
end
# method called after any test case for cleanup purposes
def teardown
puts "exit from teardown"
system("initctl start xsession/sysuid")
system("initctl start xsession/applifed")
if @options[:command] != nil
puts "#{@options[:command]}"
end
def open_Apps(appName)
#Remove the Log file if it exists
if FileTest.exists?(PIXELCHANGED_LOG)
system "rm #{PIXELCHANGED_LOG}"
end
appOnTop = @sut.application()
while appOnTop.attribute('objectName') != 'meegotouchhome'
fullName = appOnTop.attribute('FullName')
puts "Now killing #{fullName} from the top"
system "pkill #{fullName}"
appOnTop = @sut.application()
end
#Open the Application from the application grid
begin
@meegoHome = @sut.application(:name => 'duihome')
rescue MobyBase::TestObjectNotFoundError
@meegoHome = @sut.application(:name => 'meegotouchhome')
end
sleep(2)
if @meegoHome.test_object_exists?("LauncherButton", :text => appName)
icon = @meegoHome.LauncherButton(:name => "LauncherButton", :text => appName)
while icon.attribute('visibleOnScreen') == 'false'
@meegoHome.Launcher.MPannableViewport( :name => 'SwipePage' ).MWidget( :name => 'glass' ).gesture(:Up, 1, 300)
sleep(0.2)
icon.refresh
end
xpos = @meegoHome.LauncherButton(:name => "LauncherButton", :text => appName).attribute('x')
ypos = @meegoHome.LauncherButton(:name => "LauncherButton", :text => appName).attribute('y')
@pos = "#{xpos}x#{ypos}"
puts @pos
sleep (2)
system "#{PIXELCHANGED_BINARY} -c #{@pos} -f #{PIXELCHANGED_LOG} -q"
sleep (4)
system "pkill #{appName}"
else
#icon does not
#raise error and exit
raise "Application not found in Application grid"
exit 1
end
if $path.include?("scratchbox")
puts "Inside SB, Do Nothing to unlock"
else
system "mcetool --set-tklock-mode=unlocked"
end
#restart duihome so that qttasserver notices it
#NOTE: Remove the cludge after duihome -> meegotouchhome renaming is complete
if not system("/sbin/initctl restart xsession/duihome")
system("/sbin/initctl restart xsession/mthome")
end
def read_file(appName)
#Reading the log file to get the time
lines = File.open(PIXELCHANGED_LOG).readlines().collect { |x| x.split(" ")[0].to_i }
system("initctl stop xsession/sysuid")
system("initctl stop xsession/applifed")
system("initctl stop xsession/search")
system("mv /usr/lib/qt4/plugins/testability/libtestability.so /tmp/.")
# system("pkill call-history")
sleep(4)
end
# First line tells when the button is released
@start_time = lines[0]
puts "Line1: #{lines[0]}"
# Second one when the first pixel has changed its color
@end_time = lines[1]
puts "Line2: #{lines[1]}"
# method called after any test case for cleanup purposes
def teardown
puts "exit from teardown"
system("initctl start xsession/sysuid")
system("initctl start xsession/applifed")
system("initctl start xsession/search")
system("mv /tmp/libtestability.so /usr/lib/qt4/plugins/testability/libtestability.so")
end
def open_Apps(appName)
#Remove the Log file if it exists
if FileTest.exists?(PIXELCHANGED_LOG)
system "rm #{PIXELCHANGED_LOG}"
end
def measure_time
#Measuring the Startup Time for applications
app_t = @end_time - @start_time
return app_t
sleep(2)
if @options[:command] != nil
puts "#{GET_COORDINATES_SCRIPT} -g"
system "#{GET_COORDINATES_SCRIPT} -g"
# system "ls -l -s -R /usr/share/applications"
start_command ="`#{PIXELCHANGED_BINARY} -q >> #{PIXELCHANGED_LOG} &`; #{FALA_GETTIME_BINARY} \"Started from command line\" >> #{PIXELCHANGED_LOG}; #{@options[:command]} &"
puts "start command: #{start_command}"
system "#{start_command}"
sleep (4)
puts "pkill \"#{@options[:command]}\""
system "pkill \"#{@options[:command]}\""
else
@pos = `#{GET_COORDINATES_SCRIPT} -a #{@options[:application]}`
puts @pos
sleep (2)
system "#{PIXELCHANGED_BINARY} -c #{@pos} -f #{PIXELCHANGED_LOG} -q"
sleep (4)
system "pkill #{appName}"
end
def test_performance
wL = []
woL = []
wLsum = 0
woLsum = 0
#Run Application with invoker
for i in 1..COUNT
print "Now Launching #{APP_WITH_LAUNCHER} %d times\n" %i
open_Apps(APP_WITH_LAUNCHER)
sleep (5)
read_file(APP_WITH_LAUNCHER)
wL.push(measure_time)
end
#Run Application without invoker
for i in 1..COUNT
print "Now Launching #{APP_WITHOUT_LAUNCHER} %d times\n" %i
open_Apps(APP_WITHOUT_LAUNCHER)
sleep (5)
read_file(APP_WITHOUT_LAUNCHER)
woL.push(measure_time)
end
print "Startup time in milliseconds\n"
print "With Launcher \t\t Without Launcher\n"
#Printing the data
for i in 0..COUNT-1
print "%d \t\t\t %d\n" %[wL[i],woL[i]]
wLsum = wLsum + wL[i]
woLsum = woLsum + woL[i]
end
print "\nAverage Values \n"
print "%d \t\t\t %d\n\n" %[wLsum/COUNT, woLsum/COUNT]
end
def read_file(appName)
#Reading the log file to get the time
lines = File.open(PIXELCHANGED_LOG).readlines().collect { |x| x.split(" ")[0].to_i }
# First line tells when the button is released
@start_time = lines[0]
puts "Clicked: #{lines[0]}"
# Second one when the first pixel has changed its color
@end_time = lines[1]
puts "Pixel changed: #{lines[1]}"
end
def measure_time
#Measuring the Startup Time for applications
app_t = @end_time - @start_time
return app_t
end
def test_performance
wL = []
wLsum = 0
#Run Application with invoker
for i in 1..COUNT
print "Now Launching #{@options[:application]} %d times\n" %i
open_Apps(@options[:application])
sleep (5)
read_file(@options[:application])
wL.push(measure_time)
end
print "\n\nStartup time in milliseconds\n"
print "Application: #{@options[:application]} \n"
if @options[:limit] != nil
print "Time limit: #{@options[:limit]} \n"
end
#Printing the data
for i in 0..COUNT-1
print "%d \n" %[wL[i]]
wLsum = wLsum + wL[i]
end
print "\nAverage: \n"
print "%d\n" %[wLsum/COUNT]
if @options[:limit] != nil
assert((wLsum/COUNT) < @options[:limit], "Application: #{@options[:application]} avarage startup was slower than #{@options[:limit]} ms")
end
end
end

@ -5,7 +5,7 @@
<!-- Schema: https://projects.maemo.org/docs/testing/xml-definition.html -->
<suite name="applauncherd-performance-tests" domain="Application framework">
<set name="test-commandline" description="applauncherd application startup time from command line" feature="AF DUI Booster for Launcher daemon" requirement="300195">
<set name="test-commandline" description="Applauncherd application startup time from command line with Python" feature="AF DUI Booster for Launcher daemon" requirement="300195">
<pre_steps>
<step>/usr/bin/waitloadavg.rb -l 1.0 -p 1.0 -t 120</step>
</pre_steps>
@ -24,13 +24,41 @@
</get>
</set>
<set name="test-applicationGrid" description="applauncherd application startup time from application grid" feature="AF DUI Booster for Launcher daemon" requirement="300195">
<set name="test-applicationGrid" description="Application startup time from application grid" feature="AF DUI Booster for Launcher daemon" requirement="300195">
<pre_steps>
<step>/usr/bin/waitloadavg.rb -l 1.0 -p 1.0 -t 120</step>
</pre_steps>
<case name="Perf-Test" type="Performance" description="Measure startup time of the application using launcher" timeout="360" level="System" insignificant="true">
<step expected_result="0">source /tmp/session_bus_address.user; DISPLAY=:0 /usr/share/applauncherd-testscripts/test-perf.rb name test_performance &gt; /tmp/launcher_perf_new.txt</step>
<case name="Perf-Test-Grid-launcher" type="Performance" description="Measure startup time of the application using launcher" timeout="360" level="System" insignificant="true">
<step expected_result="0">source /tmp/session_bus_address.user; DISPLAY=:0 /usr/share/applauncherd-testscripts/test-perf.rb name test_performance -- -a fala_wl &gt; /tmp/perf_grid_with_launcher.txt</step>
</case>
<case name="Perf-Test-Grid-plain" type="Performance" description="Measure startup time of the application without launcher" timeout="360" level="System" insignificant="true">
<step expected_result="0">source /tmp/session_bus_address.user; DISPLAY=:0 /usr/share/applauncherd-testscripts/test-perf.rb name test_performance -- -a fala_wol &gt; /tmp/perf_grid_without_launcher.txt</step>
</case>
<environments>
<scratchbox>false</scratchbox>
<hardware>true</hardware>
</environments>
<get>
<file>/tmp/perf_grid_with_launcher.txt</file>
<file>/tmp/perf_grid_without_launcher.txt</file>
</get>
</set>
<set name="test-command-line" description="Application startup time from command line" feature="AF DUI Booster for Launcher daemon" requirement="300195">
<pre_steps>
<step>/usr/bin/waitloadavg.rb -l 1.0 -p 1.0 -t 120</step>
</pre_steps>
<case name="Perf-Test-Command-launcher" type="Performance" description="Measure startup time of the application using launcher" timeout="360" level="System" insignificant="true">
<step expected_result="0">source /tmp/session_bus_address.user; DISPLAY=:0 /usr/share/applauncherd-testscripts/test-perf.rb name test_performance -- -c /usr/bin/fala_wl &gt; /tmp/perf_commandline_with_launcher.txt</step>
</case>
<case name="Perf-Test-Command-plain" type="Performance" description="Measure startup time of the application using launcher" timeout="360" level="System" insignificant="true">
<step expected_result="0">source /tmp/session_bus_address.user; DISPLAY=:0 /usr/share/applauncherd-testscripts/test-perf.rb name test_performance -- -c /usr/bin/fala_wol &gt; /tmp/perf_commandline_without_launcher.txt</step>
</case>
<environments>
<scratchbox>false</scratchbox>
@ -38,7 +66,8 @@
</environments>
<get>
<file>/tmp/launcher_perf_new.txt</file>
<file>/tmp/perf_commandline_with_launcher.txt</file>
<file>/tmp/perf_commandline_without_launcher.txt</file>
</get>
</set>

Loading…
Cancel
Save