activityfw/testapplications/nftapps/lowmemoryapp/basewidget.cpp
author Jaakko Haukipuro (Nokia-MS/Oulu) <Jaakko.Haukipuro@nokia.com>
Thu, 16 Sep 2010 12:11:40 +0100
changeset 117 c63ee96dbe5f
permissions -rw-r--r--
Missing activityfw and taskswitcher components - fix for Bug 3670

/*
* Copyright (c) 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 "basewidget.h"
#include <QRect>
#include <QPainter>
#include <QPainterPath>
#include <QPolygon>
#include <hbgridview.h>
#include <QStandardItemModel>
#include <HbScrollArea>
#include <QPalette>
#include <QImage>
#include <QColor>
#include <HbInstance>
#include <f32file.h>
#include <qglobal.h>

const int KDataDataSize = 2*1024*1024; // 2 MB
const int KThumbDataSize = 10; // 10 B
const int KMaxHeapMem = 16*1024*1024; // 16 MB


basewidget::basewidget(QObject* activityStorage, QObject* activityManager, QTextStream* stream, QGraphicsItem *parent)
    : HbWidget(parent), mActivityStorage(activityStorage), mActivityManager(activityManager), mStream(stream),
      mPixmap(NULL),mByteArray(NULL),
      mSaveVariant(NULL), mSaveMetadata(NULL),
      mAlloc(0)
{

    
    mSaveButton = new HbPushButton("Save");
    mThumbButton = new HbPushButton("Thumb");
    mDataButton = new HbPushButton("Data");
    
            
    mKBytesEdid = new HbLineEdit("1024");
    mKBytesEdid->setObjectName("KBytesEditLine");     
    mQKBytesValidator = new QIntValidator(this); 
    mQKBytesValidator->setRange(40, KMaxHeapMem);
    mKBytesValidator = new HbValidator(this);
    mKBytesValidator->addField(mQKBytesValidator, "3000");
    mKBytesEdid->setValidator(mKBytesValidator);

    
    mStatusValueLabel = new HbLabel("None status, none message");    
    mBytesEditLabel = new HbLabel("Free KBytes[KB]");
    mCatchLabel = new HbLabel("Catches");
        
    
    mGridLayout = new QGraphicsGridLayout();    
    mGridLayout->addItem(mStatusValueLabel, 0, 0, 1, 6);
    mGridLayout->addItem(mCatchLabel, 1, 0, 1, 6);
    mGridLayout->addItem(mBytesEditLabel, 2, 0, 1, 2);
    mGridLayout->addItem(mKBytesEdid, 2, 2, 1, 4);
    mGridLayout->addItem(mSaveButton, 3, 0, 1, 2);
    mGridLayout->addItem(mDataButton, 3, 2, 1, 2);
    mGridLayout->addItem(mThumbButton, 3, 4, 1, 2);            
    setLayout(mGridLayout);
        
    
    connect(mSaveButton, SIGNAL(released()), this, SLOT(save()));
    connect(mThumbButton, SIGNAL(released()), this, SLOT(thumb()));    
    connect(mDataButton, SIGNAL(released()), this, SLOT(data()));
}

basewidget::~basewidget()
{
    delete mQKBytesValidator;
    delete mKBytesValidator;
}




int basewidget::Bytes() const
{
   int kb = Edit2Int(mKBytesEdid);
   return kb*1024;
}

int basewidget::Edit2Int(const HbLineEdit* lineedit) const
{
    int retvalue = 0;
    bool ok = false;
    QString edittext = lineedit->text();
    retvalue = edittext.toInt(&ok);
    if(ok) {
        return retvalue;
    }
    return 0;
}

void basewidget::prepareDataSave()
{
    clearSaveData();
    int bytes = KDataDataSize;    
    mByteArray = new QByteArray(bytes, 'a');
    
    HbMainWindow *mainWindow = hbInstance->allMainWindows().first();
    mPixmap = new QPixmap(QPixmap::grabWidget(mainWindow, mainWindow->rect()));
    
    mSaveVariant = new QVariant;
    *mSaveVariant = *mByteArray;
    delete mByteArray;
    mByteArray = NULL;

    
    mSaveMetadata = new QVariantHash;
    mSaveMetadata->insert(ActivityScreenshotKeyword, *mPixmap);
    delete mPixmap;
    mPixmap = NULL;    
}

void basewidget::prepareThumbSave()
{
    clearSaveData();
    int bytes = KThumbDataSize;    
    mByteArray = new QByteArray(bytes, 'a');
    
    QImage img = QImage(1000, 1000, QImage::Format_ARGB32);
    img.fill(1);
    for( int i=0; i<img.width(); i++) {
        for(int j=0; j<img.height(); j++) {        
            int index = i*j;
            img.setPixel(i, j, qRgba((10*index+104*i)%255, (200*index+6*j)%255, (150*index+34*i)%255, (80*index+40*j)%255));
        }
    }
    mPixmap = new QPixmap(QPixmap::fromImage(img));
    bool ok = mPixmap->save("c:\\ala.bmp");
    
    mSaveVariant = new QVariant;
    *mSaveVariant = *mByteArray;
    delete mByteArray;
    mByteArray = NULL;

    
    mSaveMetadata = new QVariantHash;
    mSaveMetadata->insert(ActivityScreenshotKeyword, *mPixmap);
    delete mPixmap;
    mPixmap = NULL;       
}

void basewidget::clearSaveData()
{
    delete mByteArray;
    mByteArray = NULL;
    delete mPixmap;
    mPixmap = NULL;
    delete mSaveVariant;
    mSaveVariant = NULL;
    delete mSaveMetadata;
    mSaveMetadata = NULL;
}

bool basewidget::saveActivity(int name)
{
    QString display;
    display.setNum(name);
    mSaveMetadata->insert(ActivityApplicationName, display);
    bool retok, ok;
    try {
        ok = QMetaObject::invokeMethod(mActivityStorage, "saveActivity", Q_RETURN_ARG(bool, retok), Q_ARG(QString, display), Q_ARG(QVariant, *mSaveVariant), Q_ARG(QVariantHash, *mSaveMetadata));
    }
    catch(...) {
        logCatchError("save");
        return false;
    }

    return ok && retok;
}

bool basewidget::removeActivity(const QString& name)
{
    bool retok, ok;
    try {
        ok = QMetaObject::invokeMethod(mActivityStorage, "removeActivity", Q_RETURN_ARG(bool, retok), Q_ARG(QString, name));
    }
    catch(...) {
        logCatchError("remove");
        return false;
    }
    return ok && retok;
}

bool basewidget::activities()
{
    bool ok;
    try {
        ok = QMetaObject::invokeMethod(mActivityStorage, "allActivities", Q_RETURN_ARG(QStringList, mActivities));
    }
    catch(...) {
        logCatchError("activities");
        return false;
    }
    return ok;   
}   

bool basewidget::privateData(const QString& name)
{
    QVariant data;
    bool ok;
    try {
        ok = QMetaObject::invokeMethod(mActivityStorage, "activityData", Q_RETURN_ARG(QVariant, data), Q_ARG(QString, name));
    }
    catch(...) {
        logCatchError("data");
        return false;
    }
    const char* type = data.typeName();
    QString dtype(type);    
    logDataType(dtype);
    return ok;
}

bool basewidget::getThumbnail(const QString& name)
{
    QVariantHash metadata;
    bool ok;
    try {
        ok = QMetaObject::invokeMethod(mActivityStorage, "activityMetaData", Q_RETURN_ARG(QVariantHash, metadata), Q_ARG(QString, name));
    }
    catch(...) {
        logCatchError("thumbnail");
        return false;
    }
    if(!ok) {
        return false;
    }
    QString pixfile = metadata.value(ActivityScreenshotKeyword).toString();
    ok = QMetaObject::invokeMethod(mActivityManager, "getThumbnail", Q_ARG(QSize, QSize(1000, 1000)), Q_ARG(QString, pixfile), Q_ARG(void*, NULL));
    return ok;
}



int basewidget::ClientHeapSize()
{
    RHeap& heap = User::Heap();
    TInt all=0;
    heap.AllocSize(all);
    return all;
}




void basewidget::logErrorMessage(const QString& mess)
{
    QString messlog("*Fail: ");
    messlog += mess;
    messlog += "*\n";
    *mStream<<messlog;
    mStream->flush();
    mStatusValueLabel->setPlainText("Fail");
}



void basewidget::releaseMem()
{
    mActivities.clear();
    clearSaveData();
    releaseAlloced();
}


void basewidget::save()
{
    releaseMem();
    bool ok = removeActivity("0");
    logAction("save");    
    prepareDataSave();
    alloc();
    ok = saveActivity(0);
    releaseMem();
    logSaveResult(ok);
}

void basewidget::thumb()
{
    releaseMem();
    disconnect( mActivityManager, SIGNAL(thumbnailReady(QPixmap, void *)), this, SLOT(thumbnailReady(QPixmap, void *)) );
    bool ok = removeActivity("0");
    logAction("thumb");    
    prepareThumbSave();
    ok = saveActivity(0);
    if(!ok) {
        logErrorMessage("save");
        return;
    }    
    clearSaveData();
    ok = activities();
    if(!ok || mActivities.count()==0) {
        logErrorMessage("activities");
        return;
    }    
    QString name = mActivities.at(0);
    alloc();
    ok = getThumbnail(name);
    if(!ok) {
        logErrorMessage("getthumb");
        return;
    }  
    connect( mActivityManager, SIGNAL(thumbnailReady(QPixmap, void *)), this, SLOT(thumbnailReady(QPixmap, void *)) );
    
}

void basewidget::data()
{
    releaseMem();
    bool ok = removeActivity("0");
    logAction("data");    
    prepareDataSave();    
    ok = saveActivity(0);
    if(!ok) {
        logErrorMessage("save");
        return;
    }    
    ok = activities();
    if(!ok || mActivities.count()==0) {
        logErrorMessage("activities");
        return;
    }    
    QString name = mActivities.at(0);    
    alloc();
    ok = privateData(name);
    if(!ok) {
        logErrorMessage("data");
        return;
    }  
    releaseMem();    
}

void basewidget::thumbnailReady(QPixmap pixmap, void* ptr)
{
    releaseMem();
    disconnect( mActivityManager, SIGNAL(thumbnailReady(QPixmap, void *)), this, SLOT(thumbnailReady(QPixmap, void *)) );
    logPixmapSize(pixmap);
}

void basewidget::logCatchError(const QString& mess)
{
    QString msg = tr("Catch err: %1").arg(mess);
    mCatchLabel->setPlainText(msg);
    *mStream<<msg<<"\n";
    mStream->flush();
}

void basewidget::logDataType(const QString& type)
{
    QString msg = tr("Data type: %1").arg(type);
    mStatusValueLabel->setPlainText(msg);
    *mStream<<msg<<"\n";
    mStream->flush();    
}

void basewidget::logPixmapSize(const QPixmap& pix)
{
    QSize s = pix.size();
    QString msg = tr("Pix size: %1x%2").arg(s.width()).arg(s.height());
    mStatusValueLabel->setPlainText(msg);
    *mStream<<msg<<"\n";
    mStream->flush();    
}

void basewidget::logAction(const QString& mess)
{
    mStatusValueLabel->clear();    
    mCatchLabel->clear();
    QString msg = tr("Action: %1").arg(mess);    
    *mStream<<msg<<"\n";
    QString bytemsg = tr("Free Bytes: %1").arg(Bytes());
    *mStream<<bytemsg<<"\n";
    mStream->flush();
}

void basewidget::logSaveResult(bool res)
{
    QString msg = tr("Save: %1").arg(res);
    mStatusValueLabel->setPlainText(msg);
    *mStream<<msg<<"\n";
    mStream->flush();
}

bool basewidget::alloc()
{
    releaseAlloced();
    int tobefreebytes = Bytes();    
    int all = ClientHeapSize();
    
    int nowfree = KMaxHeapMem - all;
    int toalloc = nowfree - tobefreebytes;
    
    bool ok = false;
    if( toalloc>=0 ) {
        ok = true;
        try {
            mAlloc = new char[toalloc];
        }
        catch(...) {
            ok = false;
        }
    }
    if(!mAlloc) {
        ok = false;
    }
    
    if(!ok) {
        QString msg = tr("Alloc Failed");
        mCatchLabel->setPlainText(msg);
        *mStream<<msg<<"\n";
        mStream->flush();
    }
    return ok;
}

void basewidget::releaseAlloced()
{
    delete mAlloc;
    mAlloc = NULL;
}