diff -r 000000000000 -r dd21522fd290 webengine/widgetregistry/Server/src/WidgetEntry.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/webengine/widgetregistry/Server/src/WidgetEntry.cpp Mon Mar 30 12:54:55 2009 +0300 @@ -0,0 +1,555 @@ +/* +* Copyright (c) 2006, 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Holds metadata, one version per widget. +* +* +*/ + +#include "WidgetEntry.h" +#include "WidgetRegistryConstants.h" +#include +#include +#include +//#include + +// EXTERNAL DATA STRUCTURES + +// EXTERNAL FUNCTION PROTOTYPES + +// CONSTANTS +#define SAPISECURITYPROMPTNEEDED 0x0001 +#define SAPIPROMPTLESS 0x0002 +#define SAPIACCESSDENIED 0x0003 + +// MACROS + +// LOCAL CONSTANTS AND MACROS + +// for externalize +_LIT( KXmlPropStart, "" ); +_LIT( KXmlPropEnd, "" ); +_LIT( KXmlValStart, "" ); +_LIT( KXmlValEnd, "" ); +_LIT( KXmlTypeStart, "" ); +_LIT( KXmlTypeEnd, "" ); +_LIT( KXmlNewline, "\x0D\x0A" ); // DOS/Symbian style works with XML parsers + +// for internalize +_LIT8( KXmlPropTag, "prop" ); +_LIT8( KXmlValTag, "val" ); +_LIT8( KXmlTypeTag, "type" ); +_LIT( KXmlDataTypeBool, "bool" ); +_LIT( KXmlDataTypeInt, "int" ); +_LIT( KXmlDataTypeString, "string" ); +_LIT( KXmlDataTypeUid, "uid" ); + +// MODULE DATA STRUCTURES + +// LOCAL FUNCTION PROTOTYPES + +// FORWARD DECLARATIONS + +// ============================= LOCAL FUNCTIONS =============================== + +// ============================ MEMBER FUNCTIONS =============================== + + +// ============================================================================ +// CWidgetEntry::NewL() +// two-phase constructor +// +// @since 3.1 +// ============================================================================ +// +CWidgetEntry* CWidgetEntry::NewL() + { + CWidgetEntry *self = new ( ELeave ) CWidgetEntry(); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop(); + return self; + } + +// ============================================================================ +// CWidgetEntry::NewL() +// two-phase constructor +// +// @since 5.0 +// ============================================================================ +// +CWidgetEntry* CWidgetEntry::NewL( RPointerArray** aProps ) +{ + CWidgetEntry* tmp = NewL(); + for ( TInt i = 0; i < (*aProps)->Count(); i++ ) + { + CWidgetPropertyValue* value = CWidgetPropertyValue::NewL(); + tmp->iPropertyValues.AppendL( value ); + (*tmp)[i].iType = (**aProps)[i]->iType; + (*tmp)[i].iValue = (**aProps)[i]->iValue; // shallow copy of strings + (**aProps)[i]->iType = EWidgetPropTypeUnknown; + delete (**aProps)[i]; + } + (*aProps)->Close(); + delete *aProps; + *aProps = NULL; + return tmp; +} + +// ============================================================================ +// CWidgetEntry::CWidgetEntry() +// C++ constructor +// +// @since 3.1 +// ============================================================================ +// +CWidgetEntry::CWidgetEntry() + : iPropertyValues( EWidgetPropertyIdCount ), + iBlanketPermGranted ( EFalse), + iFullView ( EFalse), + iMiniView ( EFalse) + { + } + +// ============================================================================ +// CWidgetEntry::~CWidgetEntry() +// destructor +// +// @since 3.1 +// ============================================================================ +// +CWidgetEntry::~CWidgetEntry() + { + iPropertyValues.ResetAndDestroy(); + } + +// ============================================================================ +// CWidgetEntry::ConstructL() +// symbian second phase constructor +// +// @since 3.1 +// ============================================================================ +// +void CWidgetEntry::ConstructL() + { + } + +// ============================================================================ +// CWidgetEntry::InternalizeBinaryL() +// read from persistent storage(file) +// +// @since 3.1 +// ============================================================================ +// +void CWidgetEntry::InternalizeBinaryL( RReadStream& aReadStream ) + { + for (TInt i = iPropertyValues.Count() ; i < EWidgetPropertyIdCount; i++) + { + CWidgetPropertyValue* val = CWidgetPropertyValue::NewL(); + CleanupStack::PushL(val); + iPropertyValues.AppendL( val ); + CleanupStack::Pop( val ); + } + // read what should be EWidgetPropertyListVersion + (*this)[0].DeserializeL( aReadStream ); + + // For now, leave if version doesn't match compiled-in version, + // FUTURE do something smarter + if ( ( EWidgetPropTypeUnknown == (*this)[EWidgetPropertyListVersion].iType ) + || ( WIDGETPROPERTYLISTVERSION != (*this)[EWidgetPropertyListVersion] ) ) + { + User::Leave( KErrCorrupt ); + } + + // fill property values array + for ( TInt i = 1; i < EWidgetPropertyIdCount; ++i ) + { + (*this)[i].DeserializeL( aReadStream ); + } + } + + +// ============================================================================ +// CWidgetEntry::InternalizeXmlL() +// read from persistent storage(file) +// +// @since 5.0 +// ============================================================================ +// +void CWidgetEntry::InternalizeXmlL( RFs& aFileSession, + xmlDocPtr aDoc, + xmlNode* n, + CWidgetRegistryXml* aXmlProcessor ) + { + // namevaluetypename + // + // prop subtree traversal assumes strict adherence to the + // prototype structure, otherwise code leaves with corrupt code + for ( ; + n; + ) + { + // permit some non element stuff (comment, whitespace...) before + while ( n && ( n->type != XML_ELEMENT_NODE ) ) + { + n = n->next; + } + if ( NULL == n ) + { + for (TInt i = iPropertyValues.Count(); i < EWidgetPropertyIdCount; i++) + { + CWidgetPropertyValue* val = CWidgetPropertyValue::NewL(); + CleanupStack::PushL(val); + iPropertyValues.AppendL( val ); + CleanupStack::Pop(); // val + } + return; + } + TPtrC8 propTag( n->name ); + if ( 0 != propTag.Compare( KXmlPropTag() ) ) + { + // TODO unrecognized subtree? + return; + } + // TODO validate n->children != NULL and type XML_TEXT_NODE + HBufC* name; + aXmlProcessor->GetContentL( aFileSession, aDoc, n->children, &name ); + + // get value array index (TWidgetPropertyId) for name + TPtr namePtr( name->Des() ); + TInt propId = + aXmlProcessor->GetPropertyId( namePtr ); + delete name; + name = NULL; + if ( EWidgetPropertyIdInvalid == propId ) + { + User::Leave( KErrNoMemory ); + } + + for (TInt i = iPropertyValues.Count(); i <= propId; i++) + { + CWidgetPropertyValue* val = CWidgetPropertyValue::NewL(); + CleanupStack::PushL(val); + iPropertyValues.AppendL( val ); + CleanupStack::Pop(); // val + } + + n = n->children->next; // down to val + if ( NULL == n ) + { + User::Leave( KErrCorrupt ); + } + TPtrC8 valTag( n->name ); + if ( 0 != valTag.Compare( KXmlValTag() ) ) + { + User::Leave( KErrCorrupt ); + } + if (propId >= EWidgetPropertyIdCount) // unsupported property + { + HBufC* value = NULL; + if (n->children) + { + aXmlProcessor->GetTextContentAsStringL( aFileSession, aDoc, n->children, &value ); + } + else + { + value = KNullDesC().AllocL(); + } + (*this)[propId].iValue.s = value; + (*this)[propId].iType = EWidgetPropTypeBlob; + n = (n->parent)->next; // up two and next sibling + continue; + } + // TODO validate n->children != NULL and type XML_TEXT_NODE + HBufC* value; + aXmlProcessor->GetContentL( aFileSession, aDoc, n->children, &value ); + CleanupStack::PushL( value ); + + n = n->children->next; // down to type + if ( NULL == n ) + { + User::Leave( KErrCorrupt ); + } + TPtrC8 typeTag( n->name ); + if ( 0 != typeTag.Compare( KXmlTypeTag() ) ) + { + User::Leave( KErrCorrupt ); + } + // TODO validate n->children != NULL and type XML_TEXT_NODE + HBufC* type; + aXmlProcessor->GetContentL( aFileSession, aDoc, n->children, &type ); + CleanupStack::PushL( type ); + + // now have: name, value, type + // convert type string to TWidgetPropertyType + // + // assume void/unknown is not put in XML format so anything + // not recognized should be handled like other unrecognized + // subtree + TWidgetPropertyType typeEnum = EWidgetPropTypeUnknown; + if ( 0 == type->Des().Compare( KXmlDataTypeBool() ) ) + { + typeEnum = EWidgetPropTypeBool; + } + else if ( 0 == type->Des().Compare( KXmlDataTypeInt() ) ) + { + typeEnum = EWidgetPropTypeInt; + } + else if ( 0 == type->Des().Compare( KXmlDataTypeString() ) ) + { + typeEnum = EWidgetPropTypeString; + } + else if ( 0 == type->Des().Compare( KXmlDataTypeUid() ) ) + { + typeEnum = EWidgetPropTypeUid; + } + CleanupStack::PopAndDestroy( type ); + + // TODO handle unknown type due to future extensions: add prop + // subtree to list of unrecognized subtrees + + // set prop according to type + switch ( typeEnum ) + { + case EWidgetPropTypeBool: + if ( 0 == value->Des().Compare( _L("0") ) ) + { + (*this)[propId].iValue.i = 0; + } + else + { + (*this)[propId].iValue.i = 1; + } + break; + case EWidgetPropTypeInt: + { + TLex toInt( value->Des() ); + TInt k; + if ( KErrNone != toInt.Val( k ) ) + { + User::Leave( KErrCorrupt ); + } + (*this)[propId].iValue.i = k; + } + break; + case EWidgetPropTypeString: + (*this)[propId].iValue.s = value; + break; + case EWidgetPropTypeUid: + { + TLex toUid( value->Des() ); + TInt u; + if ( KErrNone != toUid.Val( u ) ) + { + User::Leave( KErrCorrupt ); + } + (*this)[propId].iValue.uid = TUid::Uid( u ); + } + break; + }; + + (*this)[propId].iType = typeEnum; + + CleanupStack::Pop( value ); + if ( EWidgetPropTypeString != typeEnum ) + { + delete value; + } + + n = ((n->parent)->parent)->next; // up two and next sibling + } + } + + +// ============================================================================ +// CWidgetEntry::ExternalizeBinaryL() +// write to persistent storage(file) +// +// @since 3.1 +// ============================================================================ +// +void CWidgetEntry::ExternalizeBinaryL( RWriteStream& aWriteStream ) + { + TInt i = 0; + for ( ; i < EWidgetPropertyIdCount; ++i ) + { + (*this)[i].SerializeL( aWriteStream ); + } + } + +void CWidgetEntry::ExternalizeXmlL( RWriteStream& aWriteStream, + CWidgetRegistryXml* aXmlProcessor, + RFs& aFileSession ) + { + xmlDocPtr doc = NULL; // not really used + TInt i = 0; + // For each property, write an XML entry + for ( ; i < EWidgetPropertyIdCount; ++i ) + { + // skip props without values + if ( EWidgetPropTypeUnknown == (*this)[i].iType ) + { + continue; + } + + TBuf str; + // name + str.Append( KXmlPropStart ); + str.Append( aXmlProcessor->XmlPropertyName( i ) ); + aWriteStream.WriteL( str ); + // value + str.SetLength( 0 ); + str.Append( KXmlValStart ); + aWriteStream.WriteL( str ); + str.SetLength( 0 ); + switch ( (*this)[i].iType ) + { + case EWidgetPropTypeBool: + { + TInt j = (*this)[i]; + if ( 0 == j ) + { + str.Append( _L("0") ); + } + else + { + str.Append( _L("1") ); + } + } + break; + case EWidgetPropTypeInt: + { + TInt k = (*this)[i]; + str.AppendFormat( _L("%d"), k ); + } + break; + case EWidgetPropTypeString: + { + str.Append( (*this)[i] ); + } + break; + case EWidgetPropTypeUid: + const TUid& u = (*this)[i]; + TInt l = u.iUid; + str.AppendFormat( _L("%d"), l ); + break; + }; + aWriteStream.WriteL( str ); + + // type + str.SetLength( 0 ); + str.Append( KXmlTypeStart ); + switch ( (*this)[i].iType ) + { + case EWidgetPropTypeBool: + str.Append( _L("bool") ); + break; + case EWidgetPropTypeInt: + str.Append( _L("int") ); + break; + case EWidgetPropTypeString: + str.Append( _L("string") ); + break; + case EWidgetPropTypeUid: + str.Append( _L("uid") ); + break; + }; + aWriteStream.WriteL( str ); + + // + str.SetLength( 0 ); + str.Append( KXmlTypeEnd ); + str.Append( KXmlValEnd ); + str.Append( KXmlPropEnd ); + str.Append( KXmlNewline ); + aWriteStream.WriteL( str ); + } + + for ( ; i < iPropertyValues.Count(); ++i ) + { + TBuf str; + // name + str.Append( KXmlPropStart ); + str.Append( aXmlProcessor->XmlPropertyName( i ) ); + aWriteStream.WriteL( str ); + + // value + str.SetLength( 0 ); + str.Append( KXmlValStart ); + aWriteStream.WriteL( str ); + str.SetLength( 0 ); + const HBufC* s = (iPropertyValues[i])->iValue.s; + str.Append( *s ); + aWriteStream.WriteL( str ); + str.SetLength( 0 ); + str.Append( KXmlValEnd ); + str.Append( KXmlPropEnd ); + str.Append( KXmlNewline ); + aWriteStream.WriteL( str ); + } + } + + +// ============================================================================ +// CWidgetEntry::Active() +// Is widget running? 0 if not, non zero if running. +// +// @since 3.1 +// ============================================================================ +// +TInt CWidgetEntry::ActiveL() + { + if ( iActive ) + { + // check that WidgetUI didn't crash, this assumes all widgets + // in the registry are running under WidgetUI + RWsSession wsSession; + User::LeaveIfError( wsSession.Connect() ); + CleanupClosePushL( wsSession ); + TApaTaskList taskList( wsSession ); + TApaTask task = taskList.FindApp( KUidWidgetUi ); + if ( EFalse == task.Exists() ) + { + // widget UI crashed, reset active + iActive = 0; + } + CleanupStack::PopAndDestroy( &wsSession ); + } + return iActive; +} + +// ============================================================================ +// CWidgetEntry::SapiAccessState() +// Does widget have sapi access? after accepting security prompt, promptless or no access. +// +// @since 5.0 +// ============================================================================ +// +TInt CWidgetEntry::SapiAccessState() + { + if( GetFullViewState() && !GetMiniViewState()) + { + return SAPISECURITYPROMPTNEEDED; + } + else if ( GetMiniViewState() && GetBlanketPermGranted() ) + { + return SAPIPROMPTLESS; + } + else + { + return SAPIACCESSDENIED; + } + + } + +// End of File