Blog

From the Cloud with Love and Only the User Agent String

by Dino Esposito, our WURFL Developer Evangelist for Microsoft Technologies and .NET Guru

When we designed the WURFL cloud API, we mostly thought of a web-based world. For this reason, the ASP.NET API requires an HttpContext object and uses it to understand just about  everything about the incoming request. To proceed from a solid frame of reference, let’s say that you start with code similar to this:

var config = new DefaultCloudClientConfig { ApiKey = "..." };
var manager = new CloudClientManager(config);

The manager object is the console that gives you access to the cloud-stored information about the device. On the cloud client manager object you usually call the following override of the GetDeviceInfo method:

var context = HttpContext.Current;
var info = manager.GetDeviceInfo(context, new[] { "is_wireless_device", "is_tablet" });

In general, you retrieve the HTTP context in other ways than showed here, but this doesn’t change the basic facts. For example, in ASP.NET Web Forms you can access the HTTP context from the Page object; in ASP.NET MVC instead you get the reference from the controller instance that is serving the request.

Internally, the cloud client manager uses the provided HTTP context to retrieve cookies and HTTP headers (including the user agent string). It consumes the information in order to serve the corresponding values for the specified WURFL capabilities.

So far so good.

Overriding the User Agent String (PREMIUM only)

When the HTTP context is used, as a developer you do not have direct control over the user agent string (UAS) being passed. The user agent is supplied directly from the HTTP request. Is there a way to work around this and force the WURFL cloud backend to process a “given” user agent string instead of the current HTTP request? You bet!

As you know, the WURFL cloud comes in several flavors—Basic, Standard, and Premium. We made this UAS override feature available only to our Premium users. Here’s how one would use it:

var manager = new CloudClientManager(config);
var ua = "...";
var wurflRequest = new WurflCloudRequest(context) { UserAgent = ua };
var info = manager.GetDeviceInfo(wurflRequest, new[] {
               "is_wireless_device", "is_smartphone", "physical_screen_width" });

In this way, any user agent HTTP header that may be carried with the request is ignored. The user agent string processed to match a WURFL device is the one you provide. At the same time, other headers and cookies coming with the request are processed as usual.

Mocking HttpContextBase Maaaybe?

The ASP.NET cloud API is available for the .NET Framework 2.0 and .NET Framework 4.0 and newer versions. In the version compiled against the .NET Framework 4.0 the method GetDeviceInfo on the cloud client manager has the following signature:

public DeviceInfo GetDeviceInfo(HttpContextBase context, String[] capabilities)

The API for the .NET Framework 2.0, instead, uses HttpContext instead of HttpContextBase. Can you recall the difference between HttpContext and HttpContextBase?

HttpContext is the old-fashioned class representing the HTTP context of an ASP.NET request. HttpContext has no base class and no virtual methods. It’s a monolith and gives a great contribution to making ASP.NET a hard-to-test framework. On the other hand, HttpContextBase is an abstract class serving as a testable replacement for HttpContext. First introduced in ASP.NET MVC, it was the ported back to the whole ASP.NET platform with the release of ASP.NET 4.0.

What’s the point? You can create your own class derived from HttpContextBase and pass it to GetDeviceInfo to bypass the issue of overriding the user agent string in a Base WURFL cloud library. If you can do that, it should work. However, we want to call your attention on a key fact: HttpContextBase is a delicate class. It is relatively easy to mock with the help of an ad hoc mocking framework, but it is hard to clone programmatically. Moreover, it may require a lot of code on your own.

Definitive Solution Coming Up

So you provided feedback and we got the message. With the WURFL Cloud API 1.1 for ASP.NET, both Base and Premium users will be able to make a request to the cloud passing in the sole user agent string.  How to do it? It couldn’t be easier; we just added a new override for the GetDeviceInfo method on the clould client manager class:

public DeviceInfo GetDeviceInfo(String userAgent, String[] capabilities)

The code shown above therefore changes as below:

var ua = "...";
var info = manager.GetDeviceInfo(ua, new[] { "is_wireless_device", "is_tablet" });

Note, however, that only Premium users will be able to pass the sole user agent string as well as a custom user agent string and the HTTP context. Base users can specify either the HTTP context or the sole user agent string, but not the two things together.

From the WURFL cloud with love and development passion!

 

WURFL Capabilities Got Virtual

by Dino Esposito, our WURFL Developer Evangelist for Microsoft Technologies and .NET Guru

The WURFL platform has supported virtual capabilities in its WURFL Cloud service for a while. Now, with the release of the API 1.5, virtual capabilities have been revised and extended to the WURFL OnSite, WURFL InFuze and WURFL InSight frameworks. In this post, we discuss virtual capabilities and how to use them in .NET applications.

What’s a Virtual Capability?

In general, there are some capabilities that are easy and straightforward to associate with a value, and other capabilities that require some calculation and depend on the value of other capabilities. For example, it’s fairly easy and unambiguous to determine whether a device is a tablet or a smart TV; it’s much less obvious to define what a smartphone is.

In WURFL, a virtual capability is a capability whose value results from some elaboration done on top of one or more other capabilities. Getting even closer to the structure of WURFL, we could say that a virtual capability is not physically stored in the WURFL database, but is computed on demand. Conceptually, a virtual capability can be assigned to a computed column in a relational database. Beyond this point, though, a virtual capability is exactly the same as a regular capability and is used in the same way.

The table below lists the virtual capabilities supported in the WURFL API 1.5.

Virtual Capability

Description

is_smartphone

Indicates whether the device is reckoned to be a smartphone. Internally, the matcher checks the operating system, screen width, touch and a few other capabilities.

is_ios

Indicates whether the device runs iOS (any version).

is_android

Indicates whether the device runs Android (any version).

is_app

Indicates whether you’re getting the request through the browser embedded in a native app. This typically happens if the web page is hosted in a WebView component.

is_robot

Indicates whether the device is reckoned to be a robot.

advertised_device_os

Returns the common name of the operating system mounted on the device.

advertised_device_os_version

Returns the version of the operating system mounted on the device.

advertised_browser

Returns the common name of the default browser mounted on the device.

advertised_ browser _version

Returns the version of the default browser mounted on the device.

 

Like standard capabilities, virtual capabilities also always return a string value. Boolean virtual capabilities, for example, return either “true” or “false”.  Virtual capabilities in the “advertised” group, instead, just return a string that gives the commercial and familiar name/version of the underlying operating system and default browser available on the device. Most of the time, the value of the device_os standard capability coincides with the value returned by advertised_device_os. The difference is in an extra layer of normalization that is applied after reading the value of the standard capability.

Using a Virtual Capability

You query for a virtual capability using the following code:

var gotSmartphone = device.GetVirtualCapability("is_smartphone");

In WURFL 1.5, the GetVirtualCapability method has been added to the IDevice public interface along with the GetVirtualCapabilities method if you prefer to retrieve all virtual capabilities in a single shot. Below is the signature of both methods:

String GetVirtualCapability(String name);
IDictionary<String, String> GetVirtualCapabilities();

Internally, virtual capabilities rely on a separate set of matchers and abstraction layer that provides caching and overriding through patch files.

Overriding Virtual Capabilities

One thing we’ve learned over the years is that there are capabilities whose value once established in the WURFL database are generally good for everyone. On the other hand, is quite difficult to argue against a given device being wireless or not. However, not all capabilities are the same and it makes totally sense that you ask for a tool to override values set in the database. We provide patch files for that. And patch files have been a standard capability since the beginning of WURFL. Nicely enough, we extended the mechanism of patch files to virtual capabilities too.

You can override the default returned value for a virtual capability using a matching control_cap property in your patch file. For example, let’s say that for a given device WURFL sets the is_smartphone virtual capability to “true.” Let’s also say that for your application it would be better to treat that device as a plain phone. All you do is adding a controlcap_is_smartphone property to the patch file for the given device and assign it any of the following values: force_true or force_false. Here’s a fragment from a sample patch file where the is_smartphone capability is overridden to false.

<group id="virtual">
      <capability name="controlcap_is_app" value="default" />
      <capability name="controlcap_is_robot" value="default" />
      <capability name="controlcap_is_ios" value="default" />
      <capability name="controlcap_advertised_device_os_version" value="default" />
      <capability name="controlcap_is_android" value="default"/>
      <capability name="controlcap_advertised_browser_version" value="default" />
      <capability name="controlcap_advertised_browser" value="default"/>
      <capability name="controlcap_is_smartphone" value="force_false" />
      <capability name="controlcap_advertised_device_os" value="default" />
</group>

 

With virtual capabilities, arranging multi-device solutions is easier - especially in ASP.NET MVC.  In a nutshell, you can leverage display modes of ASP.NET MVC 4 (and newer) and use a mix of standard and virtual capabilities (is_tablet, is_smartphone, is_smarttv) to easily add display conditions to your site. But this is close to becoming a completely different topic  worthy of another post. Meanwhile, here’s a link to an MSDN Magazine article that talks ASP.NET MVC and WURFL together. It doesn’t mention API 1.5 and virtual capabilities, but you can easily see where virtual capabilities fit in.

 

 

The Shifting Sands of Device Identifiers

Radioactive Half Life

Or, The Half-Life of User Agents

One of the key identifiers that WURFL uses to detect devices is the user agent (UA) string. This string morphs based on the device, OS version, browser version and several other dimensions. Over the lifecycle of a device, that device’s user agent will change – especially if you are gadget geek who upgrades, experiments with alternate browsers, or generally fiddles around with his/her phone or tablet.

So, we knew UA string change, but how quickly do we see the universe of active user agents change? If we see a user agent this month, what are the odds that we will see it again unchanged in the following month?  I liken this probability to the half-life of radioactive particles that decay over time – sometimes quickly, and sometimes slowly.  (Disclaimer: I used to work in the nuclear energy industry). This behavior also reflects how difficult it is to stay up to date with user agents.  Just because you have the universe of user agents locked down this month does not mean you will be able to correctly identify most of them with the same UAs in a few months.

Filip Sufitchi and I looked back at the historical data.  Ok, actually Filip did all the hard analysis.  I just asked the questions. We plowed through millions of UA strings.  We identified the universe of unique UAs in July 2012.  It’s a big number. Then, we analyzed subsequent months (August 2012 – July 2013) to see if those original UAs showed up again.  The result: in the next month, only 74% showed up again.  Or, conversely, 26% of UAs churned away. A particular UA may show up again in later months, but in aggregate, the user agent universe is in continuous churn.

 

WURFL User Agent Half Life

This analysis was a bit of a surprise to us.  We knew that UAs changed, but we did not realize how quickly. Over time, if you are using that original set of UAs to identify devices, then it will decline in effectiveness pretty fast.  Between people buying new phones (e.g. Samsung Galaxy S4), OS upgrades (e.g. iOS 7) and new browser versions, the half-life of UAs is pretty short.  Or, to use another metaphor, the sands are always shifting.

At ScientiaMobile, we do two things to make sure this change does not impact your accuracy. First, we use a combination of detection logic in our WURFL API and updating device information in our weekly WURFL snapshot.  Every week, we analyze millions of UAs for new and relevant devices to include in the Device Description Repository (DDR).

The second thing we do is maintain a historical record of the “long tail” of devices. Because we have been doing this for over 12 years, we have a research track record that makes our detections very complete.

It is hard work maintaining WURFL.  It is not for the faint of heart. But with the time, resources, and industry connections that we devote to this issue, the result is an accurate device solution.

by Kenneth Jones, December 11, 2013

Making Mobile Device Detection Easy for Analysts

Data Ninja

You are a data Cuisinart – slicing and dicing and analyzing all day long.  You have laid your hands on weblogs and you would love to figure out a whole bunch of questions related to mobile. Like, how many android tablets are using your web site?  How many non-smartphones? What is the breakdown of Android vs. iOS vs Windows Phone OS vs other?  What are the most popular mobile devices by brand and model? How big are the screens? 

Getting your hand on that data is easy.  Unfortunately, installing the WURFL API requires getting the IT staff involved.  They say, “Sure, no problem. We will install the mobile device detection on a server, integrate the API and spit out data into a new data file.  Give us a month…”   [Head slams on desk]

ScientiaMobile decided to give you a shortcut with the WURFL InSight data service.  You can download the WURFL files that have up to 500 device capabilities from your personal customer vault.  With your ninja-like BI skills, you can join them with your weblogs using the SQL tools you have mastered over the years. No need for help from those slackers at the IT department. Needless to say: you love every second of it. Way to go, Analyst!I ran an experiment with the WURFL InSight and joined the tables with the weblogs of a site I run.  In less than 30 minutes, I had great intelligence about how frequently mobile devices were using the web site and what types of tablets and smartphones they use. Simple and easy.

I’m Ken Jones and I approve this message.

December 4, 2013 By Kenneth Jones

Great News for users of the Free WURFL Cloud

The sky is blue above the clouds.

Pooh

 

We have some great news for those who would like to play around with a professional Device Description Repository such as WURFL, but think that it is either too expensive or too complex to set up. The number of capabilities available to Cloud users has been brought to 5.

Previously the number of capabilities in the free WURFL Cloud was 2. This was not a lot for developers who wanted to explore the power of a commercial DDR free of charge. The situation has now improved for them.


http://www.scientiamobile.com/cloud


In addition to test and development, the 5000 detections per month limit is probably enough for most hobbyist use of WURFL. If not, more expensive plans start as low as $10 per month.


Using the WURFL Cloud is as simple as registering on the ScientiaMobile website (in order to enable your private vault) and downloading the Cloud Client for one of the many platforms supported (Ruby, Perl, Python, Java, PHP, .NET and Node.js):


http://www.scientiamobile.com/wurflCloud/gettingStarted


Enjoy.

 

 

Report from PHP Conference 2013 in Munich Germany: RWD Keynote and HipHop for PHP

 
The thing about Hip-Hop today is it's smart, it's insightful. The way they can communicate a complex message in a very short space is remarkable.
- Barack Obama
 
“Morality, it could be argued, represents the way that people would like the world to work, whereas economics represents how it actually does work.” 
- Steven D. Levitt, Freakonomics: A Rogue Economist Explores the Hidden Side of Everything
 

The ScientiaMobile technical team has been on tour. Steve and I just came back from Munich, Germany, where we were invited speakers at the International PHP Conference 2013.

 

It was a good experience. Since the inception of ScientiaMobile, the time to participate in conferences has been scarce for both of us, we have been way too busy building WURFL products and services, but there is no denying that there is a lot to be gained in staying connected with developers from around the world: sharing knowledge, know-how and, above all, that experience that you can only gain by working on technologies for real (as opposed to simply reading about it).


As far as hands-on experience goes, Steve did his part by showing up with a solid set of slides on Facebook’s HipHop for PHP and the HHVM (Hip Hop Virtual Machine). This is a technology that Facebook developed internally in2009 to boost the performance of native PHP, once they realized that the service popularity was growing exponentially.

 

 

Since Facebook relies on WURFL for its device detection needs, we decided a long time ago that adopting HipHop was a good idea for our APIs and infrastructure. Today, the DB API, the PHP API and the WURFL Cloud run on HipHop, thanks to Steve’s amazing work. That experience was an integral part of Steve’s presentation, along with all the information about the tool that you would expect from a speaker at an international conference. The presentation was so successful that organizers asked Steve to repeat it in a bigger room in the afternoon.


Steve discussed the issues that Facebook faced, and how HipHop for PHP was a solution to those issues. An overview of HipHop was provided as well as the gotchas that come with it (mostly related to compiling statically from a language designed to be, to a large extent, dynamic). The WURFL Cloud was illustrated as a case study for the use of both HipHop and HHVM, the HipHop Virtual Machine. Is a mod_hhvm for Apache and NGINX visible on the horizon?

Here is an interview with Steve talking about the same topic (don’t be scared by Thomas Wießeckel quick introduction in German. Interview is in English).  

 


As far as I (Luca) was concerned, I had the honor to be the keynote speaker on the first day. There was a bit of irony in having me, the lead evangelist in server-side adaptation and mobile detection, give a keynote at an event which focused on Responsive Web Design as one of the main topics. But I love irony, so I titled my presentation:


If Responsive Web Design is the Answer, What Was the Question?

 

In addition to explaining that the most important book in the history of Computer Science is not a Computer Science book, but rather an economy book, I presented some fresh perspective on how those in charge of web and product development should look at two different approaches to Responsive Web Design: "Don't Touch me" RWD vs. Custom Made RWD. The first one is about integrating a $20 RWD template with your existing content. The second is having someone with a solid understanding of RWD in the team. These are radically different approaches that will have an impact when dealing with the "burden of failure", another concept that I introduced in the keynote.
I praised RESS, explained why it can be a compelling proposition for many cases and
reaffirmed the centrality of the end-user when it comes to delivering great mobile services. I also sketched out a map of the different paths that lead from requirements for mobile to the best mobile experience that that an organization’s money (and resources) can buy.


No matter how many times I rehearse, stepping up on a stage and having the eyes of 500 people on me feels intimidating. Hopefully, that did not show too much:

 

 


There was time for a question from the audience. “So, what is the answer?”. To which, being the relativist that I am, I could only respond with the answer that most makes sense whenever humans are involved. “It depends”.

 

Luca Passani

CTO @ScientiaMobile

 

Virtual Capabilities and Filters: introducing WURFL API 1.5

Virtual Capabilities and Filters: introducing WURFL API 1.5

virtual  
 
— adjective 
1.        having the essence or effect but not the appearance or form of: a virtual revolution
2.        having the form or appearance but not the essence or effect of: virtual reality
3.        (rare)  capable of producing an effect through inherent power or virtue
 
 
 
Umberto Eco, a famous Italian phylosopher and a novelist, when asked for an opinion about ‘Virtual Reality’ replied that it did not interest him, but “please, call me back when I can make love to Marilyn Monroe”. Last time I checked, Mr. Eco was still waiting. 
 
Fortunately, long time adopters of the WURFL API are in a much better situation. Virtual capabilities, first mentioned by me in the distant 2005 on the WMLProgramming mailing list are now finally introduced as a standard feature of WURFL API 1.5 on all platforms, released by the ScientiaMobile team last week. The release has taken a bit longer than expected, because of feature creep, but it was worth the wait, because of the cool new features that come with it. 
 
There are mainly two new functionalities that WURFL adopters will appreciate in the new API: Capability filters and Virtual Capabilities. I’ll illustrate capability filters first, since they are the simplest to explain, before I delve into the complexity of virtual capabilities:
 

Capability Filters

Once upon a time, a very old version of the WURFL Java API would ship with a webapp utility that allowed users to select a set of capabilities through a panel of checkboxes and request a wurfl.xml that only contained those capabilities. This was a manual process. Integrating it into the WURFl deployment cycle did not make a lot of sense. Starting with API 1.5, you can configure the OnSite API to just load the capabilities that are relevant for our application. This has obvious advantages in terms of memory footprint, that organizations may want to exploit. The actual syntax to define a filter varies from platform to platform (Java, .NET, PHP, InFuze,...), but it is essentially about providing a list of capability names. In the case of the Java API used with the Spring framework, configuration will look something like this:
 
 
<property name="capabilityFilter">
    <set>
            <value>device_os</value>
            <value>device_os_version</value>
            <value>is_tablet</value>
            <value>is_wireless_device</value>
            <value>pointing_method</value>
            <value>preferred_markup</value>
            <value>resolution_height</value>
            <value>resolution_width</value>
            <value>ux_full_desktop</value>
            <value>xhtml_support_level</value>
    </set>
</property>
 
 
important note: the new feature of virtual capabilities introduces dependencies on certain classic capabilities. If a filter is used, there is a set of physical capabilities that must be defined, under the penalty of the API refusing service. There has been some discussion internally and with beta-testers on whether this was the optimal strategy (we could, after all, trap the exception and keep going). In the end, we figured that forcing WURFL users to know about virtual capabilities and its dependencies would be consistent with the principle of least surprise. Experience shows that users are better served by a WURFL that refuses service when things are not OK, rather than one that forgives developers, but not the end-users of the application.
 
The actual syntax to define a filter for the different APIs is explained in the respective documentations.
 

Virtual Capabilities

As early as 2004, users of the WURFL API on the WMLProgramming mailing list would ask for this or that capability to be added to WURFL. Quite a few times the requested capability completely depended on another existing capability. Hence users would be better off computing the desired value out of the other capability, rather than introducing new capabilities which could quickly become inconsistent. After all, this is not very different from the Normal Forms familiar to DBAs in the RDBMs world.  Already in 2005, there was this concept that popular dependent properties could still be offered by WURFL in the form of computed functions that behaved as capabilities, hence the name of virtual capabilities.
 
It was only in 2012 that the WURFL team finally had the cycles to go back to that idea, implement it and support it, sort of secretly and tentatively, in some of the APIs. In 2013, we decided to support the new feature across platforms and standardize it in all APIs. As an aside, here is a little lesson learned: features are like kids, once you bring them to this world, you have to support them. End of the aside.
 
Virtual capabilites are functions that behave like capabilities, but the value of which is a function of other capabilities and other values that come with the HTTP request. Virtual capabilities enable a few useful features today and open up to a world of new features in the future. 
 
 
Virtual capabilities are called with a slightly different syntax than regular capabilities. Here is an example from Java (again, refer to specific platform documentation for details):
 
Regular Capability Virtual Capability
 
WURFLEngine engine = (WURFLEngine) getServletContext(). getAttribute(WURFLEngine.class.getName());  
 
Device device = engine.getDeviceForRequest(request);
         
log.debug("Capability: " + device. getCapability("preferred_markup"));
WURFLEngine engine = (WURFLEngine) getServletContext(). getAttribute(WURFLEngine.class.getName());  
 
Device device = engine.getDeviceForRequest(request);
         
log.debug("Virtual Capability: " + device. getVirtualCapability("is_smartphone"));
 
Important Note: Again, whether we should have gone for a unifying API for regular and virtual capabilites has been the topic of discussion internally in the team. In the end, we opted for different syntax for the two capabilities. Slightly steeper learning curve for users, but less surprises to deal with when things don’t work quite as expected further down the road.
 
So, what is so cool about these virtual capabilities? a couple of example will make the point.
 

Example 1: is_smartphone

What constitutes a smartphone and what doesn’t is the source of endless discussions. Also, what one would call a smartphone in 2006, would almost guaranteed be a legacy device by today’s standards. For this reason, we decided to introduce a new Virtual Capability called is_smartphone.  This virtual capability implements a totally arbitrary definition of smartphone that may change in the future without notice to follow the evolution of the browser and device market. Think of it like a vienna sausage (AKA hot dog). It is easily available and many like it, but only as long as nobody tells them what the ingredients are. (I am tempted to argue that if you are wondering about what we put inside that capability, you may want to cook your own definition of smartphone with the other fresh unprocessed capabilities).
One hidden feature of this property is that phones for which the function evaluates to true are guaranteed to handle all popular Responsive Web Design (RWD) websites properly. This allows company to leverage is_smartphone (together with is_tablet and is_full_desktop) to detect legacy devices and route them to a different experience (say, an existing m.* site).
 
 

Example 2: advertised_browser, advertised_device_os, advertised_browser_version, advertised_device_os_version

A totally different, but still super-useful, use case is the one that introduces the ability to analyze the original UA string for browser and OS information. As you know, WURFL is geared at mobile devices. API 1.3 introduced better support for desktop web browsers, but still, filling the WURFL DB with information about hundreds of desktop web browser was never the way to go (particularly because of concerns with memory footprint).  
advertised_browser, advertised_device_os, advertised_browser_version and advertised_device_os_version are virtual capabilities that solve this issue. When used to handle mixed mobile-web traffic, 98% or more of the desktop traffic will be mapped into the ‘generic_web_browser’ device or one of its descendants by the WURFL API. In this case, the 4 virtual capabilities can be used to extract OS and Browser version information through brute force UA string analysis. Of course, this could be done also previously outside of WURFL, but now we have decided to implement this as a standard supported feature of the WURFL API.
 
 
What follows is a complete list of virtual capabilities available with API 1.5:
 

Virtual Capability

Description

is_android

True if the device runs Android (any version).

is_ios

True if the device runs iOS (any version).

is_windows_phone

True if the device runs Windows Phone 6.5 or higher. Note that this does not include Windows Mobile or Windows CE.

is_app

True if the requests is from a native app. This typically of requests from WebView components and RESTful API calls.

is_full_desktop

True if the requesting device has a full desktop experience. This capability is an alias for ux_full_desktop.

is_largescreen

True if the requesting device's screen is of a high resolution (over 480 pixels in width and height)

is_mobile

True if the device is mobile, like a phone, tablet, media player, portable game console, etc. This capability is an alias foris_wireless_device.

is_robot

True if the request is from a robot, crawler, or some other automated HTTP client.

is_smartphone

True if the device is a smartphone. Internally, the matcher checks the operating system, screen width, pointing method and a few other capabilities.

is_touchscreen

True if the primary pointing method is a touchscreen.

is_wml_preferred

True if the requesting device should be served with WML markup.

is_xhtmlmp_preferred

True if the requesting device should be served with XHTML-MP markup.

is_html_preferred

True if the requesting device should be served with HTML markup.

advertised_device_os

Returns the operating system name of the requesting device. This works for mobile and desktop devices. (ex: "Windows", "Mac OS X")

advertised_device_os_version

Returns the operating system version of the requesting device. This works for mobile and desktop devices. (ex: "XP", "10.2.1")

advertised_browser

Returns the browser name of the requesting device. This works for mobile and desktop devices. (ex: "Internet Explorer", "Chrome")

 
Virtual Capability Table: here is a list of virtual capabilities introduced with API 1.5
 
 
Illustration of virtual capabilities is not over. There is something more. What if we wanted to override the behavior of a virtual capability for specific WURFL devices? This is possible thanks to the new control capabilities.
 
 

Control Capabilities

Control capabilities are a developer’s edge on virtual capabilities that do what you want, but not quite in certain cases. If a virtual capability called “foobar” exists, you can define a WURFL patch file with group ‘virtual’ and a capability ‘controlcap_foobar’ that the virtual capability will look up before it starts to compute a value. If the capability has value ‘default’ for that device, the virtual capability will perform the expected computations.  Otherwise, it will return the value specified in the capability. In case of boolean capability, the token ‘force_true’ and ‘force_false’ should be used instead (“true” and “false” are reserved for truly boolean capabilities).
 
 
As an example,  I’ll take inspiration from this blog post by Tim Kadlec that describes a bug in the support of the  @-ms-viewport rule on Nokia Lumia 920 devices. This bug is particularly nasty if you want the device to render RWD sites. Assuming you care about this device not getting the RWD version of your site, the following patch would allow you to override the behavior of is_smartphone and treat the device as a non-smartphone:
 
 
  <device id="nokia_lumia_720_ver1" user_agent="Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; IEMobile/10.0; ARM; Touch; NOKIA; Lumia 720)" fall_back="generic_ms_phone_os8">
    <group id="virtual">
       <capability name="controlcap_is_smartphone" value="force_false"/>
    </group>
  </device>
 
 

Improved Detection

In addition to filters and virtual capabilities, API 1.5 comes with the usual batch of improvements in the detection logic. This is, of course, the main reason why people love WURFL and customers pay for updates. Going into details here is unnecessary. The following keywords will suffice: Firefox Mobile, Firefox OS, SmartTV, BlackBerry, Opera Mini, UCWeb, Bots and more…
 
Enjoy
 
Luca Passani
CTO @ScientiaMobile
 

WURFL and Google Glass

Google Glass has received quite a lot of media attention lately. 

Initially, we had gathered the information that the new tool did not come with a browser. But someone in Google had tipped us that this would change soon.

Now it's official: https://plus.google.com/+projectglass/posts/eV8RUWoodig

As part of the tip, we received the UA of the new Google Glass browser:

Mozilla/5.0 (Linux; U; Android 4.0.4; en-us; Glass 1 Build/IMM76L; XE7) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30 

WURFL commercial users will find this UA as part of the latest WURFL snapshot.

Now the question is: is_google_glass anyone?
 
Luca Passani
CTO @ScientiaMobile

Couple of Things (Smashing Magazine and Google Analytics)


"The lack of money is the root of all evil".
- Mark Twain 
 
Haven't blogged in a while. Will two halves of a piece of news make a full blog post?  let's see.
 
Smashing Magazine
SmashingMagazine, a very highly regarded website for web developers and web designers, has published an article from yours truely.
The takeway point of the article is that, once all is said and done, Responsive Web Deisgn is cool, but server-side detection can provide the extra gears to bring your site to the next level. Judging from the comments so far, it seems that I and Steve (who helped a lot with the actual example) managed to drive the point home:

Here it comes: Providing the Best User-Experience Possible. Enjoy.

The second thing that is worth mentioning on this blog today is that Google has introduced a paid Premium Analytics offering. If you are OK with the basic features of Google Analitycs we all know, analytics is free. Alternatively, if you want more, be ready to fork out $150k. 

Google Analytics Premium

Yes, that's not one hundred and fifty dollars. It's a steep 150,000.00 (one hundred and fifty thousand) dollars per year. That's a lot of money. Yet, I see this as positive news. Those systems take money to build and manage, and it is time that we come to terms again with the fact that not everything can be free of charge, not even on the Internets.

Have a good one.

Luca

You are not a man until...(WURFL InFuze and Raspberry PI)

"A man is not old until regrets take the place of dreams."

Pretty much everyone must have heard several instances of the "you are not a man until..." sentence followed by some more or less moronic action. When it comes to C APIs, I suspect that the programming counterpart recently has become "You did not build a real C API until you can compile and run it on a Raspberry PI". In fact, there seems to be a race to run every bit of software ever conceived on a Raspberry PI. So, it didn't take much before someone in our C and C++ engineering team in Milan, Italy, picked up the gauntlet and accepted the challenge on behalf of our WURFL InFuze product line.

Today, we can report that that challenge was succesfully won.

 We used a Model B Raspberry PI (512 Mb RAM and ARM 700Mhz processor). Arguably, the most popular Linux distribution for that device is Raspbian, a Debian 6 port for the ARM processor. 

We used the documentation and build scripts that are used for our standard Ubuntu and Debian 6 distributions. After installing the dependencies for compiling the WURFL InFuze products, we launched the make_all_deb_rpm.sh, script. This is the script that we run to compile all libraries and modules. Here is what the script does:

  1. Install all applications and libraries needed to compile (libboost, gcc, etc.)
  2. download the source code of the various components to include the WURFL libraries and modules.
  3. run configure and make all to compile everything
  4. launches fpm to create a .deb package.
The compilation was successful at the first attempt, exactly as we would expect for the compilation of a normal distribution of Debian 6.
 
Two packages (libwurfl.deb and mod_wurfl.deb, the Apache Module) were installed with:
 
#dpkg-i libwurfl.deb
 
Apache 2.2 was already installed by default. All the we had to do was to edit the wurfl.conf file to activate the recognition of certain capabilities, restart  Apache and... Bingo!
 
WURFL InFuze (Apache) on RaspberryPI
 
Of course, we were also able to compile the InFuze NGINX module without problems.
 
The Moral of the Story is: WURFL InFuze is now a man!
 
Enjoy!
 
The ScientiaMobile Engineering Team in Milan