Categories
technical

Mobile Ad Serving

I’ve seen a lot of AdMob [admob.com] ads in iPhone applications over the past two years. But recently I downloaded two free — i.e. ad supported — applications that appear to use a Google ad server (of course Google purchased AdMob but I don’t think it’s just a re-branding I think it’s a different service.)

I noticed this for two reasons. First; for the past few years I have been working in the mobile advertising space, so this stuff stands out. Second; the ads were odd.

Why odd? Well, as I mentioned these were ads in iPhone applications. Keep that in mind and take a look at the ads:

Google mobile ads banner for SingTel Mobile SME services
Google mobile ads banner for Android
Google mobile ads banner for Nokia 5530 Apps Store
Google mobile ads banner for Nokia E63 Apps Store

The issue, I think, with these ads is they are all for competitors. I can excuse the SingTel ad, I’m a Starhub customer but this is an add for enterprise services and the ad was served while I was on a WiFi network, so there is not much chance that Google could have determined my operator.

However, the ad for Android and the two ads for the Ovi store — which sells applications that work on Nokia handsets are not useful to me as a consumer and most likely a waste of the advertisers money. The odds that I am going to patronize either of these services from my iPhone is next to zero.

And there is little excuse for this. When I was working on requirements for a mobile advertising system the product team was adamant that it include basic relevance filtering. Now relevance filtering is complex and the simple business rule “the advertisement should be relevant and useful to the consumer” actually breaks down to a lot of technical requirements. The technical requirements of significance here are:

Requirement 1
The system shall attempt to retrieve the User-Agent header from the HTTP request. The header should be used to reduce the pool of relevant banners by removing banners that:
  1. have a User-Agent whitelist that does not include the User-Agent retrieved from the HTTP request
  2. have a User-Agent blacklist that does include the User-Agent retrieved from the HTTP request
Requirement 2
They system shall allow buyers to construct a whitelist or a blacklist of User-Agent strings which for specific campaigns or banners in a campaign.
Requirement 3
User-Agent lists (white- or black-) should be constructed of strings entered by buyers by selecting full User-Agents or pre-coded regular expression from a list or entering an arbitrary regular expression.

(Obviously there are a lot more details and other requirements that need to be clarified before you can actually implement this.) Here’s a use case that would prevent the issue of the Ovi banners being shown to me on my iPhone.

Use Case:
Setting up a campaign level whitelist, to filter out non-Nokia handsets.
Pre-Condition:
The buyer has created a campaign
The buyer selects Relevance Filtering from the interface
Post-Condition:
A new filter is added to the campaign level whitelist for the selected campaign
Scenario:
  1. The Buyer selects Create/Edit Whitelist from the Relevance Filtering menu.
  2. The System loads the Relevance Whitelist interface
  3. The Buyer selects the Filter Campaign checkbox
  4. The Buyer clicks on the Add Filter button
  5. The Buyer selects the Manual Filter filtering method
  6. The Buyer enters *nokia* in the Manual Filter textbox and clicks the Case Insensitive checkbox
  7. The Buyer clicks on the Test Filter button
  8. The System displays a list of all matching User-Agent Strings, highlighting the match(s)
  9. The Buyer clicks on Confirm Filter button
  10. The System adds the filter to the campaign level whitelist in the Database for the selected campaign

So now the Buyer (in this case Nokia or an agent acting on Nokia’s behalf to setup the ad campaign) has created a campaign level whitelist (i.e. all banners in the campaign will be filtered by this whitelist) which includes a filter of *nokia* that is case insensitive. This means that, based on the requirements enumerated above, that no ad request that includes a User-Agent string that does not includes the word nokia in it will be served any banner from this campaign. The effect? Ovi store ads will only be shown to users who are using Nokia handsets (or who’s requesting user agent does not include a User-Agent string or is using an incorrect User-Agent string that includes the word nokia.

Lets look at two use cases for requesting an ad. One where the requesting handset is Nokia N95 and one where it is an iPhone 3GS.

Use Case:
A Apple iPhone 3GS makes an Ad Request from an application running the Ad Server SDK.
Pre-Condition:
The application is using the provided Ad Server SDK
The application makes an ad request
Post-Condition:
A banner is served
Scenario:
  1. The application sends a well-formed HTTP GET Request to the Ad Request Handler URL including an Ad Request payload and the Device User-Agent Header (Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_0 like Mac OS X; en-us) AppleWebKit/528.11 (KHTML, like Gecko) Version/3.1.1 Mobile/7A238j Safari/525.20)
  2. The Ad Request Handler Thread retrieves the Ad Request Payload and the HTTP User-Agent Header constructs an Ad Request, sets it’s state to New and pushes the Ad Request onto the Inbound Ad Request Queue
  3. The Ad Request Handler Thread registers with the Ad Dispatcher to wait for it’s Ad.
  4. The Ad Request Processing Thread pops the next Ad Request off of the Inbound Ad Request Queue
  5. The Ad Request Processing Thread checks the Ad Request state
  6. The Ad Request Processing Thread finds the Ad Request state is New
  7. The Ad Request Processing Thread pushes all ads in its Recycle Ad Queue onto the Active Ad Queue
  8. The Ad Request Processing Thread sets the Ad Request state to Unfulfilled
  9. The Ad Request Processing Thread pops the first add off the Active Ad Queue
  10. The Ad Request Processing Thread checks the selected ad for White- and Black- lists
  11. The Ad Request Processing Thread finds an active Campaign Level User-Agent Whitelist
  12. The Ad Request Processing Thread attempts to match each string in the Campaign Level User-Agent Whitelist against the Device User-Agent String in the Ad Request
  13. The Ad Request Processing Thread finds no match for the string *nokia* (case insensitive) in the Device User-Agent String;Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_0 like Mac OS X; en-us) AppleWebKit/528.11 (KHTML, like Gecko) Version/3.1.1 Mobile/7A238j Safari/525.20
  14. The Ad Request Processing Thread rejects the ad for this request placing it on the Recycle Ad Queue
  15. The Ad Request Processing Thread pushes the Ad Request back on the Inbound Ad Request Queue
  16. The Ad Request Processing Thread monitors the Ad Request Queue
  17. The Ad Request Processing Thread pops the next Ad Request off of the Inbound Ad Request Queue
  18. The Ad Request Processing Thread checks the Ad Request state
  19. The Ad Request Processing Thread finds the Ad Request state is Unfulfilled
  20. The Ad Request Processing Thread pops the first add off the Active Ad Queue
  21. The Ad Request Processing Thread checks the selected ad for White- and Black- lists
  22. The Ad Request Processing Thread finds no active White- or Black- lists for the ad
  23. The Ad Request Processing Thread selects the Ad for this Ad Request attaches the Ad to the Ad Request and updates the Ad Request state to Pending
  24. The Ad Request Processing Thread pushes the Ad Request onto the Outbound Ad Request Queue
  25. The Ad Request Processing Thread pushes all ads in its Recycle Ad Queue onto the Active Ad Queue
  26. The Ad Request Processing Thread Monitors the Ad Request Queue
  27. The Ad Dispatcher pops the Ad Request off the Outbound Ad Request Queue
  28. The Ad Dispatcher reads the Ad Handler Thread Id from the Ad Request and passes the Ad Request to the corresponding Ad Handler Thread
  29. The Ad Dispatcher Monitors the Outbound Ad Request Queue
  30. The Ad Handler Thread parses the Ad Request and retrieves the ad
  31. The Ad Handler Thread constructs an HTTP Response with the Ad Response Payload including the Ad
  32. The Ad Handle Thread sends the HTTP Response to the requesting application

A few explanations/notes:

The looping nature of the Ad Request Processing Thread makes it hard to write an efficient and clear Use Case but I’m not getting paid to do this (any more) so I’m not going to spend the time to do the work to make it clearer.

This use case leaves out details of filters other than the Whilelist filter, such as Logged In/Logged Out Ad Queue selection, Ad Unit size, etc. for simplicity.

There would be multiple Ad Request Processors/Threads running, so when the first thread that retrieved the Ad Request and found the request was in the New state it pushed all the ads in it’s internal Recycle Ad Queue back onto the Active Ad Queue because those banners still need to be served and may be suitable for this Ad Request. The second time the Ad Request Processing Thread finds the Ad Request in the Unfulfilled state it does not empty it’s Recycle Ad Queue to avoid endlessly looping over the same unsuitable ad. (Writing this I think I need to think more about this—there could be a condition where a thread only ever sees Ad Requests in the Unfulfilled state and would therefore never empty its Recycle Ad Queue…)

I’ve included a lot of stuff that would actually go to other use cases and just be referenced as Include X Use Case, again I hope this makes it clearer (at least to the techies) what is happening.

Anyway… Here is what would happen when an Nokia N95 made a request:

Use Case:
A Nokia N95 makes an Ad Request from an application running the Ad Server SDK.
Pre-Condition:
The application is using the provided Ad Server SDK
The application makes an ad request
Post-Condition:
A banner is served
Scenario:
  1. The application sends a well-formed HTTP GET Request to the Ad Request Handler URL including an Ad Request payload and the Device User-Agent Header (Mozilla/5.0 (SymbianOS/9.2; U; Series60/3.1 NokiaN95/10.0.018; Profile/MIDP-2.0 Configuration/CLDC-1.1 ) AppleWebKit/413 (KHTML, like Gecko) Safari/413)
  2. The Ad Request Handler Thread retrieves the Ad Request Payload and the HTTP User-Agent Header constructs an Ad Request, sets it’s state to New and pushes the Ad Request onto the Inbound Ad Request Queue
  3. The Ad Request Handler Thread registers with the Ad Dispatcher to wait for it’s Ad.
  4. The Ad Request Processing Thread pops the next Ad Request off of the Inbound Ad Request Queue
  5. The Ad Request Processing Thread checks the Ad Request state
  6. The Ad Request Processing Thread finds the Ad Request state is New
  7. The Ad Request Processing Thread pushes all ads in its Recycle Ad Queue onto the Active Ad Queue
  8. The Ad Request Processing Thread sets the Ad Request state to Unfulfilled
  9. The Ad Request Processing Thread pops the first add off the Active Ad Queue
  10. The Ad Request Processing Thread checks the selected ad for White- and Black- lists
  11. The Ad Request Processing Thread finds an active Campaign Level User-Agent Whitelist
  12. The Ad Request Processing Thread attempts to match each string in the Campaign Level User-Agent Whitelist against the Device User-Agent String in the Ad Request
  13. The Ad Request Processing Thread finds a match for the string *nokia* (case insensitive) in the Device User-Agent String;Mozilla/5.0 (SymbianOS/9.2; U; Series60/3.1 NokiaN95/10.0.018; Profile/MIDP-2.0 Configuration/CLDC-1.1 ) AppleWebKit/413 (KHTML, like Gecko) Safari/413
  14. The Ad Request Processing Thread selects the Ad for this Ad Request attaches the Ad to the Ad Request and updates the Ad Request state to Pending
  15. The Ad Request Processing Thread pushes the Ad Request onto the Outbound Ad Request Queue
  16. The Ad Request Processing Thread pushes all ads in its Recycle Ad Queue onto the Active Ad Queue
  17. The Ad Request Processing Thread Monitors the Inbound Ad Request Queue
  18. The Ad Dispatcher pops the Ad Request off the Outbound Ad Request Queue
  19. The Ad Dispatcher reads the Ad Handler Thread Id from the Ad Request and passes the Ad Request to the corresponding Ad Handler Thread
  20. The Ad Dispatcher Monitors the Outbound Ad Request Queue
  21. The Ad Handler Thread parses the Ad Request and retrieves the ad
  22. The Ad Handler Thread constructs an HTTP Response with the Ad Response Payload including the Ad
  23. The Ad Handle Thread sends the HTTP Response to the requesting application

This type of White- and Black- list filtering would prevent me from seeing ads for the Ovi store on my iPhone (assuming the people provisioning the ads or campaigns used, and used correctly, the filtering options mentioned above — but that’s a business problem not a technical one.)

The ad serving space is complicated but have been surprised to see a number of examples like this on my phone over the past few days. In fact most of the ads I receive in the applications that use the Google system over the AdMob system seem to fall into this category. I have notices a lack of relevant ads in general for Singapore in the Google Web system. On some sites I see very relevant ads; global companies doing brand building or selling online. But on a lot of sites, and I mean a lot I see the same ads for the same service—a Singapore specific company so at least the location filtering is working. Or I see public service ads (invariably for Kiva [kiva.org].) So either there are not enough relevant ads for Singapore or these local guys are spending a lot of money to spam everyone.

The people at Google are a lot smarter than me, so I wonder if there is something I am missing in all this? Were my product people wrong? Are the users who are creating the campaigns not using some feature of the Google system that would filter these ads from me? Am I completely nuts? Do I have too much time on my hands?

Categories
ranting

Avant Garde vs. Usable Interface Design

Catching up on my RSS reader I ran across this post from Gizmodo titled Windows Phone 7 Interface: Microsoft Has Out-Appled Apple.

Oh. Provocative. Go read it. I’ll wait.

Back? Ok then. Now, opinions are like ass holes; everybody’s got one (well, not not everyone [wikipedia.org].) but I want to poke fun at the author, Jesus Diaz, opening opinion:

Windows Phone 7 feels like an iPhone from the future. The UI has the simplicity and elegance of Apple’s industrial design, while the iPhone’s UI still feels like a colorized Palm Pilot.

Jesus Diaz, in Windows Phone 7 Interface: Microsoft Has Out-Appled Apple [gizmodo.com] on Gizmodo.

Yea the Windows Phone 7 UI looks cool, and it remains to be seen if users will actually like it when it gets into the hands of all those people with ass holes opinions. But I’m going to bet on the oh-so-boring Palm Pilot-esque grid layout the iPhone uses.

Why? Same reason I don’t think everyone will be sitting on a Feel Seating System Deluxe [animicausa.com] sofa. The tired old sofa that your parents have might be musty and hold too many memories of the 70’s or 80’s to be healthy but there is a reason it looks like almost every other sofa in every other normal house in the world for the past, oh, I don’t know, 1000 years or so.

The basic design of the sofa —as used in the real world outside of the Milan furniture fashion show world— hasn’t changed much over the years. That’s a testament to one thing: it works. And while every furniture designer out there wants to do something new and original, so they make crazy sofas [freshome.com] (or crazy chairs, tables, etc.) their designs don’t change our platonic ideal of the sofa because they just aren’t practical in the end. Um, that’s why we call it fashion, different doesn’t mean good.

So, unless the Windows Phone 7 UI breaks down to a grid layout (or list layout) in the end, with some funky cool icons, I’m betting it eventually will by hook or software update.

Then again, this is just my ass hole opinion, feel free to ignore it. Oh yea, and I’ve been itching to use that sofa metaphor in a blog post for about a year.

Categories
ranting

LNY vs CNY

This coming Sunday, in addition to being St. Valentines day to most of the world, also marks the end of the Year of the Ox and the beginning of the Year of the Tiger in the Chinese Calendar.

Someone mentioned to me the other day that they had noticed that it was in-vogue this year, here in Singapore, to refer to the upcoming celebrations, also known as the Spring Festival as “LNY” or “Lunar New Year” rather than “CNY” or “Chinese New Year”.

Since they mentioned it I have noticed more use of LNY than in previous years. I wonder why? Maybe people think “Chinese New Year” is somehow racist or in some other way derogatory?

I don’t know but I think calling it LNY is the tyranny of the masses, at least in Singapore. Since both the Muslim and Indian calendars are lunar based and both lunar new years are public holidays here in Singapore. It should be CNY.

To back up my thoughts I looked it up on Wikipedia and found this choice quote:

…the Chinese calendar is still used for marking traditional East Asian holidays such as the Chinese New Year (or Spring Festival (春節), not to be confused with Lunar New Year, which is the beginning for several lunisolar calendars)

Emphasis mine

Read the rest of the article on the Chinese Calendar [wikipedia.org]. More on the Spring Festival or CNY [wikipedia.org]. Read more on Lunisolar Calendars [wikipedia.org].

Categories
ranting

The separation of marriage and civil union

In the US, and to a lesser extent in some other countries, the debate about ‘Gay Marriage’ is slow boil topic, currently mostly eclipsed by the debates over health care and the economy but occasionally still erupting into a volcano of mud slinging and hate mongering. I would like to propose a solution.

My attempt at a solution is based on the observation that marriage is a religious institution that, for historical reasons, has been co-opted into the fabric of secular law. This is, of course, a holdover from the days when there was little or no distinction between the religion and secular laws —and this can be applied equally to almost all societies and religions, the idea of marriage, the way we think of it today, seems to exist in all societies. In most of the “west” what we think of as marriage is a direct result of the Abrahamic cultures ideas codified into religious belief and later into law.

This is of a particular problem in America. Partially due to the strange fact that, alone among the “developed world”, America is becoming more religious. The acceptance of homosexuals in Western Europe seems to be more than in the US. Perhaps due to it’s seemingly more and increasingly secular nature. (I need a small army of sociologists and statisticians to verify all of my claims and ‘facts’ of course… But it’s my website so IMHO is gospel.)

The point of all this is to establish that what we call marriage, is a religious institution that, for historical reasons, has had legal status attached to it. Once we acknowledge this then we should realize that we have an issue in the US: because marriage is a religious institution, and the laws about it stem from a particular religious background, they are a violation of the constitutional principle of separation of Church and State.

To fix this I would abolish all reference to “marriage” in federal, state and local law and replace it with “Civil Union” or some new term with less baggage. A Civil Union would be defined as a legal status formed by mutual agreement between two adults to the exclusion of all other adults granting certain entitlements. The nature of these entitlements would basically be the same legal entitlements that exist for “married couples” today—things related to taxes, inheritance, health care, etc. Marriage would then revert to the exclusive authority of the religious institutions to grant and deny as they see fit—but without legal consequences.

This then would allow two men or two women to enter enter a civil union of equal standing to the civil union of any man and woman. If any couple, man and woman or man and man or women and women wanted to be ‘married’ it would be an issue for their religious community and not an issue of legality. (Interestingly not only would this allow a guy couple to have a civil union equal in all legal ways to the civil union or a hetero couple but it would allow the FLDS to practice polygamy of marriage, but they would only be entitled to a single civil union. Could an older polygamist marry a 12 year old girl? Maybe that would be up to the religious authorities but there are some other issues there like informed consent and sex with minors laws must still apply. Civil unions anyway should have a minimum age requirements, like 18 or something, if the government does not think you can fight or consume porn you probably shouldn’t be able to join yourself to another person.)

So, that’s the idea. Marriage is a religious institution so it should be removed from the legal world in the US as it violates the principle of separation of Church and State. Replace the legal side of it with a civil union that does not discriminate based on sex. Plenty here for the lawyer to thrash out and argue over, but I think it’s a good solution to the issue.

Categories
photography

Old Changi Hospital, Singapore, January 2010

IMG_3610

One more visit to OCH, actually because my sister [flickr.com] was visiting and wanted to take some photos. Glad I went because the building seems on the verge of being off limits; there are post holes all around for what appears to be an imminent fencing off. Additionally the whole building has been cleaned out and whitewashed. Not so spooky anymore without the Satanist graffiti.

You can see the whole Old Changi Hospital, Singapore, January 2010 photoset on Flickr [flickr.com]. See also here [flickr.com] and again [flickr.com] for previous visits.