rhomobile / rhodes

The Rhodes framework is a platform for building locally executing, device-optimized mobile applications for all major smartphone devices.
http://tau-platform.com/
MIT License
1.05k stars 237 forks source link

Android Common API extensions - PropertyBag Properties not initialized #600

Open jtara opened 9 years ago

jtara commented 9 years ago

Rhodes 5.0.30.

I created a simple common-API extension, using the default implementation created by command-line. I added an additional method, and one Property, which has a default value. I also changed the default instance ID from "SCN1" to "default".

Android implement does not enumerate my property, but does enumerate the ID property. iOS works correctly.

I've tried various ways of setting/getting properties. None of them see to work for Android.

AppApplication initialize:

class_name = self.class.name
Rho::Log.info "Rho::BonjourBrowser.calcSumm(2,4) = #{Rho::BonjourBrowser.calcSumm(2,4)}", class_name
Rho::Log.info "Rho::BonjourBrowser.search = #{Rho::BonjourBrowser.search}", class_name
Rho::Log.info "BonjourBrowser properties: #{Rho::BonjourBrowser.getAllProperties.inspect}", class_name

iOS:

2015-04-29 13:50:57.608 rhorunner[91980:4201686] I 04/29/2015 13:50:57:608 1d3b7000       AppApplication| Rho::BonjourBrowser.calcSumm(2,4) = 6
2015-04-29 13:50:57.608 rhorunner[91980:4201686] I 04/29/2015 13:50:57:608 1d3b7000       AppApplication| Rho::BonjourBrowser.search = 123
2015-04-29 13:50:57.608 rhorunner[91980:4201686] I 04/29/2015 13:50:57:608 1d3b7000       AppApplication| BonjourBrowser properties: {"xyzzy"=>"plugh", "ID"=>"default"}

Android:

I/APP     (13358): I 04/29/2015 16:40:45:944 00003455       AppApplication| Rho::BonjourBrowser.calcSumm(2,4) = 6
I/APP     (13358): I 04/29/2015 16:40:45:945 00003455       AppApplication| Rho::BonjourBrowser.search = 123
I/APP     (13358): I 04/29/2015 16:40:45:946 00003455       AppApplication| BonjourBrowser properties: {"id"=>"default"}

As well, note the inconsistency in capitalization of the ID key between iOS and android.

<?xml version = "1.0"?>
<?xml-stylesheet type="text/xsl" href="pb_help.xsl"?>
<API>
    <MODULE name="BonjourBrowser" parent="Rho">
        <HELP_OVERVIEW>Example extension api</HELP_OVERVIEW>
        <MORE_HELP>This is example of API. Implementation contain in extension.</MORE_HELP>

        <TEMPLATES>
            <DEFAULT_INSTANCE/>
            <PROPERTY_BAG/>
        </TEMPLATES>

        <CONSTANTS>
          <CONSTANT name="SAMPLE_INTEGER_CONSTANT" value="12345" type="INTEGER">
          </CONSTANT>
        </CONSTANTS>

         <PROPERTIES usePropertyBag="accessorsViaPropertyBag" generateAccessors="true">
            <DESC>list of properties supported by instance of object</DESC>
            <PROPERTY name="xyzzy" type="STRING" default="plugh" >
                <DESC>simple string property</DESC>
            </PROPERTY>
        </PROPERTIES>

        <METHODS>

            <METHOD name="enumerate" access="STATIC" hasCallback="optional">
                <RETURN type="ARRAY">
                    <DESC>Array of BonjourBrowser objects</DESC>
                    <PARAM type="SELF_INSTANCE"/>
                </RETURN>
            </METHOD>

            <METHOD name="getPlatformName">
                <DESC>return string with platform</DESC>
                <RETURN type="STRING"/>
            </METHOD>

            <METHOD name="calcSumm">
                <DESC>return summ of two params: a+b</DESC>
                <PARAMS>
                    <PARAM name="a" type="INTEGER">
                    </PARAM>
                    <PARAM name="b" type="INTEGER">
                    </PARAM>
                </PARAMS>
                <RETURN type="INTEGER"/>
            </METHOD>

            <METHOD name="joinStrings">
                <DESC>return join of two strings: a+b</DESC>
                <PARAMS>
                    <PARAM name="a" type="STRING">
                    </PARAM>
                    <PARAM name="b" type="STRING">
                    </PARAM>
                </PARAMS>
                <RETURN type="STRING"/>
            </METHOD>

            <METHOD name="search">
                <PARAMS>
                </PARAMS>
                <RETURN type="INTEGER"/>
            </METHOD>

        </METHODS>

        <USER_OVERVIEW>
        </USER_OVERVIEW>

        <VER_INTRODUCED>1.0.0</VER_INTRODUCED>
        <PLATFORM>
         </PLATFORM>
    </MODULE>
</API>
jtara commented 9 years ago

FYI, AudioCapture is a good canary for this coal mine. It shows evidence of work-arounds for this Issue.

There is evidence that an API was generated at some point from the XML, but then the generated files were not used, and, in fact, don't even exist in Rhodes.

ext_java_files lists files that do not exist. Clearly, the build script for this API has been modified.

And there are commented-out calls to super in the implementations of property getters and setters.

Apparently, the generated code (which I am guessing is broken) was bypassed and the property-related code written directly in AudioCapture.java.

Presumably, the author of AudioCapture had to work-around non-working generated code dealing with properties.

All well and good that they did what was needed to make the API work. But the code generator should be fixed, and/or the documentation updated to reflect that this part of the common API code generator is nonfunctional for Android.

jtara commented 9 years ago

I updated the title.

Properties do work -partially. But they are not initialized in the generated code. If you define properties in the XML and set default values, the values are NOT set to the defaults (on Android) and the property keys are not added to the map.

I tested by defaulting a property value in the XML, printing all properties, setting a property, then printing properties again.

Works for iOS.

Defaults do not work for Android.

class_name = self.class.name
Rho::Log.info "Rho::BonjourBrowser.calcSumm(2,4) = #{Rho::BonjourBrowser.calcSumm(2,4)}", class_name
Rho::Log.info "Rho::BonjourBrowser.search = #{Rho::BonjourBrowser.search}", class_name
Rho::Log.info "BonjourBrowser properties: #{Rho::BonjourBrowser.getAllProperties.inspect}", class_name
Rho::BonjourBrowser.setProperty('xyzzy', 'abcde')
Rho::Log.info "BonjourBrowser properties: #{Rho::BonjourBrowser.getAllProperties.inspect}", class_name
Rho::Log.info "AudioCapture properties: #{Rho::AudioCapture.getAllProperties.inspect}", class_name

iOS

2015-04-29 20:38:53.756 rhorunner[6485:4431988] I 04/29/2015 20:38:53:756 17e30000       AppApplication| Rho::BonjourBrowser.calcSumm(2,4) = 6
2015-04-29 20:38:53.756 rhorunner[6485:4431988] I 04/29/2015 20:38:53:756 17e30000       AppApplication| Rho::BonjourBrowser.search = 123
2015-04-29 20:38:53.757 rhorunner[6485:4431988] I 04/29/2015 20:38:53:757 17e30000       AppApplication| BonjourBrowser properties: {"xyzzy"=>"plugh", "ID"=>"default"}
2015-04-29 20:38:53.757 rhorunner[6485:4431988] I 04/29/2015 20:38:53:757 17e30000       AppApplication| BonjourBrowser properties: {"xyzzy"=>"abcde", "ID"=>"default"}
2015-04-29 20:38:53.757 rhorunner[6485:4431988] I 04/29/2015 20:38:53:757 17e30000       AppApplication| AudioCapture properties: {"ID"=>"AudioCaptureUnit", "fileName"=>"AudioCapture", "source"=>"mic", "encoder"=>"", "maxDuration"=>"20000"}

Android

I/APP     (14995): I 04/29/2015 23:33:09:448 00003abb       AppApplication| Rho::BonjourBrowser.calcSumm(2,4) = 6
I/APP     (14995): I 04/29/2015 23:33:09:449 00003abb       AppApplication| Rho::BonjourBrowser.search = 123
I/APP     (14995): I 04/29/2015 23:33:09:450 00003abb       AppApplication| BonjourBrowser properties: {"id"=>"default"}
I/APP     (14995): I 04/29/2015 23:33:09:451 00003abb       AppApplication| BonjourBrowser properties: {"id"=>"default", "xyzzy"=>"abcde"}

I/APP (14995): I 04/29/2015 23:33:09:451 00003abb AppApplication| AudioCapture properties: {"fileName"=>"", "source"=>"mic", "maxDuration"=>"20000", "encoder"=>"AAC"}