webengine/widgetregistry/Server/src/WidgetRegistry.cpp
changeset 0 dd21522fd290
child 5 10e98eab6f85
equal deleted inserted replaced
-1:000000000000 0:dd21522fd290
       
     1 /*
       
     2 * Copyright (c) 2006, 2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Manages list of widget entries.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <e32base.h>
       
    20 #include <f32file.h>
       
    21 #include <s32file.h>
       
    22 #include <s32mem.h>
       
    23 #include <bautils.h>
       
    24 
       
    25 #include "WidgetEntry.h"
       
    26 #include "WidgetRegistry.h"
       
    27 #include "WidgetInstaller.h"
       
    28 #include <libxml2_globals.h>
       
    29 #include <libc\stdlib.h>
       
    30 #include <libxml2_parser.h>
       
    31 #include <libxml2_tree.h>
       
    32 #include "WidgetMMCHandler.h"
       
    33 #include "UidAllocator.h"
       
    34 #if defined( BRDO_WRT_SECURITY_MGR_FF )
       
    35 #include <RTSecManager.h>
       
    36 #endif
       
    37 #include <e32property.h>
       
    38 
       
    39 // CONSTANTS
       
    40 
       
    41 static const TInt KDefaultWidgetCount = 20; // used for initial RArray size
       
    42 static const TInt KAppArchTimeout = 10000000; // 10 seconds in microseconds
       
    43 static const TInt KAppArchDelayInterval = 500000; // 500 milliseonds in microseconds
       
    44 
       
    45 enum
       
    46     {
       
    47     EAppListFlagEntry = 1
       
    48     };
       
    49 
       
    50 enum
       
    51     {
       
    52     EInstallListFlagEntry = 1
       
    53     };
       
    54 
       
    55 // Be sure that length of literal pathname strings is less than
       
    56 // KWidgetRegistryMaxPathName in header file.
       
    57 //
       
    58 // drive letter a: is used as a placeholder, it will be set as needed
       
    59 _LIT( KWidgetInstallPath,
       
    60       "a:\\private\\10282822\\" );
       
    61 _LIT( KWidgetEntryStoreBinaryFile,
       
    62       "a:\\private\\10282f06\\WidgetEntryStore.dat" );
       
    63 _LIT( KWidgetEntryStoreXmlFile,
       
    64       "a:\\private\\10282f06\\WidgetEntryStore.xml" );
       
    65 _LIT( KWidgetEntryStoreXmlTempFile,
       
    66       "a:\\private\\10282f06\\WidgetEntryStoreTemp.xml" );
       
    67 _LIT( KWidgetDirFile, "widget_lproj.xml" );
       
    68 _LIT( KWidgetAccessPolicy, "WidgetAccessPolicy.xml" );
       
    69 _LIT( KWidgetPolicyIdFile, "WidgetPolicyId.dat" );
       
    70 
       
    71 _LIT( KWidgetDefaultLangDir, "en" );
       
    72 _LIT8( KLangID, "LangID" );
       
    73 _LIT8( KLangDir, "LangDir" );
       
    74 
       
    75 // for exteranlize
       
    76 _LIT( KXmlHeader,
       
    77       "<?xml version=\"1.0\" encoding=\"UTF-16\" standalone=\"yes\" ?>" );
       
    78 _LIT( KXmlRootStart, "<widgetregistry>" );
       
    79 _LIT( KXmlRootEnd, "</widgetregistry>" );
       
    80 _LIT( KWidgetEntryStart, "<entry>" );
       
    81 _LIT( KWidgetEntryEnd, "</entry>" );
       
    82 _LIT( KXmlNewline, "\x0D\x0A" ); // DOS/Symbian style works with XML parsers
       
    83 
       
    84 // for internalize
       
    85 _LIT8( KWidgetRegistry, "widgetregistry" );
       
    86 _LIT8( KEntry, "entry" );
       
    87 
       
    88 LOG_NAMES( "widreg", "widreg.txt" )
       
    89 
       
    90 void XmlDocFree( TAny* aPtr )
       
    91     {
       
    92     __ASSERT_DEBUG( aPtr, User::Invariant() );
       
    93     xmlDocPtr ptr( (xmlDocPtr)(aPtr) );
       
    94     xmlFreeDoc( ptr );
       
    95     }
       
    96 
       
    97 // ============================================================================
       
    98 // Traverse to the next Node
       
    99 //
       
   100 // @param aNode: current node
       
   101 // @since 3.1
       
   102 // @return next node
       
   103 // ============================================================================
       
   104 //
       
   105 xmlNode* TraverseNextNode( xmlNode* n )
       
   106     {
       
   107     // depth first
       
   108     if ( n->children )
       
   109         {
       
   110         n = n->children;
       
   111         }
       
   112     else
       
   113         {
       
   114         // go up while no sibling
       
   115         while ( n->parent && !n->next )
       
   116             {
       
   117             n = n->parent;
       
   118             }
       
   119         // sibling?
       
   120         if ( n->next )
       
   121             {
       
   122             n = n->next;
       
   123             }
       
   124         else // done
       
   125             {
       
   126             n = NULL;
       
   127             }
       
   128         }
       
   129     return n;
       
   130     }
       
   131 // ============================================================================
       
   132 // Changes the Publish & Subscribe key value
       
   133 // ============================================================================
       
   134 //
       
   135 
       
   136 static void NotifyWidgetAltered()
       
   137     {
       
   138     const TUid KMyPropertyCat = { 0x10282E5A };
       
   139     enum TMyPropertyKeys { EMyPropertyAltered = 110 };
       
   140     TInt altered( 1 );
       
   141     RProperty::Set( KMyPropertyCat, EMyPropertyAltered , altered );
       
   142     }
       
   143 // ============================================================================
       
   144 // CWidgetRegistry::NewL()
       
   145 // two-phase constructor
       
   146 //
       
   147 // @since 3.1
       
   148 // ============================================================================
       
   149 //
       
   150 CWidgetRegistry* CWidgetRegistry::NewL( RFs& aFs )
       
   151     {
       
   152     CWidgetRegistry* widgetRegistry = new ( ELeave ) CWidgetRegistry( aFs );
       
   153     CleanupStack::PushL( widgetRegistry );
       
   154     TRAP_IGNORE( widgetRegistry->ConstructL() );
       
   155     CleanupStack::Pop( widgetRegistry );
       
   156     return widgetRegistry;
       
   157     }
       
   158 
       
   159 // ============================================================================
       
   160 // CWidgetRegistry::CWidgetRegistry()
       
   161 // C++ constructor
       
   162 //
       
   163 // @since 3.1
       
   164 // ============================================================================
       
   165 //
       
   166 CWidgetRegistry::CWidgetRegistry( RFs& aFs ):
       
   167     iFs( aFs ),
       
   168     iWidgetInstallPath( KWidgetInstallPath ),
       
   169     iRegistryBinaryFileName( KWidgetEntryStoreBinaryFile ),
       
   170     iRegistryXmlFileName( KWidgetEntryStoreXmlFile ),
       
   171     iRegistryXmlTempFileName( KWidgetEntryStoreXmlTempFile ),
       
   172     iPolicyId( 0 )
       
   173     {
       
   174     }
       
   175 
       
   176 // ============================================================================
       
   177 // CWidgetRegistry::~CWidgetRegistry()
       
   178 // destructor
       
   179 //
       
   180 // @since 3.1
       
   181 // ============================================================================
       
   182 //
       
   183 CWidgetRegistry::~CWidgetRegistry()
       
   184     {
       
   185     iEntries.ResetAndDestroy();
       
   186     iUsedUids.Close();
       
   187     // iFs not owned
       
   188     iAppArch.Close();
       
   189     delete iInstaller;
       
   190     iLangDirList.ResetAndDestroy();
       
   191     delete iMMCHandler;
       
   192     delete iXmlProcessor;
       
   193 
       
   194     iFs.Close();
       
   195     LOG_DESTRUCT;
       
   196     }
       
   197 
       
   198 // ============================================================================
       
   199 // CWidgetRegistry::ConstructL()
       
   200 // Symbian second phase constructor
       
   201 //
       
   202 // @since 3.1
       
   203 // ============================================================================
       
   204 //
       
   205 void CWidgetRegistry::ConstructL()
       
   206     {
       
   207     LOG_CONSTRUCTL;
       
   208     LOG_OPEN;
       
   209     LOG( "CWidgetRegistry::ConstructL internalize" );
       
   210 
       
   211     User::LeaveIfError( iFs.Connect() );
       
   212     iFs.CreatePrivatePath( EDriveC );
       
   213     iFs.SetSessionToPrivate( EDriveC );
       
   214     User::LeaveIfError( iAppArch.Connect() );
       
   215     iInstaller = CWidgetInstaller::NewL();
       
   216 
       
   217     // If internalizing leaves, then the registry will be out-of-sync
       
   218     // with the installed widgets and apparc.  But that's okay since
       
   219     // it should be detected and corrected once the resource limit
       
   220     // that caused the leave is removed.
       
   221     TBool dirtyFlag = EFalse;
       
   222     iXmlProcessor = CWidgetRegistryXml::NewL();
       
   223     TRAP_IGNORE( InternalizeL( dirtyFlag ) );
       
   224     if ( dirtyFlag )
       
   225         {
       
   226         // Basically same reason to ignore leaves here.
       
   227         TRAP_IGNORE( ExternalizeL() );
       
   228         }
       
   229 
       
   230     LOG( " ctor internalize done" );
       
   231 
       
   232 #if defined( BRDO_WRT_SECURITY_MGR_FF )
       
   233     FetchSecurityPolicyIdL();
       
   234 #endif
       
   235 
       
   236     LOG1( "ConstructL internalize done, registry count %d",
       
   237               iEntries.Count() );
       
   238     LOG_CLOSE;
       
   239 
       
   240     iMMCHandler = CWidgetMMCHandler::NewL( *this, iFs );
       
   241     iMMCHandler->Start();
       
   242     }
       
   243 
       
   244 // ============================================================================
       
   245 // CWidgetRegistry::FetchSecurityPolicyIdL()
       
   246 // Get policyId from security manager
       
   247 //
       
   248 // @since 5.0
       
   249 // ============================================================================
       
   250 //
       
   251 TInt CWidgetRegistry::FetchSecurityPolicyIdL()
       
   252     {
       
   253 #if defined( BRDO_WRT_SECURITY_MGR_FF )
       
   254     if ( !iPolicyId )
       
   255         {
       
   256         if ( KErrNone == iFs.ShareProtected() )
       
   257             {
       
   258             TFileName secPolicyFileName;
       
   259             RFile secPolicyFile;
       
   260             iFs.PrivatePath( secPolicyFileName );
       
   261 #ifdef __WINSCW__
       
   262             secPolicyFileName.Insert( 0, _L( "C:" ));
       
   263 #else
       
   264             secPolicyFileName.Insert( 0, _L( "Z:" ));
       
   265 #endif
       
   266             secPolicyFileName.Append( KWidgetAccessPolicy );
       
   267 
       
   268             if ( KErrNone == secPolicyFile.Open( iFs, secPolicyFileName, EFileShareAny ) )
       
   269                 {
       
   270                 CleanupClosePushL( secPolicyFile );
       
   271                 CRTSecManager* secMgr = CRTSecManager::NewL();
       
   272                 iPolicyId = secMgr->SetPolicy( secPolicyFile );
       
   273                 CleanupStack::PopAndDestroy( &secPolicyFile );
       
   274 
       
   275                 CleanupStack::PushL( secMgr );
       
   276                 // read old policyId, unset old policy file; store new policyId
       
   277                 RFile policyIdFile;
       
   278                 TFileName policyIdFileName;
       
   279                 iFs.PrivatePath( policyIdFileName );
       
   280                 policyIdFileName.Insert( 0, _L( "C:" ));
       
   281                 policyIdFileName.Append( KWidgetPolicyIdFile );
       
   282 
       
   283                 TInt error = KErrNotFound;
       
   284                 error = policyIdFile.Open( iFs, policyIdFileName, EFileShareAny );
       
   285                 // policy Id file exists
       
   286                 if ( error == KErrNone )
       
   287                     {
       
   288                     CleanupClosePushL( policyIdFile );
       
   289                     RFileReadStream readStream;
       
   290                     CleanupClosePushL( readStream );
       
   291                     readStream.Attach( policyIdFile );
       
   292 
       
   293                     TInt oldPolicyId = 0;
       
   294                     TRAP_IGNORE( oldPolicyId = readStream.ReadInt32L() );
       
   295                     // clean the old policy file
       
   296                     if ( oldPolicyId > 0 )
       
   297                         {
       
   298                         secMgr->UnSetPolicy( oldPolicyId );
       
   299                         }
       
   300 
       
   301                     CleanupStack::PopAndDestroy( &readStream );
       
   302                     }
       
   303                 // create policy Id file
       
   304                 else if ( error == KErrNotFound )
       
   305                     {
       
   306                     User::LeaveIfError( policyIdFile.Create( iFs, policyIdFileName, EFileShareAny ) );
       
   307                         CleanupClosePushL( policyIdFile );
       
   308                     }
       
   309 
       
   310                 // we should have a good policyIdFile by now, store iPolicyId there
       
   311                     RFileWriteStream writeStream;
       
   312                     CleanupClosePushL( writeStream );
       
   313                     writeStream.Replace( iFs, policyIdFileName, EFileShareAny );
       
   314 
       
   315                     TRAP_IGNORE( writeStream.WriteInt32L( iPolicyId ) );
       
   316 
       
   317                 CleanupStack::PopAndDestroy( 2, &policyIdFile );// writeStream, policyIdFile
       
   318 
       
   319                 CleanupStack::PopAndDestroy( secMgr );
       
   320                 }
       
   321             }
       
   322         }
       
   323 #else
       
   324 	iPolicyId = KErrNotSupported;
       
   325 #endif    
       
   326     return iPolicyId;
       
   327     }
       
   328 
       
   329 // ============================================================================
       
   330 // CWidgetRegistry::GetWidgetEntryL()
       
   331 // Get widget entry by UID or leave with KErrNotFound
       
   332 //
       
   333 // @since 3.1
       
   334 // ============================================================================
       
   335 //
       
   336 CWidgetEntry& CWidgetRegistry::GetWidgetEntryL( const TUid& aUid ) const
       
   337     {
       
   338     for( TInt i = 0; i < iEntries.Count(); i++)
       
   339         {
       
   340         CWidgetEntry* entry = iEntries[i];
       
   341         if ( TUid::Uid( (*entry)[EUid] ) == aUid )
       
   342             {
       
   343             return *entry;
       
   344             }
       
   345         }
       
   346     User::Leave( KErrNotFound );
       
   347     return *iEntries[0];  // just for compiler
       
   348     }
       
   349 
       
   350 // ============================================================================
       
   351 // CWidgetRegistry::GetWidgetEntry()
       
   352 // Get the widget entry
       
   353 //
       
   354 // @since 3.1
       
   355 // ============================================================================
       
   356 //
       
   357 // TODO use leaving version GetWidgetEntryL everywhere and delete this version
       
   358 TInt CWidgetRegistry::GetWidgetEntry(
       
   359     const TUid& aUid,
       
   360     CWidgetEntry*& aEntry) const
       
   361     {
       
   362     for(TInt i = 0;i < iEntries.Count();i++)
       
   363         {
       
   364         CWidgetEntry* entry = iEntries[i];
       
   365         if ( TUid::Uid( (*entry)[EUid] ) == aUid )
       
   366             {
       
   367             aEntry = entry;
       
   368             return i;
       
   369             }
       
   370         }
       
   371     return -1;
       
   372     }
       
   373 
       
   374 // ============================================================================
       
   375 // CWidgetRegistry::GetWidgetEntry()
       
   376 // Get the widget entry
       
   377 //
       
   378 // @since 3.1
       
   379 // ============================================================================
       
   380 //
       
   381 TInt CWidgetRegistry::GetWidgetEntry(
       
   382     const TDesC& aBundleId,
       
   383     CWidgetEntry*& aEntry) const
       
   384     {
       
   385     for(TInt i = 0;i < iEntries.Count();i++)
       
   386         {
       
   387         CWidgetEntry* entry = iEntries[i];
       
   388         const TDesC& widgetBundleId = (*entry)[EBundleIdentifier];
       
   389         if ( widgetBundleId.CompareF( aBundleId ) == 0 )
       
   390             {
       
   391             aEntry = entry;
       
   392             return i;
       
   393             }
       
   394         }
       
   395     return -1;
       
   396     }
       
   397 
       
   398 // ============================================================================
       
   399 // CWidgetRegistry::GetWidgetEntry()
       
   400 // Returns the WidgetEntry at a particular index
       
   401 //
       
   402 // @since 3.1
       
   403 // ============================================================================
       
   404 //
       
   405 const CWidgetEntry* CWidgetRegistry::GetWidgetEntry( const TInt& aPos )
       
   406     {
       
   407     return iEntries[aPos];
       
   408     }
       
   409 
       
   410 
       
   411 // ============================================================================
       
   412 // CWidgetRegistry::InsertL()
       
   413 // Insert the widget entry into the list if BundleID is not already in
       
   414 // the list.
       
   415 //
       
   416 // @since 3.1
       
   417 // ============================================================================
       
   418 //
       
   419 TInt CWidgetRegistry::InsertL( CWidgetEntry* aEntry )
       
   420     {
       
   421     CWidgetEntry* entry = NULL;
       
   422     TDesC bundleID = (*aEntry)[EBundleIdentifier];
       
   423     TInt pos  = GetWidgetEntry( bundleID, entry );
       
   424     if ( pos == KErrNotFound )
       
   425         {
       
   426         iUsedUids.AppendL( TUid::Uid( (*aEntry)[EUid] ) );
       
   427         TInt error = iEntries.Append( aEntry );
       
   428         if ( KErrNone != error )
       
   429             {
       
   430             TInt upos = iUsedUids.FindReverse( TUid::Uid( (*aEntry)[EUid] ) );
       
   431             iUsedUids.Remove( upos );
       
   432             User::Leave( error );
       
   433             }
       
   434         }
       
   435     return pos;
       
   436     }
       
   437 
       
   438 // ============================================================================
       
   439 // CWidgetRegistry::Remove()
       
   440 // Remove the widget entry from the list
       
   441 //
       
   442 // @since 3.1
       
   443 // ============================================================================
       
   444 //
       
   445 void CWidgetRegistry::Remove( const TDesC& aBundleId )
       
   446     {
       
   447     CWidgetEntry* entry = NULL;
       
   448     TInt pos  = GetWidgetEntry( aBundleId, entry );
       
   449 
       
   450     if ( pos != -1 )
       
   451         {
       
   452         TInt upos = iUsedUids.Find( TUid::Uid( (*entry)[EUid] ) );
       
   453         if ( upos >= 0 )
       
   454             {
       
   455             iUsedUids.Remove( upos );
       
   456             }
       
   457 
       
   458         iEntries.Remove( pos );
       
   459 
       
   460         delete entry;
       
   461         }
       
   462     }
       
   463 
       
   464 // ============================================================================
       
   465 // CWidgetRegistry::Remove()
       
   466 // Remove the widget entry from the list
       
   467 //
       
   468 // @since 3.1
       
   469 // ============================================================================
       
   470 //
       
   471 void CWidgetRegistry::Remove( const TUid& aUid )
       
   472     {
       
   473     CWidgetEntry* entry = NULL;
       
   474     TInt pos  = GetWidgetEntry( aUid, entry );
       
   475 
       
   476     if ( pos != -1 )
       
   477         {
       
   478         TInt upos = iUsedUids.Find( TUid::Uid( (*entry)[EUid] ) );
       
   479         if ( upos >= 0 )
       
   480             {
       
   481             iUsedUids.Remove( upos );
       
   482             }
       
   483 
       
   484         iEntries.Remove( pos );
       
   485         delete entry;
       
   486         }
       
   487 
       
   488     }
       
   489 
       
   490 
       
   491 // ============================================================================
       
   492 // CWidgetRegistry::InternalizeL()
       
   493 // Read entry info from data file into memory
       
   494 //
       
   495 // @since 3.1
       
   496 // ============================================================================
       
   497 //
       
   498 void CWidgetRegistry::InternalizeL( TBool& aDirtyFlag )
       
   499     {
       
   500     LOG_OPEN;
       
   501     LOG( "Internalize" );
       
   502 
       
   503     // prepare for consistency enforcement
       
   504     RArray<TUid> appArchList( KDefaultWidgetCount );
       
   505     RArray<TInt> appArchListFlags( KDefaultWidgetCount );
       
   506     // default is internalization just imports files without
       
   507     // modification, if dirty flag gets set to true, do externalize
       
   508     // after internalize to bring files into sync with modified
       
   509     // registry contents
       
   510     aDirtyFlag = EFalse;
       
   511 
       
   512     // internal dirty flag, will be copied to arg dirty flag at
       
   513     // end if no leave occurs
       
   514     TBool dirtyFlag = EFalse;
       
   515 
       
   516     // empty the registry
       
   517     iEntries.ResetAndDestroy();
       
   518     iUsedUids.Reset();
       
   519 
       
   520     CleanupClosePushL( appArchList );
       
   521     CleanupClosePushL( appArchListFlags );
       
   522     TBool doConsistency = AppArchWidgets( appArchList, appArchListFlags );
       
   523     if ( doConsistency )
       
   524         {
       
   525 
       
   526         // UIDs are the key differentiator of apps in app arch.  The
       
   527         // widget implementation used BundleID to differentiate
       
   528         // widgets on installation (overwrite is keyed by BundleID).
       
   529         // But once widgets are installed, they are assigned a unique
       
   530         // UID.  For UID allocation purposes, it is important that
       
   531         // UIDs already known to app arch be reserved.
       
   532         for ( TInt i = 0; i < appArchList.Count(); i++ )
       
   533             {
       
   534             if ( KErrNone != iUsedUids.Append( (appArchList)[i] ) )
       
   535                 {
       
   536                 // no recovery possible
       
   537                 doConsistency = EFalse;
       
   538                 break;
       
   539                 }
       
   540             }
       
   541         }
       
   542     LOG2( " iUsedUids %d and doConsistency %d",
       
   543           (TInt)(iUsedUids.Count()), (TInt)doConsistency );
       
   544 
       
   545     TRAPD( error, GetLprojNameL( iLprojName ) );
       
   546     if ( KErrNone != error )
       
   547         {
       
   548         // on error use english
       
   549         iLprojName = _L("en");
       
   550         }
       
   551 
       
   552     // List all drives in the system
       
   553     TDriveList driveList;
       
   554     User::LeaveIfError( iFs.DriveList(driveList) );
       
   555 
       
   556     // Check all drives but Z and D.  Scan from Y to A because that is
       
   557     // the order that the loader and AppArch follow when "shadowing"
       
   558     // UID identical apps. Drive Z is ignored because it is used for
       
   559     // the phone ROM image and is not an installation location for
       
   560     // widgets. Drive D is ignored because it is a temporary RAM disk
       
   561     // and not a widget install location.
       
   562     for ( TInt driveNumber = EDriveY; driveNumber >= EDriveA; driveNumber-- )
       
   563         {
       
   564         // The drives that will be filtered out are the same ones that
       
   565         // WidgetInstaller filters out in CWidgetUIHandler::SelectDriveL()
       
   566         if ( (EDriveD == driveNumber)
       
   567              || !driveList[driveNumber] )
       
   568             {
       
   569             // EDriveD is a temporary drive usually a RAM disk
       
   570             continue;
       
   571             }
       
   572 
       
   573         TVolumeInfo volInfo;
       
   574         if ( iFs.Volume( volInfo, driveNumber ) != KErrNone )
       
   575             {
       
   576             // volume is not usable (e.g. no media card inserted)
       
   577             continue;
       
   578             }
       
   579         if ( (volInfo.iDrive.iType == EMediaNotPresent) ||
       
   580              (volInfo.iDrive.iType == EMediaRom) ||
       
   581              (volInfo.iDrive.iType == EMediaRemote) ||
       
   582              (volInfo.iDrive.iDriveAtt & KDriveAttRom) ||
       
   583              (volInfo.iDrive.iDriveAtt & KDriveAttSubsted) )
       
   584             {
       
   585             // not a suitable widget install drive
       
   586             continue;
       
   587             }
       
   588 
       
   589         // found a usable drive
       
   590         TDriveUnit driveUnit( driveNumber );
       
   591         LOG1( " Drive %c", (TUint)(driveUnit.Name()[0]) );
       
   592 
       
   593         // prepare for consistency enforcement
       
   594         CDir* installedListForDrive = NULL;
       
   595         RArray<TInt> installedListForDriveFlags;
       
   596         if ( doConsistency )
       
   597             {
       
   598             doConsistency = InstallDirWidgets( driveUnit,
       
   599                                                installedListForDrive,
       
   600                                                installedListForDriveFlags );
       
   601             }
       
   602         LOG1( " after InstallDirWidgets doConsistency %d",
       
   603                   (TInt)doConsistency );
       
   604 
       
   605         // direct install path to this drive
       
   606         iWidgetInstallPath[0] = driveUnit.Name()[0];
       
   607 
       
   608         // which persistent data files exist?
       
   609         iRegistryBinaryFileName[0] = driveUnit.Name()[0];
       
   610         TBool binaryExists = BaflUtils::FileExists( iFs,
       
   611                                                     iRegistryBinaryFileName );
       
   612 
       
   613         iRegistryXmlFileName[0] = driveUnit.Name()[0];
       
   614         TBool xmlExists = BaflUtils::FileExists( iFs,
       
   615                                                  iRegistryXmlFileName );
       
   616 
       
   617         // Here internalizing a single drive.  If internalizing
       
   618         // leaves, then the registry will be out-of-sync with the
       
   619         // installed widgets and apparc.  But that's okay since it
       
   620         // should be detected and corrected once the resource limit
       
   621         // that caused the leave is removed.
       
   622         if ( xmlExists )
       
   623             {
       
   624             TRAP_IGNORE( InternalizeXmlL( iRegistryXmlFileName,
       
   625                                           driveUnit,
       
   626                                           doConsistency,
       
   627                                           appArchList,
       
   628                                           appArchListFlags,
       
   629                                           installedListForDrive,
       
   630                                           installedListForDriveFlags,
       
   631                                           dirtyFlag ) );
       
   632             }
       
   633         else if ( binaryExists )
       
   634             {
       
   635             TRAP_IGNORE( InternalizeBinaryL( iRegistryBinaryFileName,
       
   636                                              driveUnit,
       
   637                                              doConsistency,
       
   638                                              appArchList,
       
   639                                              appArchListFlags,
       
   640                                              installedListForDrive,
       
   641                                              installedListForDriveFlags,
       
   642                                              dirtyFlag ) );
       
   643             }
       
   644 
       
   645         if ( doConsistency )
       
   646             {
       
   647             InstallDirConsistency( installedListForDrive,
       
   648                                    installedListForDriveFlags,
       
   649                                    dirtyFlag );
       
   650             }
       
   651         delete installedListForDrive;
       
   652         installedListForDriveFlags.Close();
       
   653         } // for
       
   654     if ( doConsistency )
       
   655         {
       
   656         AppArchListConsistency( appArchList, appArchListFlags );
       
   657         }    
       
   658     CleanupStack::PopAndDestroy( 2, &appArchList );//appArchListFlags, appArchList
       
   659 
       
   660     aDirtyFlag = dirtyFlag;
       
   661     LOG1( "Internalize done, dirty flag %d", (TInt)dirtyFlag );
       
   662     LOG_CLOSE;
       
   663     }
       
   664 
       
   665 // ============================================================================
       
   666 // CWidgetRegistry::InternalizeBinaryL()
       
   667 // Read entry info from data file into memory
       
   668 //
       
   669 // @since 3.1
       
   670 // ============================================================================
       
   671 //
       
   672 void CWidgetRegistry::InternalizeBinaryL( const TDesC& aFileName,
       
   673                                           const TDriveUnit& aDriveUnit,
       
   674                                           TBool aDoConsistency,
       
   675                                           RArray<TUid>& aAppArchList,
       
   676                                           RArray<TInt>& aAppArchListFlags,
       
   677                                           const CDir* aInstalledListForDrive,
       
   678                                           RArray<TInt>& aInstalledListForDriveFlags,
       
   679                                           TBool& aDirtyFlag )
       
   680     {
       
   681     LOG( "InternalizeBinaryL" );
       
   682     RFile file;
       
   683     User::LeaveIfError( file.Open( iFs, aFileName, EFileRead ) );
       
   684     CleanupClosePushL( file );
       
   685 
       
   686     RFileReadStream readStream;
       
   687     CleanupClosePushL( readStream );
       
   688     readStream.Attach( file );
       
   689 
       
   690     TInt error = KErrNone;
       
   691     TInt entryCount = 0;
       
   692     TRAP( error, entryCount = readStream.ReadInt32L() );
       
   693     // TODO should limit entryCount to something like 1024
       
   694     // for each entry in the registry file
       
   695     for ( TInt i = 0 ; i < entryCount; i++ )
       
   696         {
       
   697         CWidgetEntry* entry = CWidgetEntry::NewL();
       
   698         CleanupStack::PushL( entry );
       
   699 
       
   700         // extract one entry
       
   701         TRAP( error,
       
   702               entry->InternalizeBinaryL( readStream ) );
       
   703         if ( KErrNone == error )
       
   704             {
       
   705             CWidgetEntry* res( NULL );
       
   706             if ( aDoConsistency )
       
   707                 {
       
   708                 res = EntryConsistency( entry,
       
   709                                           aAppArchList,
       
   710                                           aAppArchListFlags,
       
   711                                           aInstalledListForDrive,
       
   712                                           aInstalledListForDriveFlags,
       
   713                                           aDriveUnit,
       
   714                                           aDirtyFlag );
       
   715                 }
       
   716             if ( NULL != res )
       
   717                 {
       
   718                 TRAP( error, InsertL( entry ) );
       
   719                 if ( KErrNone != error )
       
   720                     {
       
   721                     CleanupStack::PopAndDestroy( entry );
       
   722                     }
       
   723                 else
       
   724                     {
       
   725                     __ASSERT_DEBUG( res == entry, User::Invariant() );
       
   726                     // Entry was inserted successfully.
       
   727                     CleanupStack::Pop( entry );
       
   728                     // add uid to AppArchList if not there,
       
   729                     // this can happend due to UID
       
   730                     // reallocation for UID collision resolution
       
   731                     TInt uidInt = (*entry)[EUid];
       
   732                     if ( aDoConsistency &&
       
   733                          ( KErrNotFound
       
   734                            == aAppArchList.Find(TUid::Uid(uidInt)) ) )
       
   735                         {
       
   736                         User::LeaveIfError( aAppArchList.Append( TUid::Uid(uidInt) ) );
       
   737                         User::LeaveIfError( aAppArchListFlags.Append( EAppListFlagEntry ) );
       
   738                         }
       
   739                     LOG2( " entry 0x%x (%d) added to registry",
       
   740                               uidInt, uidInt );
       
   741                     }
       
   742                 }
       
   743             }
       
   744         else
       
   745             {
       
   746             // entry error
       
   747             CleanupStack::PopAndDestroy( entry );
       
   748             }
       
   749         } // for
       
   750 
       
   751     CleanupStack::PopAndDestroy( 2, &file ); // readStream, file
       
   752     }
       
   753 
       
   754 // ============================================================================
       
   755 // CWidgetRegistry::InternalizeXmlL()
       
   756 // Read entry info from data file into memory
       
   757 //
       
   758 // @since 5.0
       
   759 // ============================================================================
       
   760 //
       
   761 void CWidgetRegistry::InternalizeXmlL( const TDesC& aFileName,
       
   762                                        const TDriveUnit& aDriveUnit,
       
   763                                        TBool aDoConsistency,
       
   764                                        RArray<TUid>& aAppArchList,
       
   765                                        RArray<TInt>& aAppArchListFlags,
       
   766                                        const CDir* aInstalledListForDrive,
       
   767                                        RArray<TInt>& aInstalledListForDriveFlags,
       
   768                                        TBool& aDirtyFlag )
       
   769     {
       
   770     LOG( "InternalizeXmlL" );
       
   771     RFile file;
       
   772     User::LeaveIfError( file.Open( iFs, aFileName, EFileRead ) );
       
   773     CleanupClosePushL( file );
       
   774 
       
   775     TInt size;
       
   776     User::LeaveIfError( file.Size( size ) );
       
   777     HBufC8* buf = HBufC8::NewLC( size );
       
   778     TPtr8 bufPtr( buf->Des() );
       
   779     User::LeaveIfError( file.Read( bufPtr ) );
       
   780 
       
   781     // initialize the parser and check compiled code matches lib version
       
   782     LIBXML_TEST_VERSION
       
   783 
       
   784     xmlDocPtr doc; // resulting document tree
       
   785 
       
   786     doc = xmlReadMemory( (const char *)bufPtr.Ptr(), bufPtr.Length(),
       
   787                          NULL, // no base URL
       
   788                          NULL, // get encoding from doc
       
   789                          0); // options
       
   790 
       
   791     if ( !doc )
       
   792         {
       
   793         LOG( " leaving: parse failed XML corrupt" );
       
   794         User::Leave( KErrCorrupt );
       
   795         }
       
   796     
       
   797     //TCleanupItem item( XmlDocFree, doc );
       
   798     //CleanupStack::PushL( item );
       
   799     xmlNode* rootElement = xmlDocGetRootElement( doc );
       
   800     TPtrC8 rootTag( rootElement->name );
       
   801     if ( 0 != rootTag.Compare( KWidgetRegistry() ) )
       
   802     {
       
   803         LOG( " leaving: XML root element mismatch" );
       
   804         User::Leave( KErrCorrupt );
       
   805     }
       
   806 
       
   807     for ( xmlNode* n = rootElement->children;
       
   808           n;
       
   809           n = n->next )
       
   810         {
       
   811         if ( n->type == XML_ELEMENT_NODE )
       
   812             {
       
   813             TPtrC8 element( n->name );
       
   814 
       
   815             if ( 0 == element.Compare( KEntry() ) )
       
   816                 {
       
   817                 if ( NULL == n->children )
       
   818                     {
       
   819                     // malformed? should we require entry to have
       
   820                     // some minimal info?
       
   821                     continue;
       
   822                     }
       
   823                 CWidgetEntry* entry = CWidgetEntry::NewL();
       
   824                 CleanupStack::PushL( entry );
       
   825 
       
   826                 // extract one entry
       
   827                 TRAPD( error,
       
   828                        entry->InternalizeXmlL( iFs, doc, n->children,
       
   829                                                iXmlProcessor ) );
       
   830                 LOG2( " entry 0x%x read from XML with error %d",
       
   831                           (error == KErrNone)? (*entry)[EUid] : 0,
       
   832                           error );
       
   833                 if ( KErrNone == error )
       
   834                     {
       
   835                     if ( aDoConsistency )
       
   836                         {
       
   837                         entry = EntryConsistency( entry,
       
   838                                                   aAppArchList,
       
   839                                                   aAppArchListFlags,
       
   840                                                   aInstalledListForDrive,
       
   841                                                   aInstalledListForDriveFlags,
       
   842                                                   aDriveUnit,
       
   843                                                   aDirtyFlag );
       
   844                         }
       
   845                     if ( NULL != entry )
       
   846                         {
       
   847                         TRAP( error, InsertL( entry ) );
       
   848                         if ( KErrNone != error )
       
   849                             {
       
   850                             delete entry;
       
   851                             }
       
   852                         else
       
   853                             {
       
   854                             entry->SetBlanketPermission((*entry)[EBlanketPermGranted] );
       
   855                             // add uid to AppArchList if not there,
       
   856                             // this can happend due to UID
       
   857                             // reallocation for UID collision resolution
       
   858                             TInt uidInt = (*entry)[EUid];
       
   859                             if ( aDoConsistency &&
       
   860                                  ( KErrNotFound
       
   861                                    == aAppArchList.Find(TUid::Uid(uidInt)) ) )
       
   862                                 {
       
   863                                 aAppArchList.Append( TUid::Uid(uidInt) );
       
   864                                 aAppArchListFlags.Append( EAppListFlagEntry );
       
   865                                 }
       
   866                             LOG2( " entry 0x%x (%d) added to registry",
       
   867                                       uidInt, uidInt );
       
   868                             }
       
   869                         }
       
   870                     }
       
   871                 else
       
   872                     {
       
   873                     // entry error
       
   874                     delete entry;
       
   875                     LOG( " entry internalize failed" );
       
   876                     }
       
   877 
       
   878                 CleanupStack::Pop(); //entry
       
   879                 } // if <entry>
       
   880             } // if n is element
       
   881         } // for
       
   882 
       
   883     xmlFreeDoc( doc );
       
   884     xmlCleanupParser();
       
   885 
       
   886     CleanupStack::PopAndDestroy( 2, &file ); // buf, file
       
   887     }
       
   888 
       
   889 // ============================================================================
       
   890 // CWidgetRegistry::ExternalizeL()
       
   891 // Write entry info in memory into data file
       
   892 //
       
   893 // @since 3.1
       
   894 // ============================================================================
       
   895 //
       
   896 void CWidgetRegistry::ExternalizeL()
       
   897     {
       
   898     // in order to have a list of all entries for a particular drive,
       
   899     // create a hash map from the entries with the key as drive name
       
   900     // and value as an array of entry indices for that drive
       
   901     RPtrHashMap< TInt, CArrayFixFlat<TInt> > driveEntryHashMap;
       
   902     CleanupClosePushL( driveEntryHashMap );
       
   903 
       
   904     for (TInt i = 0 ;i < iEntries.Count(); i++)
       
   905         {
       
   906         CWidgetEntry* entry = iEntries[i];
       
   907         const TDesC& driveName = (*entry)[EDriveName];
       
   908         TDriveUnit driveUnit( driveName );
       
   909         CArrayFixFlat<TInt>* array =
       
   910             driveEntryHashMap.Find( driveUnit );
       
   911         if( !array )
       
   912            {
       
   913            TInt* driveNo = new (ELeave) TInt( driveUnit );
       
   914            CArrayFixFlat<TInt>* drArray = new (ELeave) CArrayFixFlat<TInt>(1);
       
   915             CleanupStack::PushL( drArray );
       
   916            drArray->AppendL(i);
       
   917            driveEntryHashMap.Insert(driveNo, drArray);
       
   918            }
       
   919         else
       
   920            {
       
   921            array->AppendL(i);
       
   922            }
       
   923         }
       
   924 
       
   925     // List all drives in the system
       
   926     TDriveList driveList;
       
   927     User::LeaveIfError( iFs.DriveList(driveList) );
       
   928 
       
   929     // Check all drives
       
   930     for ( TInt driveNumber = EDriveA; driveNumber <= EDriveZ; driveNumber++ )
       
   931         {
       
   932         // The drives that will be filtered out are the same ones that
       
   933         // WidgetInstaller filters out in CWidgetUIHandler::SelectDriveL()
       
   934         if ( (EDriveD == driveNumber)
       
   935              || !driveList[driveNumber] )
       
   936             {
       
   937             // EDriveD is a temporary drive, usually a RAM disk
       
   938             continue;
       
   939             }
       
   940 
       
   941         TVolumeInfo volInfo;
       
   942         if ( iFs.Volume( volInfo, driveNumber ) != KErrNone )
       
   943             {
       
   944             // The volume is not usable (e.g. no media card inserted)
       
   945             continue;
       
   946             }
       
   947         if ( (volInfo.iDrive.iType == EMediaNotPresent) ||
       
   948              (volInfo.iDrive.iType == EMediaRom) ||
       
   949              (volInfo.iDrive.iType == EMediaRemote) ||
       
   950              (volInfo.iDrive.iDriveAtt & KDriveAttRom) ||
       
   951              (volInfo.iDrive.iDriveAtt & KDriveAttSubsted) )
       
   952             {
       
   953             continue;
       
   954             }
       
   955 
       
   956         // found a usable drive
       
   957         TDriveUnit driveUnit( driveNumber );
       
   958 
       
   959         // redirect paths to this drive
       
   960         iRegistryBinaryFileName[0] = driveUnit.Name()[0];
       
   961         iRegistryXmlFileName[0] = iRegistryBinaryFileName[0];
       
   962         iRegistryXmlTempFileName[0] = iRegistryBinaryFileName[0];
       
   963 
       
   964         const CArrayFixFlat<TInt>* indices =
       
   965             driveEntryHashMap.Find( driveNumber );
       
   966         if ( NULL == indices )
       
   967             {
       
   968             // not in hash map, delete any existing versions
       
   969             BaflUtils::DeleteFile( iFs, iRegistryBinaryFileName );
       
   970             BaflUtils::DeleteFile( iFs, iRegistryXmlFileName );
       
   971             BaflUtils::DeleteFile( iFs, iRegistryXmlTempFileName );
       
   972             }
       
   973         else
       
   974             {
       
   975             iFs.CreatePrivatePath( driveUnit );
       
   976 
       
   977             // a transactional file update to protect against
       
   978             // disk full, etc: overwrite temp then rename temp to original
       
   979 
       
   980             TRAPD( error,
       
   981                    ExternalizeXmlL( iRegistryXmlTempFileName, indices ) );
       
   982             if ( KErrNone == error )
       
   983                 {
       
   984                 // last steps in transactional update
       
   985                 BaflUtils::DeleteFile( iFs, iRegistryXmlFileName );
       
   986                 BaflUtils::RenameFile( iFs,
       
   987                                        iRegistryXmlTempFileName,
       
   988                                        iRegistryXmlFileName );
       
   989                 }
       
   990             else // handle leave by deleting temp file
       
   991                 {
       
   992                 BaflUtils::DeleteFile( iFs, iRegistryXmlTempFileName );
       
   993                 }
       
   994             }
       
   995         }
       
   996 
       
   997     for ( TInt i = 0; i < driveEntryHashMap.Count(); i++ )
       
   998         {
       
   999         CleanupStack::Pop();
       
  1000         }
       
  1001     CleanupStack::Pop( &driveEntryHashMap );
       
  1002     driveEntryHashMap.ResetAndDestroy();
       
  1003     driveEntryHashMap.Close();
       
  1004     }
       
  1005 
       
  1006 // ============================================================================
       
  1007 // CWidgetRegistry::ExternalizeBinaryL
       
  1008 // Externalize Binary file
       
  1009 //
       
  1010 // @since 3.1
       
  1011 // ============================================================================
       
  1012 //
       
  1013 void CWidgetRegistry::ExternalizeBinaryL( const TDesC& aFilename,
       
  1014                                           const CArrayFixFlat<TInt>* aIndices )
       
  1015     {
       
  1016     RFileWriteStream writeStream;
       
  1017     CleanupClosePushL( writeStream );
       
  1018 
       
  1019     RFile file;
       
  1020     User::LeaveIfError( file.Replace( iFs, aFilename, EFileWrite ) );
       
  1021     CleanupClosePushL( file );
       
  1022     writeStream.Attach( file );
       
  1023     writeStream.WriteInt32L( aIndices->Count() );
       
  1024     for ( TInt i = 0; i < aIndices->Count() ; i++ )
       
  1025         {
       
  1026         TInt pos = (*aIndices)[i];
       
  1027         CWidgetEntry* entry = iEntries[pos];
       
  1028         if(entry)
       
  1029             {
       
  1030             TRAPD( error, entry->ExternalizeBinaryL( writeStream ) );
       
  1031             if ( KErrNone != error )
       
  1032                 {
       
  1033                 // TODO how to recover from error?
       
  1034                 continue;
       
  1035                 }
       
  1036             }
       
  1037         }
       
  1038     writeStream.CommitL();
       
  1039     CleanupStack::PopAndDestroy(2);
       
  1040     }
       
  1041 
       
  1042 // ============================================================================
       
  1043 // CWidgetRegistry::ExternalizeXmlL
       
  1044 //
       
  1045 // @since 3.1
       
  1046 // ============================================================================
       
  1047 //
       
  1048 void CWidgetRegistry::ExternalizeXmlL( const TDesC& aFilename,
       
  1049                                        const CArrayFixFlat<TInt>* aIndices )
       
  1050     {
       
  1051     // sequence: write XML header, write each entry including
       
  1052     // unrecognized XML, write closing XML
       
  1053 
       
  1054     RFileWriteStream writeStream;
       
  1055     CleanupClosePushL( writeStream );
       
  1056 
       
  1057     RFile file;
       
  1058     User::LeaveIfError( file.Replace( iFs, aFilename, EFileWrite ) );
       
  1059     CleanupClosePushL( file );
       
  1060     writeStream.Attach( file );
       
  1061 
       
  1062     // write XML header
       
  1063     TInt bom = 0xfeff; // byte-order mark
       
  1064     writeStream.WriteInt16L( bom );
       
  1065     writeStream.WriteL( KXmlHeader );
       
  1066     writeStream.WriteL( KXmlNewline );
       
  1067     writeStream.WriteL( KXmlRootStart );
       
  1068     writeStream.WriteL( KXmlNewline );
       
  1069 
       
  1070     for ( TInt i = 0; i < aIndices->Count() ; i++ )
       
  1071         {
       
  1072         TInt pos = (*aIndices)[i];
       
  1073         CWidgetEntry* entry = iEntries[pos];
       
  1074         if ( entry )
       
  1075             {
       
  1076             writeStream.WriteL( KWidgetEntryStart );
       
  1077             writeStream.WriteL( KXmlNewline );
       
  1078             // TODO handle unrecognized XML from internalize
       
  1079             TRAPD( error, entry->ExternalizeXmlL( writeStream,
       
  1080                                                   iXmlProcessor,
       
  1081                                                   iFs) );
       
  1082             writeStream.WriteL( KWidgetEntryEnd );
       
  1083             writeStream.WriteL( KXmlNewline );
       
  1084             if ( KErrNone != error )
       
  1085                 {
       
  1086                 // TODO how to recover from error?
       
  1087                 continue;
       
  1088                 }
       
  1089             }
       
  1090         }
       
  1091 
       
  1092     writeStream.WriteL( KXmlRootEnd );
       
  1093     writeStream.WriteL( KXmlNewline );
       
  1094     writeStream.CommitL();
       
  1095 
       
  1096     CleanupStack::PopAndDestroy( 2 ); // file, writeStream
       
  1097     }
       
  1098 
       
  1099 // ============================================================================
       
  1100 // CWidgetRegistry::RegisterWidget()
       
  1101 // Creates CWidgetEntry
       
  1102 //
       
  1103 // @since 3.1
       
  1104 // ============================================================================
       
  1105 //
       
  1106 void CWidgetRegistry::RegisterWidgetL( RReadStream& aStream )
       
  1107     {
       
  1108     CWidgetEntry* entry = CWidgetEntry::NewL();
       
  1109     CleanupStack::PushL( entry );
       
  1110 
       
  1111     entry->InternalizeBinaryL( aStream );
       
  1112     InsertL( entry );
       
  1113 
       
  1114     CleanupStack::Pop(); //entry
       
  1115     ExternalizeL();
       
  1116 
       
  1117     //Notify WRT Harvester that widget registry has changed
       
  1118     NotifyWidgetAltered();
       
  1119     }
       
  1120 
       
  1121 // ============================================================================
       
  1122 // CWidgetRegistry::IsWidget()
       
  1123 // Returns true if the Uid falls within the range specified for widgets
       
  1124 //
       
  1125 // @since 3.1
       
  1126 // ============================================================================
       
  1127 //
       
  1128 TBool CWidgetRegistry::IsWidget( const TUid& aUid ) const
       
  1129     {
       
  1130     if ( ( aUid.iUid >= KWidgetUidLowerBound ) &&
       
  1131         ( aUid.iUid <= KWidgetUidUpperBound ) )
       
  1132         {
       
  1133         return ETrue;
       
  1134         }
       
  1135     else
       
  1136         {
       
  1137         return EFalse;
       
  1138         }
       
  1139 
       
  1140     }
       
  1141 
       
  1142 // ============================================================================
       
  1143 // CWidgetRegistry::WidgetExists()
       
  1144 // Returns true if the widget is installed
       
  1145 //
       
  1146 // @since 3.1
       
  1147 // ============================================================================
       
  1148 //
       
  1149 TBool CWidgetRegistry::WidgetExists( const TDesC& aWidgetId ) const
       
  1150     {
       
  1151     CWidgetEntry* entry = NULL;
       
  1152     TInt pos = GetWidgetEntry( TPtrC( aWidgetId ), entry );
       
  1153     return ( pos != -1 )?  ETrue : EFalse;
       
  1154     }
       
  1155 
       
  1156 // ============================================================================
       
  1157 // CWidgetRegistry::IsWidgetRunning()
       
  1158 // Returns true if the widget is running
       
  1159 //
       
  1160 // @since 3.1
       
  1161 // ============================================================================
       
  1162 //
       
  1163 TBool CWidgetRegistry::IsWidgetRunning( const TUid& aUid ) const
       
  1164     {
       
  1165     TBool active = EFalse;
       
  1166     CWidgetEntry* entry = NULL;
       
  1167 
       
  1168     GetWidgetEntry( aUid, entry );
       
  1169     if ( entry && entry->ActiveL() )
       
  1170         {
       
  1171         active = ETrue;
       
  1172         }
       
  1173     return active;
       
  1174     }
       
  1175 
       
  1176 // ============================================================================
       
  1177 // CWidgetRegistry::WidgetSapiAccessState()
       
  1178 // Returns sapi widget access state
       
  1179 //
       
  1180 // @since 5.0
       
  1181 // ============================================================================
       
  1182 //
       
  1183 TInt CWidgetRegistry::WidgetSapiAccessState( const TUid& aUid ) const
       
  1184     {
       
  1185     CWidgetEntry* entry = NULL;
       
  1186 
       
  1187     GetWidgetEntry( aUid, entry );
       
  1188     if ( entry)
       
  1189         {
       
  1190         return entry->SapiAccessState();
       
  1191         }
       
  1192     return -1;
       
  1193     }
       
  1194 
       
  1195 // ============================================================================
       
  1196 // CWidgetRegistry::IsWidgetInMiniView()
       
  1197 // Returns true if the widget is in miniview
       
  1198 //
       
  1199 // @since 5.0
       
  1200 // ============================================================================
       
  1201 //
       
  1202 TBool CWidgetRegistry::IsWidgetInMiniView( const TUid& aUid ) const
       
  1203     {
       
  1204     TBool state = EFalse;
       
  1205     CWidgetEntry* entry = NULL;
       
  1206 
       
  1207     GetWidgetEntry( aUid, entry );
       
  1208     if ( entry && entry->GetMiniViewState())
       
  1209         {
       
  1210         state = ETrue;
       
  1211         }
       
  1212     return state;
       
  1213     }
       
  1214 
       
  1215 // ============================================================================
       
  1216 // CWidgetRegistry::IsWidgetInFullView()
       
  1217 // Returns true if the widget is in miniview
       
  1218 //
       
  1219 // @since 5.0
       
  1220 // ============================================================================
       
  1221 //
       
  1222 TBool CWidgetRegistry::IsWidgetInFullView( const TUid& aUid ) const
       
  1223     {
       
  1224     TBool state = EFalse;
       
  1225     CWidgetEntry* entry = NULL;
       
  1226 
       
  1227     GetWidgetEntry( aUid, entry );
       
  1228     if ( entry && entry->GetFullViewState())
       
  1229         {
       
  1230         state = ETrue;
       
  1231         }
       
  1232     return state;
       
  1233     }
       
  1234 
       
  1235 TBool CWidgetRegistry::IsBlanketPermGranted( const TUid& aUid ) const
       
  1236     {
       
  1237     TBool state = EFalse;
       
  1238     CWidgetEntry* entry = NULL;
       
  1239 
       
  1240     GetWidgetEntry( aUid, entry );
       
  1241     if ( entry && entry->GetBlanketPermGranted())
       
  1242         {
       
  1243         state = ETrue;
       
  1244         }
       
  1245     return state;
       
  1246     }
       
  1247 
       
  1248 // ============================================================================
       
  1249 // CWidgetRegistry::InstalledWidgets()
       
  1250 // Returns widget info for all the installed widgets
       
  1251 //
       
  1252 // @since 3.1
       
  1253 // ============================================================================
       
  1254 //
       
  1255 void CWidgetRegistry::InstalledWidgetsL( RWidgetInfoArray& aWidgetInfoArr )
       
  1256     {
       
  1257     for ( TInt pos = 0; pos < iEntries.Count(); pos++ )
       
  1258         {
       
  1259         CWidgetEntry* entry = iEntries[pos];
       
  1260         if(entry)
       
  1261             {
       
  1262             CWidgetInfo *info = new ( ELeave ) CWidgetInfo();
       
  1263             info->iUid = TUid::Uid( (*entry)[EUid] );
       
  1264             info->iFileSize = (*entry)[EFileSize];
       
  1265             *(info->iBundleName) = (*entry)[EBundleName];
       
  1266             *(info->iDriveName) = (*entry)[EDriveName];
       
  1267             aWidgetInfoArr.AppendL( info );
       
  1268             }
       
  1269         }
       
  1270     }
       
  1271 
       
  1272 // ============================================================================
       
  1273 // CWidgetRegistry::RunningWidgetsL()
       
  1274 // Returns widget info for all the running widgets
       
  1275 //
       
  1276 // @since 3.1
       
  1277 // ============================================================================
       
  1278 //
       
  1279 void CWidgetRegistry::RunningWidgetsL( RWidgetInfoArray& aWidgetInfoArr )
       
  1280     {
       
  1281     for ( TInt pos = 0; pos < iEntries.Count(); pos++ )
       
  1282         {
       
  1283         CWidgetEntry* entry = iEntries[pos];
       
  1284 
       
  1285         if ( entry && entry->ActiveL() )
       
  1286             {
       
  1287             CWidgetInfo* info = new ( ELeave ) CWidgetInfo();
       
  1288             info->iUid = TUid::Uid( (*entry)[EUid] );
       
  1289             info->iFileSize = (*entry)[EFileSize];
       
  1290             *(info->iBundleName) = (*entry)[EBundleName];
       
  1291             *(info->iDriveName) = (*entry)[EDriveName];
       
  1292             aWidgetInfoArr.AppendL( info );
       
  1293             }
       
  1294         }
       
  1295     }
       
  1296 
       
  1297 // ============================================================================
       
  1298 // CWidgetRegistry::DeRegisterWidgetL()
       
  1299 // Deregister the widget
       
  1300 //
       
  1301 // @since 3.1
       
  1302 // ============================================================================
       
  1303 //
       
  1304 void CWidgetRegistry::DeRegisterWidgetL( const TUid& aUid )
       
  1305     {
       
  1306     Remove( aUid );
       
  1307     ExternalizeL( );
       
  1308     //Notify WRT Harvester that widget registry has changed
       
  1309     NotifyWidgetAltered();
       
  1310     }
       
  1311 
       
  1312 // ============================================================================
       
  1313 // CWidgetRegistry::GetWidgetBundleId()
       
  1314 // Returns bundleId of the widget with a particular UId.
       
  1315 //
       
  1316 // @since 3.1
       
  1317 // ============================================================================
       
  1318 //
       
  1319 void CWidgetRegistry::GetWidgetBundleId( const TUid& aUid, TDes& aBundleId )
       
  1320     {
       
  1321     CWidgetEntry* entry = NULL;
       
  1322     TInt pos = GetWidgetEntry( aUid, entry );
       
  1323 
       
  1324     if ( pos != -1 )
       
  1325         {
       
  1326         const TDesC& widgetBundleId = (*entry)[EBundleIdentifier];
       
  1327         aBundleId.Copy( widgetBundleId );
       
  1328         aBundleId.SetLength( widgetBundleId.Length() );
       
  1329         }
       
  1330     else
       
  1331         {
       
  1332         aBundleId.SetLength( 0 );
       
  1333         }
       
  1334     }
       
  1335 
       
  1336 // ============================================================================
       
  1337 // CWidgetRegistry::GetWidgetBundleName()
       
  1338 // Returns bundle display name of the widget with a particular UId.
       
  1339 //
       
  1340 // @since 3.1
       
  1341 // ============================================================================
       
  1342 //
       
  1343 void CWidgetRegistry::GetWidgetBundleName( const TUid& aUid, TDes& aBundleName )
       
  1344     {
       
  1345     CWidgetEntry* entry = NULL;
       
  1346     TInt pos = GetWidgetEntry( aUid, entry );
       
  1347 
       
  1348     if ( pos != -1 )
       
  1349         {
       
  1350         const TDesC& widgetBundleName = (*entry)[EBundleName];
       
  1351         aBundleName.Copy( widgetBundleName );
       
  1352         aBundleName.SetLength( widgetBundleName.Length() );
       
  1353         }
       
  1354     else
       
  1355         {
       
  1356         aBundleName.SetLength( 0 );
       
  1357         }
       
  1358     }
       
  1359 
       
  1360 // ============================================================================
       
  1361 // CWidgetRegistry::GetWidgetPropertyValueL()
       
  1362 // return serialized value of property aId for the widget aUid or leave
       
  1363 //
       
  1364 // @since 3.1
       
  1365 // ============================================================================
       
  1366 //
       
  1367 CBufFlat* CWidgetRegistry::GetWidgetPropertyValueL(
       
  1368     const TUid& aUid,
       
  1369     TWidgetPropertyId aId,
       
  1370     TInt aMaxLength )
       
  1371     {
       
  1372     CWidgetEntry& entry = GetWidgetEntryL( aUid );
       
  1373     CBufFlat* buf = CBufFlat::NewL( aMaxLength );
       
  1374     CleanupStack::PushL( buf );
       
  1375     RBufWriteStream stream( *buf ); // stream over the buffer
       
  1376     CleanupClosePushL( stream );
       
  1377 
       
  1378     // TBD safe array indexing (leave if out of range)
       
  1379     entry[aId].SerializeL( stream ); // serialize
       
  1380 
       
  1381     CleanupStack::PopAndDestroy( &stream );
       
  1382     CleanupStack::Pop(); // buf
       
  1383     return buf;
       
  1384     }
       
  1385 
       
  1386 // ============================================================================
       
  1387 // CWidgetRegistry::GetWidgetPath()
       
  1388 // Returns path of the widget with a particular UId.
       
  1389 //
       
  1390 // @since 3.1
       
  1391 // ============================================================================
       
  1392 //
       
  1393 void CWidgetRegistry::GetWidgetPath( const TUid& aUid, TDes& aPath )
       
  1394     {
       
  1395     CWidgetEntry* entry = NULL;
       
  1396     TInt pos = GetWidgetEntry( aUid, entry );
       
  1397 
       
  1398     if ( pos != -1 )
       
  1399         {
       
  1400         const TDesC& widgetBasePath = (*entry)[EBasePath];
       
  1401         aPath.Copy( widgetBasePath );
       
  1402         aPath.SetLength( widgetBasePath.Length() );
       
  1403         }
       
  1404     else
       
  1405         {
       
  1406         aPath.SetLength( 0 );
       
  1407         }
       
  1408     }
       
  1409 
       
  1410 // ============================================================================
       
  1411 // CWidgetRegistry::GetLprojName()
       
  1412 // Returns lproj name
       
  1413 //
       
  1414 // @since 3.1
       
  1415 // ============================================================================
       
  1416 //
       
  1417 void CWidgetRegistry::GetLprojNameL( TDes& aPath )
       
  1418     {
       
  1419     if ( !iLangDirList.Count() )
       
  1420         {
       
  1421         CreateLangDirListL();
       
  1422         }
       
  1423     HBufC8* lprojName = iLangDirList.Find( User::Language() );
       
  1424     if ( lprojName )
       
  1425         {
       
  1426         TPtr8 lprojNamePtr = lprojName->Des();
       
  1427         aPath.Copy( lprojNamePtr );
       
  1428         }
       
  1429     else
       
  1430         {
       
  1431         aPath.Copy( KWidgetDefaultLangDir );
       
  1432         }
       
  1433     }
       
  1434 
       
  1435 // ============================================================================
       
  1436 // CWidgetRegistry::GetWidgetUid()
       
  1437 // Returns UId of the widget with a particular bundle identifier
       
  1438 //
       
  1439 // @since 3.1
       
  1440 // ============================================================================
       
  1441 //
       
  1442 TUid CWidgetRegistry::GetWidgetUid( const TDesC& aBundleId ) const
       
  1443     {
       
  1444     CWidgetEntry* entry = NULL;
       
  1445     TInt pos = GetWidgetEntry( aBundleId, entry );
       
  1446 
       
  1447     if ( pos != -1 )
       
  1448         {
       
  1449         return TUid::Uid( (*entry)[EUid] );
       
  1450         }
       
  1451     else
       
  1452         {
       
  1453         return KNullUid;
       
  1454         }
       
  1455     }
       
  1456 
       
  1457 // ============================================================================
       
  1458 // CWidgetRegistry::GetWidgetUidForUrl()
       
  1459 // Returns uid of the widget with a patricular html path
       
  1460 //
       
  1461 // @since 3.1
       
  1462 // ============================================================================
       
  1463 //
       
  1464 TUid CWidgetRegistry::GetWidgetUidForUrl( const TDesC& aUrl ) const
       
  1465     {
       
  1466     for( TInt i = 0; i < iEntries.Count(); i++)
       
  1467         {
       
  1468         CWidgetEntry* entry = iEntries[i];
       
  1469 
       
  1470         if ( aUrl.CompareF( (*entry)[EMainHTML] ) == 0 )
       
  1471             {
       
  1472             return TUid::Uid( (*entry)[EUid] );
       
  1473             }
       
  1474         }
       
  1475     return KNullUid;
       
  1476     }
       
  1477 
       
  1478 // ============================================================================
       
  1479 // CWidgetRegistry::UsedUids()
       
  1480 // Returns array of used UIds
       
  1481 //
       
  1482 // @since 3.1
       
  1483 // ============================================================================
       
  1484 //
       
  1485 void CWidgetRegistry::UsedUidsL( RUidArray& aUsedUids )
       
  1486     {
       
  1487     for( TInt i = 0; i < iUsedUids.Count(); i++ )
       
  1488         {
       
  1489         aUsedUids.AppendL( iUsedUids[i] );
       
  1490         }
       
  1491     }
       
  1492 
       
  1493 // ============================================================================
       
  1494 // CWidgetRegistry::GetAvailableUidL()
       
  1495 // Get next availble uid from the pool using a random generation
       
  1496 //
       
  1497 // @since 3.1
       
  1498 // ============================================================================
       
  1499 //
       
  1500 TUid CWidgetRegistry::GetAvailableUidL( TInt aDriveLetter )
       
  1501     {
       
  1502     TUidAllocator uidAllocator;
       
  1503     return TUid::Uid( uidAllocator.AllocateL( iUsedUids, aDriveLetter ) );
       
  1504     }
       
  1505 
       
  1506 // ============================================================================
       
  1507 // CWidgetRegistry::SetActive()
       
  1508 // Set/Reset active status of the widget with a particular UId
       
  1509 //
       
  1510 // @since 3.1
       
  1511 // ============================================================================
       
  1512 //
       
  1513 void CWidgetRegistry::SetActive( TUid aUid, TInt aStatus )
       
  1514     {
       
  1515     CWidgetEntry* entry = NULL;
       
  1516     TInt pos = GetWidgetEntry( aUid, entry );
       
  1517     if ( pos != -1 )
       
  1518       {
       
  1519         entry->SetActive( aStatus );
       
  1520       }
       
  1521     }
       
  1522 
       
  1523 // ============================================================================
       
  1524 // CWidgetRegistry::SetMiniView()
       
  1525 // Set/Reset Widget status for launched in MiniView
       
  1526 //
       
  1527 // @since 5.0
       
  1528 // ============================================================================
       
  1529 //
       
  1530 void CWidgetRegistry::SetMiniView( TUid aUid, TInt aStatus )
       
  1531     {
       
  1532     CWidgetEntry* entry = NULL;
       
  1533     TInt pos = GetWidgetEntry( aUid, entry );
       
  1534     if ( pos != -1 )
       
  1535         {
       
  1536         entry->SetMiniView( aStatus );
       
  1537         }
       
  1538     }
       
  1539 
       
  1540 // ============================================================================
       
  1541 // CWidgetRegistry::SetFullView()
       
  1542 // Set/Reset Widget status in FullView
       
  1543 //
       
  1544 // @since 5.0
       
  1545 // ============================================================================
       
  1546 //
       
  1547 void CWidgetRegistry::SetFullView( TUid aUid, TInt aStatus )
       
  1548     {
       
  1549     CWidgetEntry* entry = NULL;
       
  1550     TInt pos = GetWidgetEntry( aUid, entry );
       
  1551     if ( pos != -1 )
       
  1552         {
       
  1553         entry->SetFullView( aStatus );
       
  1554         }
       
  1555     }
       
  1556 
       
  1557 // ============================================================================
       
  1558 // CWidgetRegistry::SetBlanketPermissionL()
       
  1559 // Set/Reset Widget Blanket Permission
       
  1560 //
       
  1561 // @since 5.0
       
  1562 // ============================================================================
       
  1563 //
       
  1564 void CWidgetRegistry::SetBlanketPermissionL( TUid aUid, TInt aStatus )
       
  1565     {
       
  1566     CWidgetEntry* entry = NULL;
       
  1567     TInt pos = GetWidgetEntry( aUid, entry );
       
  1568     if ( pos != -1 )
       
  1569         {
       
  1570         entry->SetBlanketPermission( aStatus );
       
  1571         }
       
  1572     ExternalizeL();
       
  1573     }
       
  1574 
       
  1575 // ============================================================================
       
  1576 // CWidgetRegistry::CreateLangDirListL()
       
  1577 // create the mapping table for language and lproj dir
       
  1578 //
       
  1579 // @since 3.1
       
  1580 // ============================================================================
       
  1581 //
       
  1582 void CWidgetRegistry::CreateLangDirListL()
       
  1583     {
       
  1584     TLanguage defaultLanguage = User::Language();
       
  1585     RFile file;
       
  1586     TFileName langDirFile;
       
  1587     iFs.PrivatePath( langDirFile );
       
  1588 #ifdef __WINSCW__
       
  1589     langDirFile.Insert( 0, _L( "C:" ));
       
  1590 #else
       
  1591     langDirFile.Insert( 0, _L( "Z:" ));
       
  1592 #endif
       
  1593     langDirFile.Append( KWidgetDirFile );
       
  1594     User::LeaveIfError( file.Open( iFs, langDirFile, EFileRead ) );
       
  1595     CleanupClosePushL( file );
       
  1596 
       
  1597     TInt size;
       
  1598     User::LeaveIfError( file.Size( size ) );
       
  1599     HBufC8* buf = HBufC8::NewLC( size );
       
  1600     TPtr8 bufPtr( buf->Des() );
       
  1601     User::LeaveIfError( file.Read( bufPtr ) );
       
  1602     CleanupStack::Pop( buf );
       
  1603     CleanupStack::PopAndDestroy( &file );
       
  1604     CleanupStack::PushL( buf );
       
  1605 
       
  1606     // initialize the parser and check compiled code matches lib version
       
  1607     LIBXML_TEST_VERSION
       
  1608 
       
  1609     xmlDocPtr doc; // resulting document tree
       
  1610 
       
  1611     doc = xmlReadMemory( (const char *)bufPtr.Ptr(), bufPtr.Length(),
       
  1612                          NULL, // no base URL
       
  1613                          NULL, // get encoding from doc
       
  1614                          0); // options
       
  1615 
       
  1616     if ( !doc )
       
  1617           {
       
  1618           User::Leave( KErrCorrupt );
       
  1619           }
       
  1620 
       
  1621     xmlNode* rootElement = xmlDocGetRootElement( doc );
       
  1622 
       
  1623     TInt* langID = NULL;
       
  1624     xmlNode* n;
       
  1625 
       
  1626     for ( n = rootElement; n; n = TraverseNextNode( n ) )
       
  1627         {
       
  1628         HBufC8* langDir;
       
  1629         if ( n->type == XML_ELEMENT_NODE )
       
  1630             {
       
  1631             TPtrC8 element( n->name );
       
  1632 
       
  1633             if ( element.Compare( KLangID() ) == 0 )
       
  1634                 {
       
  1635                 if ( n->children && n->children->type == XML_TEXT_NODE )
       
  1636                     {
       
  1637                     TPtrC8 content( n->children->content );
       
  1638                     langID = new TInt( atoi( (const char *)content.Ptr() ) );
       
  1639                     CleanupStack::PushL( langID );
       
  1640                     }
       
  1641                 }
       
  1642             if ( element.Compare( KLangDir() ) == 0 )
       
  1643                 {
       
  1644                 if ( n->children && n->children->type == XML_TEXT_NODE )
       
  1645                     {
       
  1646                         TPtrC8 content( n->children->content );
       
  1647                     langDir = HBufC8::NewLC( content.Length() );
       
  1648                     langDir->Des().Copy( content );
       
  1649                     if ( *langID <= 0 )
       
  1650                         {
       
  1651                         User::Leave( KErrCorrupt );
       
  1652                         }
       
  1653                     TInt* currentLangID = new TInt(*langID);
       
  1654                     CleanupStack::Pop(langDir);
       
  1655                     iLangDirList.Insert( currentLangID, langDir );
       
  1656                     *langID = 0;
       
  1657                     CleanupStack::PopAndDestroy(langID);
       
  1658                     langID = NULL;
       
  1659                     }
       
  1660                 }
       
  1661             }   // if n is element
       
  1662 
       
  1663         }   // for
       
  1664 
       
  1665     xmlFreeDoc(doc);
       
  1666     xmlCleanupParser();
       
  1667     xmlCleanupGlobalData();
       
  1668     CleanupStack::PopAndDestroy( buf );
       
  1669     }
       
  1670 
       
  1671 TBool CWidgetRegistry::InstallDirWidgets(
       
  1672     const TDriveUnit& aDriveUnit,
       
  1673     CDir*& aInstalledListForDrive,
       
  1674     RArray<TInt>& aInstalledListForDriveFlags )
       
  1675     {
       
  1676     LOG( "InstallDirWidgets" );
       
  1677     TBool doConsistency = ETrue;
       
  1678     aInstalledListForDrive = NULL;
       
  1679     aInstalledListForDriveFlags.Reset();
       
  1680     iWidgetInstallPath[0] = aDriveUnit.Name()[0];
       
  1681     TInt error = iFs.GetDir( iWidgetInstallPath,
       
  1682                              KEntryAttDir | KEntryAttMatchExclusive,
       
  1683                              ESortNone,
       
  1684                              aInstalledListForDrive );
       
  1685     if ( KErrPathNotFound == error )
       
  1686         {
       
  1687         LOG( "install path not found" );
       
  1688         delete aInstalledListForDrive;
       
  1689         aInstalledListForDrive = NULL;
       
  1690         return doConsistency;
       
  1691         }
       
  1692     if ( KErrNone != error || NULL == aInstalledListForDrive )
       
  1693         {
       
  1694         delete aInstalledListForDrive;
       
  1695         aInstalledListForDrive = NULL;
       
  1696         doConsistency = EFalse;
       
  1697         LOG( "error listing install directory, doConsistency 0" );
       
  1698         }
       
  1699     else
       
  1700         {
       
  1701         TInt count =
       
  1702             ( (NULL == aInstalledListForDrive) ?
       
  1703               0 : aInstalledListForDrive->Count() );
       
  1704         if ( count )
       
  1705             {
       
  1706                 for ( TInt i = 0; i < aInstalledListForDrive->Count(); i++ )
       
  1707                     {
       
  1708                 error = aInstalledListForDriveFlags.Append( 0 );
       
  1709                     if ( KErrNone != error )
       
  1710                         {
       
  1711                         break;
       
  1712                         }
       
  1713                     }
       
  1714             if ( KErrNone != error )
       
  1715                 {
       
  1716                 doConsistency = EFalse;
       
  1717                 aInstalledListForDriveFlags.Reset();
       
  1718                 
       
  1719                 delete aInstalledListForDrive;
       
  1720                 aInstalledListForDrive = NULL;
       
  1721                 }
       
  1722             }
       
  1723         }
       
  1724     LOG_CODE( if ( aInstalledListForDrive ) )
       
  1725     LOG2( "InstallDirWidgets done count %d doConsistency %d",
       
  1726               aInstalledListForDrive->Count(),
       
  1727               (TInt)doConsistency );
       
  1728     LOG_CODE( else )
       
  1729     LOG1( "InstallDirWidgets return NULL list doConsistency %d",
       
  1730               (TInt)doConsistency );
       
  1731     return doConsistency;
       
  1732     }
       
  1733 
       
  1734 // a routine to build an array of widgets according to app arch app list
       
  1735 // returns NULL on error, otherwise a UID list (possibly with no entries)
       
  1736 TInt CWidgetRegistry::AppArchWidgetUids( RArray< TUid >& aUids )
       
  1737     {
       
  1738     LOG( "AppArchWidgetUids" );
       
  1739     TInt error = iAppArch.GetAllApps();
       
  1740     aUids.Reset();
       
  1741     if ( KErrNone != error )
       
  1742         {
       
  1743         LOG ( "AppArchWidgetUids done error NULL list" );
       
  1744         
       
  1745         return error;
       
  1746         }
       
  1747     TInt appArchWaitTotal = 0;
       
  1748     TApaAppInfo info;
       
  1749     do
       
  1750         {
       
  1751         error = iAppArch.GetNextApp( info );
       
  1752         if ( KErrNone == error )
       
  1753             {
       
  1754             if ( TUidAllocator::IsWidget( info.iUid ) )
       
  1755                 {
       
  1756                 LOG2( " widget uid 0x%x (%d)",
       
  1757                           (TUint)(info.iUid.iUid), info.iUid.iUid );
       
  1758                 error = aUids.Append( info.iUid );
       
  1759                 if ( KErrNone !=  error )
       
  1760                     {
       
  1761                     break;
       
  1762                     }
       
  1763                 }
       
  1764             continue;
       
  1765             }
       
  1766         else if ( RApaLsSession::EAppListInvalid == error )
       
  1767             {
       
  1768             if ( appArchWaitTotal > KAppArchTimeout )
       
  1769                 {
       
  1770                 LOG( " appArchWaitTotal > KAppArchTimeout" );
       
  1771                 break;
       
  1772                 }
       
  1773             appArchWaitTotal += KAppArchDelayInterval;
       
  1774             LOG1( " appArchWaitTotal %d", appArchWaitTotal );
       
  1775             User::After( KAppArchDelayInterval );
       
  1776             continue;
       
  1777             }
       
  1778         } while ( RApaLsSession::ENoMoreAppsInList != error );
       
  1779     if ( RApaLsSession::ENoMoreAppsInList != error )
       
  1780         {
       
  1781         aUids.Reset();
       
  1782         }
       
  1783     LOG_CODE( if ( aUids.Count() ) )
       
  1784     LOG1( "AppArchWidgetUids done widget count %d",
       
  1785               aUids.Count() );
       
  1786     LOG_CODE( else )
       
  1787     LOG( "AppArchWidgetUids done error NULL list" );
       
  1788 
       
  1789     return error;
       
  1790     }
       
  1791 
       
  1792 // if primary return bool is T then arg lists will be non NUll, else
       
  1793 // return bool will be F and arg lists will be NULL (error condition)
       
  1794 TBool CWidgetRegistry::AppArchWidgets( RArray<TUid>& aAppArchList,
       
  1795                                        RArray<TInt>& aAppArchListFlags )
       
  1796     {
       
  1797     TBool doConsistency = ETrue;
       
  1798     TInt error = AppArchWidgetUids( aAppArchList );
       
  1799     aAppArchListFlags.Reset();
       
  1800     // NULL means AppArchWidgetUids encountered an error
       
  1801     if ( error )
       
  1802         {
       
  1803         // doConsistency flase means there is an unrecoverable error
       
  1804         // in consistency logic
       
  1805         doConsistency = EFalse;
       
  1806         }
       
  1807     else
       
  1808         {
       
  1809         TInt error = KErrNone;
       
  1810         for ( TInt i = 0 ; i < aAppArchList.Count(); i++ )
       
  1811                 {
       
  1812             error = aAppArchListFlags.Append( 0 );
       
  1813                 if ( KErrNone != error )
       
  1814                     {
       
  1815                     break;
       
  1816                     }
       
  1817                 }
       
  1818     
       
  1819         if ( KErrNone != error )
       
  1820             {
       
  1821             doConsistency = EFalse;
       
  1822             aAppArchListFlags.Reset();
       
  1823             aAppArchList.Reset();
       
  1824             }
       
  1825         }
       
  1826     LOG_CODE( if ( aAppArchList.Count() ) )
       
  1827     LOG2( "AppArchWidgets done widgets count %d doConsistency %d",
       
  1828               aAppArchListFlags.Count(), (TInt)doConsistency );
       
  1829     LOG_CODE( else )
       
  1830     LOG1( "AppArchWidgets done error doConsistency %d",
       
  1831               (TInt)doConsistency );
       
  1832     return doConsistency;
       
  1833     }
       
  1834 
       
  1835 // when called: aAppArchList and Flags must not be
       
  1836 // NULL. aInstalledListForDrive and Flags may be NULL
       
  1837 CWidgetEntry* CWidgetRegistry::EntryConsistency(
       
  1838     CWidgetEntry* aEntry,
       
  1839     const RArray<TUid>& aAppArchList,
       
  1840     RArray<TInt>& aAppArchListFlags,
       
  1841     const CDir* aInstalledListForDrive,
       
  1842     RArray<TInt>& aInstalledListForDriveFlags,
       
  1843     const TDriveUnit& aDriveUnit,
       
  1844     TBool& aDirtyFlag )
       
  1845     {
       
  1846     LOG( "EntryConsistency" );
       
  1847     TInt error;
       
  1848     TBool inAppList;
       
  1849     TUid uid;
       
  1850 
       
  1851     if ( IsEntryInstalled( aEntry, aInstalledListForDrive,
       
  1852                            aInstalledListForDriveFlags ) )
       
  1853         {
       
  1854         error = IsEntryInAppList( aEntry,
       
  1855                                   aAppArchList,
       
  1856                                   aAppArchListFlags,
       
  1857                                   inAppList,
       
  1858                                   uid );
       
  1859         if ( ( inAppList == EFalse ) || ( KErrNone != error ) )
       
  1860             {
       
  1861             if ( KErrNone == error )
       
  1862                 {
       
  1863                 LOG( " entry not in AppArch" );
       
  1864                 // not in AppArch but may be using a UID already in
       
  1865                 // use (UID conflict)
       
  1866                 error =
       
  1867                     InternalizeEntryNewUidIfNeeded( aEntry, aDriveUnit );
       
  1868                 if ( KErrNone == error )
       
  1869                     {
       
  1870                     iInstaller->RenameIconFile( iFs, aEntry->Properties() );
       
  1871                     TInt uidInt = (*aEntry)[EUid];
       
  1872                     TRAP( error,
       
  1873                           iInstaller->RegisterWidgetL(
       
  1874                               (*aEntry)[EMainHTML],
       
  1875                               (*aEntry)[EBundleDisplayName],
       
  1876                               (*aEntry)[EIconPath],
       
  1877                               (*aEntry)[EDriveName],
       
  1878                               TUid::Uid( uidInt ) ) );
       
  1879                     if ( KErrNone == error )
       
  1880                         {
       
  1881                         LOG2( " registered widget 0x%x (%d)",
       
  1882                                   uidInt, uidInt );
       
  1883                         LOG( " registry dirty flag set" );
       
  1884                         aDirtyFlag = ETrue;
       
  1885                         }
       
  1886                     }
       
  1887                 }
       
  1888             // catches errors from several prior lines
       
  1889             if ( KErrNone != error )
       
  1890                 {
       
  1891                 // allocated uid hasn't been added to iUsedUid yet so
       
  1892                 // just delete entry
       
  1893 
       
  1894                 // on error don't put entry in registry
       
  1895                 LOG( " error entry deleted" );
       
  1896                 delete aEntry;
       
  1897                 aEntry = NULL;
       
  1898                 }
       
  1899             }
       
  1900         }
       
  1901     else
       
  1902         {
       
  1903         LOG( " entry is not installed" );
       
  1904         // entry is not installed, clean up app list if needed
       
  1905         error = IsEntryInAppList( aEntry,
       
  1906                                   aAppArchList,
       
  1907                                   aAppArchListFlags,
       
  1908                                   inAppList,
       
  1909                                   uid );
       
  1910         if ( ( (TInt)ETrue == inAppList ) && ( KErrNone == error ) )
       
  1911             {
       
  1912             LOG( " removing from AppArch" );
       
  1913             // there is nothing useful to do on error
       
  1914             TRAP_IGNORE( iInstaller->DeregisterWidgetL( uid ) );
       
  1915             }
       
  1916 
       
  1917         // don't put entry in registry
       
  1918         LOG( " entry deleted" );
       
  1919         delete aEntry;
       
  1920         aEntry = NULL;
       
  1921         aDirtyFlag = ETrue;
       
  1922         }
       
  1923     LOG( "EntryConsistency done " );
       
  1924     return aEntry;
       
  1925     }
       
  1926 
       
  1927 // aInstalledListForDrive and Flags may be NULL (meaning no installed widgets)
       
  1928 TBool CWidgetRegistry::IsEntryInstalled(
       
  1929     CWidgetEntry* aEntry,
       
  1930     const CDir* aInstalledListForDrive,
       
  1931     RArray<TInt>& aInstalledListForDriveFlags )
       
  1932     {
       
  1933     TBool result = EFalse;
       
  1934     // NULL is an expected input due to GetDir producing it for empty lists
       
  1935     if ( NULL != aInstalledListForDrive )
       
  1936         {
       
  1937         const TDesC& bundleIdentifier = (*aEntry)[EBundleIdentifier];
       
  1938         for ( TInt i = 0; i < aInstalledListForDrive->Count(); i++ )
       
  1939             {
       
  1940             if ( !((aInstalledListForDriveFlags)[i] & EInstallListFlagEntry ))
       
  1941                 {
       
  1942                 TEntry dirEntry = (*aInstalledListForDrive)[i];
       
  1943                 if ( 0 == bundleIdentifier.Compare( dirEntry.iName ) )
       
  1944                     {
       
  1945                     (aInstalledListForDriveFlags)[i] |= EInstallListFlagEntry;
       
  1946                     result = ETrue;
       
  1947                     break;
       
  1948                     }
       
  1949                 }
       
  1950             }
       
  1951         }
       
  1952     LOG1( "IsEntryInstalled result %d", (TInt)result );
       
  1953     return result;
       
  1954     }
       
  1955 
       
  1956 // aAppArchList and Flags must not be NULL but may be empty (0 count)
       
  1957 TInt CWidgetRegistry::IsEntryInAppList( CWidgetEntry* aEntry,
       
  1958                                         const RArray<TUid>& aAppArchList,
       
  1959                                         RArray<TInt>& aAppArchListFlags,
       
  1960                                         TBool& aInAppList,
       
  1961                                         TUid& uid )
       
  1962      {
       
  1963      // entry has uid and EMainHTML, appInfo has uid and iFullName,
       
  1964      // both should match exactly
       
  1965      TInt error = KErrNone;
       
  1966      aInAppList = EFalse;
       
  1967      for ( TInt i = 0; i < aAppArchList.Count(); i++ )
       
  1968          {
       
  1969          if ( !( (aAppArchListFlags)[i] & EAppListFlagEntry ) )
       
  1970              {
       
  1971              uid = aAppArchList[i];
       
  1972              TInt uidInt = (*aEntry)[EUid];
       
  1973              TUid uid2 = TUid::Uid( uidInt );
       
  1974              if ( uid == uid2 )
       
  1975                  {
       
  1976                  TApaAppInfo appInfo;
       
  1977                  error = iAppArch.GetAppInfo( appInfo, uid );
       
  1978                  if ( KErrNone == error )
       
  1979                      {
       
  1980                      const TDesC& mainHtml = (*aEntry)[EMainHTML];
       
  1981                      if ( 0 == mainHtml.Compare( appInfo.iFullName ) )
       
  1982                          {
       
  1983                          aAppArchListFlags[i] |= EAppListFlagEntry;
       
  1984                          aInAppList = ETrue;
       
  1985                          break;
       
  1986                          }
       
  1987                      }
       
  1988                  else
       
  1989                      {
       
  1990                      break;
       
  1991                      }
       
  1992                  }
       
  1993              }
       
  1994          }
       
  1995      LOG2( "IsEntryInAppList done %d error %d",
       
  1996            (TInt)aInAppList, error );
       
  1997      return error;
       
  1998      }
       
  1999 
       
  2000 // This will assign a new UID if the UID in the entry appears either
       
  2001 // in iUsedUids or a call to GetAppInfo returns some info (something
       
  2002 // is using the UID).  The new UID will *not* be placed in iUsedUids and
       
  2003 // GetAppInfo using the new UID will return KErrNotFound.
       
  2004 TInt CWidgetRegistry::InternalizeEntryNewUidIfNeeded(
       
  2005     CWidgetEntry* aEntry,
       
  2006     const TDriveUnit& aDriveUnit )
       
  2007     {
       
  2008     LOG( "InternalizeEntryNewUidIfNeeded" );
       
  2009     // entry has a uid but it may already be in use by another widget
       
  2010     // according to app arch or iUsedUids
       
  2011     TUidAllocator uidAllocator;
       
  2012     TInt upos = iUsedUids.Find( TUid::Uid( (*aEntry)[EUid] ) );
       
  2013     TApaAppInfo appInfo;
       
  2014     TInt error = iAppArch.GetAppInfo( appInfo, TUid::Uid( (*aEntry)[EUid] ) );
       
  2015     if ( KErrNotFound != upos || KErrNotFound != error )
       
  2016         {
       
  2017         LOG( " widget needs a new UID" );
       
  2018         LOG_CLOSE;
       
  2019         LOG_OPEN;
       
  2020         do
       
  2021             {
       
  2022             TInt uidInt = 0;
       
  2023             TRAP( error,
       
  2024                   uidInt = uidAllocator.AllocateL( iUsedUids,
       
  2025                                                    aDriveUnit.Name()[0] ) );
       
  2026             if ( KErrNone != error )
       
  2027                 {
       
  2028                 LOG(
       
  2029     "InternalizeEntryNewUidIfNeeded done error failed to allocate a new UID" );
       
  2030                 return KErrNotFound;
       
  2031                 }
       
  2032             TUid uid = TUid::Uid( uidInt );
       
  2033             error = iAppArch.GetAppInfo( appInfo, uid );
       
  2034             if ( KErrNotFound == error )
       
  2035                 {
       
  2036                 // use new uid (do icon mbm file rename elsewhere) and
       
  2037                 // don't add it to iUsedUids yet as that will be done
       
  2038                 // when entry is finally inserted in registry
       
  2039                 (*aEntry)[EUid] = uidInt;
       
  2040                 LOG2(
       
  2041   "InternalizeEntryNewUidIfNeeded done new uid is 0x%x (%d)", uidInt, uidInt );
       
  2042                 return KErrNone;
       
  2043                 }
       
  2044             else if ( KErrNone == error )
       
  2045                 {
       
  2046                 // don't allocate this uid because AppArch thinks it
       
  2047                 // is in use
       
  2048                 error = iUsedUids.Append( uid );
       
  2049                 }
       
  2050             } while ( KErrNone == error );
       
  2051         LOG(
       
  2052     "InternalizeEntryNewUidIfNeeded done error failed to allocate a new UID" );
       
  2053         return KErrNotFound;
       
  2054         }
       
  2055     LOG( "InternalizeEntryNewUidIfNeeded done widget already has a unique ID" );    LOG_CLOSE;
       
  2056     LOG_OPEN;
       
  2057     return KErrNone;
       
  2058     }
       
  2059 
       
  2060 
       
  2061 // this examines the installed widget list after the persistent
       
  2062 // registry entries have been processed for any installed widgets that
       
  2063 // don't yet have a registry entry.  An entry is generated and the
       
  2064 // widget is registered with app arch.
       
  2065 void CWidgetRegistry::InstallDirConsistency(
       
  2066     const CDir* aInstalledListForDrive,
       
  2067     RArray<TInt>& aInstalledListForDriveFlags,
       
  2068     TBool& aDirtyFlag )
       
  2069     {
       
  2070     LOG( "InstallDirConsistency" );
       
  2071     if ( NULL == aInstalledListForDrive
       
  2072          || ( ( NULL != aInstalledListForDrive)
       
  2073               && ( 0 == aInstalledListForDrive->Count() ) ) )
       
  2074         {
       
  2075         LOG( " nothing is installed" );
       
  2076         return;
       
  2077         }
       
  2078     TInt error = KErrNone;
       
  2079     TUidAllocator uidAllocator;
       
  2080     for ( TInt i = 0; i < aInstalledListForDrive->Count(); i++ )
       
  2081         {
       
  2082         if ( !( aInstalledListForDriveFlags[i] & EInstallListFlagEntry ) )
       
  2083             {
       
  2084             TFileName widgetPath( iWidgetInstallPath );
       
  2085             widgetPath.Append( (*aInstalledListForDrive)[i].iName );
       
  2086             widgetPath.Append( _L("\\") );
       
  2087             // assume directory under this is widget top-level dir
       
  2088             CDir *listing = NULL;
       
  2089             error = iFs.GetDir( widgetPath,
       
  2090                                 KEntryAttDir | KEntryAttMatchExclusive,
       
  2091                                 ESortNone,
       
  2092                                 listing );
       
  2093             if ( ( KErrNone != error )
       
  2094                  || ( 1 != listing->Count() ) )
       
  2095                 {
       
  2096                 // skip this widget
       
  2097                 LOG( " rejecting a directory that has unexpected contents" );
       
  2098                 delete listing;
       
  2099                 continue;
       
  2100                 }
       
  2101             LOG( " found inconsistency" );
       
  2102             widgetPath.Append( ((*listing)[0]).iName );
       
  2103             widgetPath.Append( _L("\\") );
       
  2104             delete listing;
       
  2105 
       
  2106             TInt uidInt = 0;
       
  2107             TRAP( error, uidInt =
       
  2108                   uidAllocator.AllocateL( iUsedUids,
       
  2109                                           iWidgetInstallPath[0] ) );
       
  2110             if ( KErrNone != error )
       
  2111                 {
       
  2112                 LOG1( " uid allocate error %d", error );
       
  2113                 continue; // skip this widget
       
  2114                 }
       
  2115 
       
  2116             LOG( " getting properties from installed widget" );
       
  2117             LOG_CLOSE;
       
  2118             LOG_OPEN;
       
  2119             RPointerArray<CWidgetPropertyValue>* tmp;
       
  2120             TRAP( error,
       
  2121                   tmp =
       
  2122                   iInstaller->WidgetPropertiesFromInstalledWidgetL(
       
  2123                       iFs, widgetPath, iLprojName, TUid::Uid( uidInt ) ) );
       
  2124             if ( KErrNone != error || !tmp )
       
  2125                 {
       
  2126                 LOG1( " props from installed widget error %d", error );
       
  2127                 continue; // skip this widget
       
  2128                 }
       
  2129             LOG( " got properties from installed widget" );
       
  2130             // transfer ownership of tmp
       
  2131             CWidgetEntry* entry = NULL;
       
  2132             TRAP( error, entry = CWidgetEntry::NewL( &tmp ) );
       
  2133             if ( KErrNone != error )
       
  2134                 {
       
  2135                 LOG1( " new entry copy ctor error %d", error );
       
  2136                 if ( tmp )
       
  2137                     {
       
  2138                     tmp->ResetAndDestroy();
       
  2139                     }
       
  2140                 continue; // skip this widget
       
  2141                 }
       
  2142             // app arch may have this widget under another uid
       
  2143             // but if we assign a new uid and register the
       
  2144             // widget then the duplicate app arch entry will
       
  2145             // be removed when app arch list is made
       
  2146             // consistent by removing entries not in the
       
  2147             // registry by uid
       
  2148 
       
  2149             // check that uid is unknown to app arch
       
  2150             TDriveUnit driveUnit( widgetPath );
       
  2151             error = InternalizeEntryNewUidIfNeeded( entry, driveUnit );
       
  2152             if ( KErrNone != error )
       
  2153                 {
       
  2154                 LOG1( " new uid if needed error %d", error );
       
  2155                 delete entry;
       
  2156                 continue; // skip this widget
       
  2157                 }
       
  2158             LOG_CODE( TInt uidLog = (*entry)[EUid] );
       
  2159             LOG1( " uid 0x%x", uidLog );
       
  2160             LOG_CODE( const TDesC& logDes = (*entry)[EMainHTML] );
       
  2161             LOG1( " mainHTML %S", &logDes );
       
  2162             LOG_CODE( const TDesC& logDes2 = (*entry)[EBundleDisplayName] );
       
  2163             LOG1( " bundleDiplayname %S", &logDes2 );
       
  2164 
       
  2165             TRAP( error,
       
  2166                   iInstaller->RegisterWidgetL(
       
  2167                       (*entry)[EMainHTML],
       
  2168                       (*entry)[EBundleDisplayName],
       
  2169                       (*entry)[EIconPath],
       
  2170                       (*entry)[EDriveName],
       
  2171                       TUid::Uid( (*entry)[EUid]) ) );
       
  2172 
       
  2173             if ( KErrNone == error )
       
  2174                 {
       
  2175                 LOG2( " registered widget 0x%x (%d)",
       
  2176                           uidLog, uidLog );
       
  2177                 TRAP( error,
       
  2178                       InsertL( entry ) );
       
  2179                 if ( KErrNone != error )
       
  2180                     {
       
  2181                     LOG1( " insert entry error %d", error );
       
  2182                     delete entry;
       
  2183                     continue; // skip this widget
       
  2184                     }
       
  2185                 LOG2( " entry 0x%x (%d) added to registry",
       
  2186                           uidLog, uidLog );
       
  2187                 LOG( "registry dirty flag set" );
       
  2188                 aDirtyFlag = ETrue;
       
  2189                 }
       
  2190             else
       
  2191                 {
       
  2192                 // allocated uid hasn't been added to iUsedUid yet so
       
  2193                 // just delete entry
       
  2194                 delete entry;
       
  2195                 LOG( "failed to recover an installed widget" );
       
  2196                 continue; // skip this widget
       
  2197                 }
       
  2198             }
       
  2199         }
       
  2200     LOG( "InstallDirConsistency done" );
       
  2201     }
       
  2202 
       
  2203 void CWidgetRegistry::AppArchListConsistency( const RArray<TUid>& aAppArchList,
       
  2204                                               RArray<TInt>& aAppArchListFlags )
       
  2205     {
       
  2206     LOG( "AppArchListConsistency" );
       
  2207     for ( TInt i = 0; i < aAppArchList.Count(); i++ )
       
  2208         {
       
  2209         if ( !( aAppArchListFlags[i] & EAppListFlagEntry ) )
       
  2210             {
       
  2211             LOG_CODE( TInt uidIntLog = aAppArchList[i].iUid );
       
  2212             LOG2( " deregistered widget 0x%x (%d)",
       
  2213                       uidIntLog, uidIntLog );
       
  2214             TRAP_IGNORE( iInstaller->DeregisterWidgetL( aAppArchList[i] ) );
       
  2215             }
       
  2216         }
       
  2217     LOG( "AppArchListConsistency done" );
       
  2218     }
       
  2219 
       
  2220 
       
  2221 // End of File