mmsharing/mmshui/src/musuiresourcehandler.cpp
branchRCL_3
changeset 33 bc78a40cd63c
equal deleted inserted replaced
32:73a1feb507fb 33:bc78a40cd63c
       
     1 /*
       
     2 * Copyright (c) 2007 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 "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:  Handler for camera, keypad and video player resources
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 #include "musuiresourcehandler.h"
       
    21 #include "musuipropertywatch.h"
       
    22 #include "musuieventobserver.h"
       
    23 #include "musuidialogutil.h"
       
    24 #include "muslogger.h"
       
    25 #include "mussettings.inl"
       
    26 
       
    27 #include <musui.rsg>
       
    28 #include <AknWaitDialog.h>
       
    29 #include <StringLoader.h>
       
    30 
       
    31 using namespace NMusResourceApi;
       
    32 
       
    33 
       
    34 // -----------------------------------------------------------------------------
       
    35 //
       
    36 // -----------------------------------------------------------------------------
       
    37 //
       
    38 CMusUiResourceHandler::~CMusUiResourceHandler()
       
    39     {    
       
    40     delete iCameraResourceWatch;
       
    41     delete iKeypadResourceWatch;
       
    42     
       
    43     delete iChangeProductModeDialog;
       
    44     delete iDialogPrompt;
       
    45     }
       
    46     
       
    47     
       
    48 // -----------------------------------------------------------------------------
       
    49 //
       
    50 // -----------------------------------------------------------------------------
       
    51 //
       
    52 CMusUiResourceHandler* CMusUiResourceHandler::NewL( 
       
    53                                             MMusUiEventObserver& aObserver )
       
    54     {
       
    55     MUS_LOG( "mus: [MUSUI ] -> CMusUiResourceHandler::NewL()" )
       
    56     
       
    57     CMusUiResourceHandler* self = 
       
    58                             new ( ELeave ) CMusUiResourceHandler( aObserver );
       
    59     CleanupStack::PushL( self );
       
    60     self->ConstructL();
       
    61     CleanupStack::Pop( self );
       
    62 
       
    63     MUS_LOG( "mus: [MUSUI ] <- CMusUiResourceHandler::NewL()" )
       
    64     return self;
       
    65     }
       
    66 
       
    67 
       
    68 // -----------------------------------------------------------------------------
       
    69 //
       
    70 // -----------------------------------------------------------------------------
       
    71 //
       
    72 TBool CMusUiResourceHandler::RequestKeypadL( TBool aMandatory )
       
    73     {
       
    74     MUS_LOG( "mus: [MUSUI ]  -> CMusUiResourceHandler::RequestKeypadL" )
       
    75     
       
    76     TBool keypadAvailable( EFalse ); 
       
    77     
       
    78     switch ( iKeypadAvailability )
       
    79         {        
       
    80         case NMusResourceApi::EAvailable:
       
    81             {
       
    82             MUS_LOG( "mus: [MUSUI ]     Keypad is available" )            
       
    83 		    break;		            
       
    84             }			         
       
    85         case NMusResourceApi::ENotAvailable:
       
    86             {
       
    87             MUS_LOG( "mus: [MUSUI ]     Keypad is not available, changing mode" )
       
    88             iKeypadAvailibilityInProgress = ETrue;
       
    89             delete iDialogPrompt;
       
    90             iDialogPrompt = NULL;
       
    91             iDialogPrompt = StringLoader::LoadL( R_MUS_CHANGE_KEYPAD_MODE_TXT );
       
    92             ShowChangeProductModeDialogL( *iDialogPrompt );            
       
    93             MUS_LOG( "                 Product mode changed" )
       
    94             MUS_LOG1( "                 Keypad availability is %d", 
       
    95                       iKeypadAvailability )            
       
    96             break;
       
    97             }
       
    98         default:
       
    99             {
       
   100             MUS_LOG( "mus: [MUSUI ]     availability default." )
       
   101             break;
       
   102             }
       
   103             
       
   104         }
       
   105         
       
   106     switch(iKeypadUsability)
       
   107     	{
       
   108     	case MusSettingsKeys::EUsabilityLandscape:
       
   109             {
       
   110             MUS_LOG( "mus: [MUSUI ]     Keypad is usable in landscape" )
       
   111             iObserver.SwitchOrientationL( 
       
   112                                     CAknAppUiBase::EAppUiOrientationLandscape );            
       
   113             break;
       
   114             }
       
   115         case MusSettingsKeys::EUsabilityPortrait:
       
   116             {
       
   117             MUS_LOG( "mus: [MUSUI ]     Keypad is usable in portrait" )
       
   118             iObserver.SwitchOrientationL( 
       
   119                                     CAknAppUiBase::EAppUiOrientationPortrait );            
       
   120             break;
       
   121             }	
       
   122     	case MusSettingsKeys::EUsabilityAlways:
       
   123     		{
       
   124     		MUS_LOG( "mus: [MUSUI ]     Keypad is usable in all mode" )
       
   125     		keypadAvailable = ETrue;	
       
   126     		}
       
   127     		break;
       
   128     	default:
       
   129     	  	MUS_LOG( "mus: [MUSUI ]     usuability default ." )
       
   130     	  	break;
       
   131     	}
       
   132     	
       
   133     keypadAvailable = IsCurrentlyAvailable( iKeypadAvailability,
       
   134 		                                    iKeypadUsability );
       
   135             
       
   136     if ( aMandatory && !keypadAvailable )
       
   137         {
       
   138         MUS_LOG( "mus: [MUSUI ]     Mandatory keypad not available, exiting" )
       
   139         MusUiDialogUtil::ShowGlobalInformationDialogL( 
       
   140                                 R_MUS_LIVE_SHARING_VIEW_NOTE_SHARING_ENDED );
       
   141         iObserver.HandleExit();
       
   142         }
       
   143     
       
   144     MUS_LOG1( "mus: [MUSUI ]  <- CMusUiResourceHandler::RequestKeypadL( %d )",
       
   145               keypadAvailable )
       
   146     
       
   147     return keypadAvailable;
       
   148     
       
   149     
       
   150     }
       
   151     
       
   152     
       
   153 // -----------------------------------------------------------------------------
       
   154 //
       
   155 // -----------------------------------------------------------------------------
       
   156 //
       
   157 TBool CMusUiResourceHandler::RequestCameraL( TBool aMandatory )
       
   158     {
       
   159     MUS_LOG( "mus: [MUSUI ]  -> CMusUiResourceHandler::RequestCameraL" )
       
   160     
       
   161     TBool cameraAvailable( EFalse );
       
   162     
       
   163     switch ( iCameraAvailability )
       
   164         {        
       
   165         case NMusResourceApi::EAvailable:
       
   166             {
       
   167             MUS_LOG( "mus: [MUSUI ]     Camera is available" )            
       
   168             cameraAvailable = ETrue;
       
   169             break;
       
   170             }
       
   171         
       
   172         case NMusResourceApi::ENotAvailable:
       
   173             {
       
   174             MUS_LOG( "mus: [MUSUI ]     Camera is not available, changing mode" )
       
   175 
       
   176             iCameraAvailibilityInProgress = ETrue;
       
   177             delete iDialogPrompt;
       
   178             iDialogPrompt = NULL;
       
   179             iDialogPrompt = StringLoader::LoadL(
       
   180                 R_MUS_LIVE_SHARING_VIEW_OPEN_CAMERA_LENS_COVER_WAIT_NOTE_TXT );
       
   181             ShowChangeProductModeDialogL( *iDialogPrompt );
       
   182             
       
   183             MUS_LOG( "                 Product mode changed" )
       
   184             MUS_LOG1( "                 Camera availability is %d", 
       
   185                       iCameraAvailability )                                  
       
   186             break;
       
   187             }
       
   188         default:
       
   189         	MUS_LOG( "mus: [MUSUI ]     availability default." )
       
   190             break;
       
   191         }
       
   192         
       
   193     switch(iCameraUsability)
       
   194     	{
       
   195     	case MusSettingsKeys::EUsabilityLandscape:
       
   196             {
       
   197             MUS_LOG( "mus: [MUSUI ]     Camera is usable in landscape" )
       
   198             iObserver.SwitchOrientationL( 
       
   199                                 CAknAppUiBase::EAppUiOrientationLandscape );            
       
   200             break;
       
   201             }
       
   202         case MusSettingsKeys::EUsabilityPortrait:
       
   203             {
       
   204             MUS_LOG( "mus: [MUSUI ]     Camera is usable in portrait" )
       
   205             iObserver.SwitchOrientationL( 
       
   206                                 CAknAppUiBase::EAppUiOrientationPortrait );           
       
   207             break;
       
   208             }	
       
   209         case MusSettingsKeys::EUsabilityAlways:
       
   210     		{
       
   211     		MUS_LOG( "mus: [MUSUI ]     camera is usable in all mode" )
       
   212     		cameraAvailable = ETrue;	
       
   213     		}
       
   214     	default:
       
   215             {
       
   216             MUS_LOG( "mus: [MUSUI ]     usuability default." )
       
   217             break;
       
   218             }
       
   219     	}
       
   220     
       
   221     cameraAvailable = IsCurrentlyAvailable( iCameraAvailability,
       
   222 		                                    iCameraUsability );
       
   223     if ( aMandatory && !cameraAvailable )
       
   224         {
       
   225         MUS_LOG( "mus: [MUSUI ]     Mandatory camera not available, exiting" )
       
   226         MusUiDialogUtil::ShowGlobalInformationDialogL( 
       
   227                                 R_MUS_LIVE_SHARING_VIEW_NOTE_SHARING_ENDED ); 
       
   228         iObserver.HandleExit();        
       
   229         }
       
   230     
       
   231     MUS_LOG1( "mus: [MUSUI ]  <- CMusUiResourceHandler::RequestCameraL( %d )",
       
   232               cameraAvailable )
       
   233         
       
   234     return cameraAvailable;
       
   235     }
       
   236  
       
   237 
       
   238 // -----------------------------------------------------------------------------
       
   239 //
       
   240 // -----------------------------------------------------------------------------
       
   241 //
       
   242 TBool CMusUiResourceHandler::RequestVideoPlayerL( TBool aMandatory )
       
   243     { 
       
   244     MUS_LOG( "mus: [MUSUI ]  -> CMusUiResourceHandler::RequestVideoPlayerL" )
       
   245     
       
   246     TBool videoPlayerAvailable( EFalse );
       
   247     
       
   248     /* Video Player will be always available. There is no dynamic variation */
       
   249     NMusResourceApi::TAvailability vpAvailability = NMusResourceApi::EAvailable;
       
   250     
       
   251     switch ( iVideoplayerUsability )
       
   252         {       
       
   253         case MusSettingsKeys::EUsabilityAlways:
       
   254             {
       
   255             MUS_LOG( "mus: [MUSUI ]     Video player is usuable in all mode" )            
       
   256             videoPlayerAvailable = ETrue;
       
   257             break;
       
   258             }
       
   259         case MusSettingsKeys::EUsabilityLandscape:
       
   260             {
       
   261             MUS_LOG( "mus: [MUSUI ]     Video player is usable in landscape" )
       
   262 
       
   263             iObserver.SwitchOrientationL( 
       
   264                                     CAknAppUiBase::EAppUiOrientationLandscape );
       
   265             videoPlayerAvailable = IsCurrentlyAvailable( vpAvailability,
       
   266                                                          iVideoplayerUsability );
       
   267             break;
       
   268             }
       
   269         case MusSettingsKeys::EUsabilityPortrait:
       
   270             {
       
   271             MUS_LOG( "mus: [MUSUI ]     Video player is usable in portrait" )
       
   272 
       
   273             iObserver.SwitchOrientationL( 
       
   274                                     CAknAppUiBase::EAppUiOrientationPortrait );
       
   275             videoPlayerAvailable = IsCurrentlyAvailable( vpAvailability,
       
   276                                                          iVideoplayerUsability );
       
   277             break;
       
   278             }        
       
   279         default:
       
   280             {
       
   281             MUS_LOG( "mus: [MUSUI ]     usuability default." )
       
   282             break;
       
   283             }
       
   284         }
       
   285     
       
   286     if ( aMandatory && !videoPlayerAvailable )
       
   287         {
       
   288         MUS_LOG( "mus: [MUSUI ]     Mandatory player not available, exiting" )
       
   289         MusUiDialogUtil::ShowGlobalInformationDialogL( 
       
   290                                 R_MUS_LIVE_SHARING_VIEW_NOTE_SHARING_ENDED );
       
   291         iObserver.HandleExit();
       
   292         }
       
   293         
       
   294     MUS_LOG1( "mus: [MUSUI ]  <- CMusUiResourceHandler::RequestVideoPlayerL(%d)",
       
   295               videoPlayerAvailable )
       
   296     
       
   297     return videoPlayerAvailable;
       
   298     }
       
   299 
       
   300 
       
   301 // -----------------------------------------------------------------------------
       
   302 // Called by CMusUiPropertyWatch, when resource key values change in P&S
       
   303 // -----------------------------------------------------------------------------
       
   304 //
       
   305 void CMusUiResourceHandler::PropertyChanged( const TUint aKey,
       
   306                                              const TInt aValue )
       
   307     {
       
   308     
       
   309     MUS_LOG2( "mus: [MUSUI ] -> CMusUiResourceHandler::ResourcePropertyChanged:\
       
   310               aKey: [%u] aValue: [%d]", aKey, aValue )
       
   311               
       
   312     switch( aKey )
       
   313         {
       
   314         case NMusResourceApi::KCameraAvailability:
       
   315             {
       
   316             MUS_LOG( "mus: [MUSUI ]  KCameraAvailability   " )            
       
   317             iCameraAvailability = static_cast< TAvailability >( aValue );
       
   318             if ( iCameraAvailibilityInProgress && iChangeProductModeDialog )
       
   319                 {
       
   320                 TRAP_IGNORE( iChangeProductModeDialog->ProcessFinishedL() );
       
   321                 }
       
   322             iCameraAvailibilityInProgress = EFalse;
       
   323             break;
       
   324             }
       
   325         case NMusResourceApi::KKeypadAvailability:
       
   326             {
       
   327             MUS_LOG( "mus: [MUSUI ]  KKeypadAvailability   " )            
       
   328             iKeypadAvailability = static_cast< TAvailability >( aValue );
       
   329             if ( iKeypadAvailibilityInProgress && iChangeProductModeDialog )
       
   330                 {
       
   331                 TRAP_IGNORE( iChangeProductModeDialog->ProcessFinishedL() );
       
   332                 }
       
   333             iKeypadAvailibilityInProgress = EFalse;
       
   334             break;
       
   335             }       
       
   336         default:
       
   337             {
       
   338             MUS_LOG( "mus: [MUSUI ]     avilability property watch default." )
       
   339             break;
       
   340             }
       
   341             
       
   342         }
       
   343         
       
   344     MUS_LOG( "mus: [MUSUI ]  <- CMusUiResourceHandler::ResourcePropertyChanged" )
       
   345     }
       
   346 
       
   347 
       
   348 // -----------------------------------------------------------------------------
       
   349 //
       
   350 // -----------------------------------------------------------------------------
       
   351 //
       
   352 void CMusUiResourceHandler::HandlePropertyError( const TInt aReason )
       
   353     {
       
   354     MUS_LOG( "mus: [MUSUI ] -> CMusUiResourceHandler::HandlePropertyError()" )
       
   355 
       
   356     iObserver.HandleError( aReason );
       
   357     }
       
   358 
       
   359 
       
   360 // -----------------------------------------------------------------------------
       
   361 // C++ constructor
       
   362 // -----------------------------------------------------------------------------
       
   363 //
       
   364 CMusUiResourceHandler::CMusUiResourceHandler( MMusUiEventObserver& aObserver )
       
   365     :iObserver( aObserver ),
       
   366      iCameraAvailability(NMusResourceApi::EAvailable),
       
   367      iKeypadAvailability(NMusResourceApi::EAvailable),
       
   368      iCameraUsability(MusSettingsKeys::EUsabilityAlways),
       
   369      iKeypadUsability(MusSettingsKeys::EUsabilityAlways),
       
   370      iVideoplayerUsability(MusSettingsKeys::EUsabilityAlways)
       
   371     {
       
   372     }
       
   373 
       
   374 
       
   375 // -----------------------------------------------------------------------------
       
   376 // Symbian second phase constructor
       
   377 // -----------------------------------------------------------------------------
       
   378 //
       
   379 void CMusUiResourceHandler::ConstructL()
       
   380     {
       
   381     MUS_LOG( "mus: [MUSUI ] -> CMusUiResourceHandler::ConstructL()" )
       
   382     
       
   383 	iCameraAvailibilityInProgress = EFalse;
       
   384     iKeypadAvailibilityInProgress = EFalse;     
       
   385              
       
   386     // Read the value from cenrep and check whether camera,keypad
       
   387     // and videoplayer usability.
       
   388     MultimediaSharingSettings::ResourceUsability( iCameraUsability ,
       
   389     											  iKeypadUsability,
       
   390     											  iVideoplayerUsability);
       
   391         
       
   392     // Read the value from cenrep and check whether camera and keypad
       
   393     // available dynamically.
       
   394     MusSettingsKeys::TAvailability camera,keypad;    
       
   395     MultimediaSharingSettings::ResourceAvailability( camera ,
       
   396     												 keypad);
       
   397     
       
   398     TInt err = KErrNone;
       
   399     
       
   400     // Set Camera availability     
       
   401     if(camera == MusSettingsKeys::EAvailabilityDynamic)    												 
       
   402     	{
       
   403     	// read the PS key intial value
       
   404     	err = RProperty::Get(
       
   405                             NMusResourceApi::KCategoryUid,
       
   406                             NMusResourceApi::KCameraAvailability,
       
   407                             (TInt&)iCameraAvailability );
       
   408         if(err) 
       
   409         	{
       
   410         	MUS_LOG1( "mus: [MUSUI ] Error = %d",err )
       
   411         	iCameraAvailability = NMusResourceApi::ENotAvailable;
       
   412         	}
       
   413         // watch the camera ps key for further change
       
   414     	iCameraResourceWatch = CMusUiPropertyWatch::NewL(
       
   415                             *this,
       
   416                             NMusResourceApi::KCategoryUid,
       
   417                             KCameraAvailability ); 
       
   418     	}
       
   419     else
       
   420     	{
       
   421     	iCameraAvailability = NMusResourceApi::EAvailable;	
       
   422     	}
       
   423     	
       
   424     // Set Keypad availability    
       
   425      if(keypad == MusSettingsKeys::EAvailabilityDynamic)    												 
       
   426     	{
       
   427     	// read the PS key intial value
       
   428     	err = RProperty::Get(
       
   429                             NMusResourceApi::KCategoryUid,
       
   430                             NMusResourceApi::KKeypadAvailability,
       
   431                             (TInt&)iKeypadAvailability ); 
       
   432         if(err) 
       
   433         	{
       
   434         	MUS_LOG1( "mus: [MUSUI ] Error = %d",err )
       
   435         	iKeypadAvailability = NMusResourceApi::ENotAvailable;
       
   436         	}
       
   437     	// watch the keypad ps key
       
   438     	iKeypadResourceWatch = CMusUiPropertyWatch::NewL(
       
   439                             		*this,
       
   440                             		NMusResourceApi::KCategoryUid,
       
   441                             		KKeypadAvailability );        
       
   442     	}
       
   443     else
       
   444     	{
       
   445     	iKeypadAvailability = NMusResourceApi::EAvailable;	
       
   446     	}
       
   447     
       
   448     // Videoplayer availability always static
       
   449      
       
   450     MUS_LOG( "mus: [MUSUI ] <- CMusUiResourceHandler::ConstructL()" )
       
   451     }
       
   452 
       
   453 
       
   454 // -----------------------------------------------------------------------------
       
   455 //
       
   456 // -----------------------------------------------------------------------------
       
   457 //
       
   458 TBool CMusUiResourceHandler::ShowChangeProductModeDialogL( 
       
   459                                                         const TDesC& aPrompt )
       
   460     {
       
   461     MUS_LOG( "mus: [MUSUI ] -> CMusUiResourceHandler::ShowChangeProductModeDialogL()" )
       
   462     
       
   463     TBool returnValue = EFalse;
       
   464 
       
   465     if ( !iChangeProductModeDialog )
       
   466         {    
       
   467         iChangeProductModeDialog = new ( ELeave ) CAknWaitDialog( (
       
   468                 reinterpret_cast<CEikDialog**>( &iChangeProductModeDialog )  ), 
       
   469                 ETrue );
       
   470                     
       
   471         iChangeProductModeDialog->SetTextL( aPrompt );
       
   472         
       
   473         iChangeProductModeDialog->PrepareLC( 
       
   474                         R_MUS_LIVE_SHARING_VIEW_ACTIVATE_CAMERA_WAIT_NOTE );
       
   475         returnValue = iChangeProductModeDialog->RunLD();
       
   476         
       
   477         iChangeProductModeDialog = NULL;
       
   478         }
       
   479     
       
   480     MUS_LOG( "mus: [MUSUI ] <- CMusUiResourceHandler::ShowChangeProductModeDialogL()" )
       
   481     
       
   482     return returnValue;
       
   483     }
       
   484     
       
   485 
       
   486 // -----------------------------------------------------------------------------
       
   487 //
       
   488 // -----------------------------------------------------------------------------
       
   489 //
       
   490 TBool CMusUiResourceHandler::IsCurrentlyAvailable( 
       
   491                         NMusResourceApi::TAvailability aResourceAvailability,
       
   492                         MusSettingsKeys::TUsability aResourceUsability
       
   493                          )
       
   494     {
       
   495     MUS_LOG( "mus: [MUSUI ] -> CMusUiResourceHandler::IsCurrentlyAvailable()" )
       
   496 
       
   497     CAknAppUiBase::TAppUiOrientation orientation = iObserver.AppOrientation();
       
   498     
       
   499     MUS_LOG( "mus: [MUSUI ] <- CMusUiResourceHandler::IsCurrentlyAvailable()" )
       
   500     
       
   501     return ( aResourceAvailability == NMusResourceApi::EAvailable && 
       
   502              (
       
   503               aResourceUsability == MusSettingsKeys::EUsabilityAlways ||
       
   504               (aResourceUsability == MusSettingsKeys::EUsabilityLandscape && 
       
   505                orientation == CAknAppUiBase::EAppUiOrientationLandscape) ||
       
   506               (aResourceUsability == MusSettingsKeys::EUsabilityPortrait &&
       
   507                orientation == CAknAppUiBase::EAppUiOrientationPortrait)
       
   508              )
       
   509             );
       
   510     }
       
   511 
       
   512 // -----------------------------------------------------------------------------
       
   513 //
       
   514 // -----------------------------------------------------------------------------
       
   515 //
       
   516 void CMusUiResourceHandler::CheckInitialOrientationL(MultimediaSharing::TMusUseCase aUsecase )
       
   517     {
       
   518     MUS_LOG( "mus: [MUSUI ] -> CMusUiResourceHandler::CheckInitialOrientationL()" )
       
   519     if ( aUsecase != MultimediaSharing::EMusLiveVideo &&
       
   520          aUsecase != MultimediaSharing::EMusClipVideo &&
       
   521          aUsecase != MultimediaSharing::EMusReceive )
       
   522         {
       
   523         return;   
       
   524         }
       
   525     
       
   526     MusSettingsKeys::TUsability usability = ( aUsecase == MultimediaSharing::EMusLiveVideo ) ?
       
   527         iCameraUsability : iVideoplayerUsability;
       
   528     if ( usability == MusSettingsKeys::EUsabilityPortrait )
       
   529         {
       
   530         iObserver.SwitchOrientationL( CAknAppUiBase::EAppUiOrientationPortrait );
       
   531         }
       
   532     else if ( usability == MusSettingsKeys::EUsabilityLandscape )
       
   533         {
       
   534         iObserver.SwitchOrientationL( CAknAppUiBase::EAppUiOrientationLandscape );
       
   535         }
       
   536     MUS_LOG( "mus: [MUSUI ] <- CMusUiResourceHandler::CheckInitialOrientationL()" )
       
   537     }
       
   538 
       
   539 
       
   540 
       
   541 
       
   542 
       
   543 
       
   544 
       
   545 
       
   546 
       
   547 
       
   548 
       
   549 
       
   550 
       
   551 
       
   552 
       
   553 
       
   554 
       
   555 
       
   556 
       
   557 
       
   558