--- a/src/hbcore/devicedialogbase/devicedialogserver/hbdevicedialogmanager_p.cpp Fri Sep 17 08:32:10 2010 +0300
+++ b/src/hbcore/devicedialogbase/devicedialogserver/hbdevicedialogmanager_p.cpp Mon Oct 04 00:38:12 2010 +0300
@@ -115,8 +115,8 @@
if (event->type() == QEvent::QEvent::GraphicsSceneResize) {
HbPopup *popup = qobject_cast<HbPopup*>(obj);
if (popup) {
- QRectF rect = popup->rect();
- rect.moveTo(popup->pos());
+ QRectF rect = popup->mapToScene(popup->rect()).boundingRect();
+ rect = mDeviceDialogManger->mMainWindow->mapFromScene(rect).boundingRect();
HbDeviceDialogsContainer::Dialog & dialog = mDeviceDialogManger->mDialogs.find(popup);
mDeviceDialogManger->addRegionRect(dialog.id(), rect);
}
@@ -240,6 +240,7 @@
{
TRACE_ENTRY
+ parameters.mError = HbDeviceDialogNoError;
int id = 0;
HbDeviceDialogPlugin::DeviceDialogInfo info;
@@ -290,8 +291,16 @@
HbDeviceDialogsContainer::Dialog &dialog = mDialogs.find(id);
if (dialog.isValid()) {
HbDeviceDialogInterface *interface = dialog.widget();
- bool success = interface->setDeviceDialogParameters(parameters);
- if (!success) {
+ bool success = false;
+ bool catched = false;
+ try {
+ success = interface->setDeviceDialogParameters(parameters);
+ } catch (const std::bad_alloc &) {
+ catched = true;
+ }
+ if (catched) {
+ ret = HbDeviceDialogGeneralError;
+ } else if (!success) {
ret = checkpluginerror(interface->deviceDialogError());
} else {
ret = HbDeviceDialogNoError;
@@ -314,9 +323,13 @@
if (!byClient) {
dialog.setFlags(HbDeviceDialogsContainer::Dialog::ClosedByServer);
}
- dialog.widget()->closeDeviceDialog(byClient);
+ ret = HbDeviceDialogNoError;
+ try {
+ dialog.widget()->closeDeviceDialog(byClient);
+ } catch(const std::bad_alloc &) {
+ ret = HbDeviceDialogGeneralError;
+ }
startHousekeeperTimer();
- ret = HbDeviceDialogNoError;
}
TRACE_EXIT
return ret;
@@ -350,6 +363,11 @@
int HbDeviceDialogManagerPrivate::activateIndicator(
HbDeviceDialogServer::IndicatorParameters ¶meters)
{
+ // In order to prevent dialogs/indicators trowing bad_alloc during execution, amount
+ // of heap available is checked before activation is allowed.
+ if (!heapAvailable(NormalLevelMinHeap)) {
+ return HbDeviceDialogGeneralError;
+ }
QVariantMap credentials;
addSecurityCredentials(parameters, credentials);
int result = HbDeviceDialogNoError;
@@ -461,7 +479,7 @@
RWindowBase *win =
static_cast<RWindowBase*>(mMainWindow->effectiveWinId()->DrawableWindow());
if (win) {
- RRegionBuf<1> windowRegion(QRectToTRect(mMainWindow->sceneRect()));
+ RRegionBuf<1> windowRegion(QRectToTRect(mMainWindow->rect()));
win->SetShape(windowRegion);
}
}
@@ -636,7 +654,12 @@
HbDeviceDialogServer::DialogParameters ¶meters,
HbDeviceDialogPlugin::DeviceDialogInfo &deviceDialogInfo, HbPopup *&popup)
{
- parameters.mError = HbDeviceDialogNoError;
+ // In order to prevent a dialog trowing bad_alloc when it is executing, amount
+ // of heap available is checked before new dialog is allowed.
+ if (!heapAvailable(SecurityLevelMinHeap)) {
+ parameters.mError = HbDeviceDialogGeneralError;
+ return 0;
+ }
QString pluginFilePath;
if (!mPluginManager.loadPlugin(parameters.mType, QString(), &pluginFilePath)) {
@@ -658,6 +681,15 @@
return 0;
}
+ // Normal level device dialogs require bigger heap reserve in order to not to
+ // block higher level dialogs.
+ if (deviceDialogInfo.showLevel == HbDeviceDialogPlugin::NormalLevel &&
+ !heapAvailable(NormalLevelMinHeap)) {
+ parameters.mError = HbDeviceDialogGeneralError;
+ mPluginManager.unloadPlugin(pluginFilePath);
+ return 0;
+ }
+
// Plugin may request security check of the client
if (deviceDialogInfo.flags & HbDeviceDialogPlugin::SecurityCheck) {
QVariantMap credentials;
@@ -819,6 +851,34 @@
return true;
}
+// Check there is minimum amount of heap available
+bool HbDeviceDialogManagerPrivate::heapAvailable(int aBytes)
+{
+ const int MaxFragments = 16;
+ const int MinFragmentSize = 0x1000; // 4 kB
+ int fragmentSize = aBytes / MaxFragments;
+ if (fragmentSize < MinFragmentSize) {
+ fragmentSize = MinFragmentSize;
+ }
+ char *fragments[MaxFragments];
+ memset(&fragments, 0, sizeof(fragments));
+ bool success = true;
+ int i = 0;
+ while(success && i < MaxFragments && aBytes >= 0) {
+ try {
+ fragments[i] = new char[fragmentSize];
+ } catch(const std::bad_alloc &) {
+ success = false;
+ }
+ i++;
+ aBytes -= fragmentSize;
+ }
+ for(--i; i >= 0; i--) {
+ delete [] fragments[i];
+ }
+ return success;
+}
+
// Called by device dialog widget to send some data to client.
void HbDeviceDialogManagerPrivate::deviceDialogUpdate(const QVariantMap &data) const
{