<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>Vineet Gupta</title> <link>http://www.vineetgupta.com</link> <description>Cloud computing, distributed systems, high scalable systems, mobile-web, real-time web, functional programming, concurrency, algorithms and data structures</description> <lastBuildDate>Thu, 28 Mar 2013 18:05:39 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.0.1</generator> <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/VineetGupta" /><feedburner:info uri="vineetgupta" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><geo:lat>12.56</geo:lat><geo:long>77.38</geo:long><creativeCommons:license>http://creativecommons.org/licenses/by-sa/3.0/</creativeCommons:license><image><link>http://creativecommons.org/licenses/by-sa/3.0/</link><url>http://creativecommons.org/images/public/somerights20.gif</url><title>Some Rights Reserved</title></image><feedburner:emailServiceId>VineetGupta</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><feedburner:feedFlare href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.feedburner.com%2FVineetGupta" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2FVineetGupta" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://feeds.my.aol.com/add.jsp?url=http%3A%2F%2Ffeeds.feedburner.com%2FVineetGupta" src="http://o.aolcdn.com/favorites.my.aol.com/webmaster/ffclient/webroot/locale/en-US/images/myAOLButtonSmall.gif">Subscribe with My AOL</feedburner:feedFlare><feedburner:feedFlare href="http://www.bloglines.com/sub/http://feeds.feedburner.com/VineetGupta" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.feedburner.com%2FVineetGupta" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2FVineetGupta" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2FVineetGupta" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><feedburner:feedFlare href="http://www.plusmo.com/add?url=http%3A%2F%2Ffeeds.feedburner.com%2FVineetGupta" src="http://plusmo.com/res/graphics/fbplusmo.gif">Subscribe with Plusmo</feedburner:feedFlare><feedburner:feedFlare href="http://www.live.com/?add=http%3A%2F%2Ffeeds.feedburner.com%2FVineetGupta" src="http://tkfiles.storage.msn.com/x1piYkpqHC_35nIp1gLE68-wvzLZO8iXl_JMledmJQXP-XTBOLfmQv4zhj4MhcWEJh_GtoBIiAl1Mjh-ndp9k47If7hTaFno0mxW9_i3p_5qQw">Subscribe with Live.com</feedburner:feedFlare><item><title>Offering Choices Considered Harmful</title><link>http://feedproxy.google.com/~r/VineetGupta/~3/NVxEeauMUJA/</link> <comments>http://www.vineetgupta.com/2013/03/offering-choices-considered-harmful/#comments</comments> <pubDate>Sun, 10 Mar 2013 01:04:34 +0000</pubDate> <dc:creator>Vineet Gupta</dc:creator> <category><![CDATA[Uncategorized]]></category><guid isPermaLink="false">http://www.vineetgupta.com/?p=10154</guid> <description>Here&amp;#8217;s something that I wish more people involved in designing consumer software products realized - multiple choices inside a product prevent the user from using the product and make him unhappy. Let me explain why. Continued &amp;#8211; http://softwaredev.quora.com/Offering-Choices-Considered-Harmful</description> <content:encoded><![CDATA[<p>Here&#8217;s something that I wish more people involved in designing consumer software products realized - <em>multiple choices inside a product prevent the user from using the product and make him unhappy</em>. Let me explain why.</p><p>Continued &#8211; <a
href="http://softwaredev.quora.com/Offering-Choices-Considered-Harmful">http://softwaredev.quora.com/Offering-Choices-Considered-Harmful</a></p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/VineetGupta?a=NVxEeauMUJA:8C5DVGjkgeI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/VineetGupta?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VineetGupta?a=NVxEeauMUJA:8C5DVGjkgeI:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/VineetGupta?i=NVxEeauMUJA:8C5DVGjkgeI:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VineetGupta?a=NVxEeauMUJA:8C5DVGjkgeI:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/VineetGupta?i=NVxEeauMUJA:8C5DVGjkgeI:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VineetGupta?a=NVxEeauMUJA:8C5DVGjkgeI:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/VineetGupta?i=NVxEeauMUJA:8C5DVGjkgeI:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VineetGupta?a=NVxEeauMUJA:8C5DVGjkgeI:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/VineetGupta?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/VineetGupta/~4/NVxEeauMUJA" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://www.vineetgupta.com/2013/03/offering-choices-considered-harmful/feed/</wfw:commentRss> <slash:comments>0</slash:comments> <feedburner:origLink>http://www.vineetgupta.com/2013/03/offering-choices-considered-harmful/</feedburner:origLink></item> <item><title>When in Doubt, Iterate Faster</title><link>http://feedproxy.google.com/~r/VineetGupta/~3/E9EPECJMN2M/</link> <comments>http://www.vineetgupta.com/2013/03/when-in-doubt-iterate-faster/#comments</comments> <pubDate>Sun, 03 Mar 2013 00:58:04 +0000</pubDate> <dc:creator>Vineet Gupta</dc:creator> <category><![CDATA[Uncategorized]]></category><guid isPermaLink="false">http://www.vineetgupta.com/?p=10152</guid> <description>There is a little something that most people who are in the business of creating software understand, but outsiders seldom know. It is this – in software development you cannot get things right the first time. Continued - http://softwaredev.quora.com/When-in-Doubt-Iterate-Faster</description> <content:encoded><![CDATA[<p>There is a little something that most people who are in the business of creating software understand, but outsiders seldom know. It is this – <em>in software development you cannot get things right the first time</em>.</p><p>Continued - <a
href="http://softwaredev.quora.com/When-in-Doubt-Iterate-Faster">http://softwaredev.quora.com/When-in-Doubt-Iterate-Faster</a></p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/VineetGupta?a=E9EPECJMN2M:9QLBDYfQa-E:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/VineetGupta?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VineetGupta?a=E9EPECJMN2M:9QLBDYfQa-E:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/VineetGupta?i=E9EPECJMN2M:9QLBDYfQa-E:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VineetGupta?a=E9EPECJMN2M:9QLBDYfQa-E:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/VineetGupta?i=E9EPECJMN2M:9QLBDYfQa-E:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VineetGupta?a=E9EPECJMN2M:9QLBDYfQa-E:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/VineetGupta?i=E9EPECJMN2M:9QLBDYfQa-E:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VineetGupta?a=E9EPECJMN2M:9QLBDYfQa-E:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/VineetGupta?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/VineetGupta/~4/E9EPECJMN2M" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://www.vineetgupta.com/2013/03/when-in-doubt-iterate-faster/feed/</wfw:commentRss> <slash:comments>0</slash:comments> <feedburner:origLink>http://www.vineetgupta.com/2013/03/when-in-doubt-iterate-faster/</feedburner:origLink></item> <item><title>Moving blog to Quora</title><link>http://feedproxy.google.com/~r/VineetGupta/~3/xslWzkIyy4c/</link> <comments>http://www.vineetgupta.com/2013/03/moving-blog-to-quora/#comments</comments> <pubDate>Fri, 01 Mar 2013 19:40:15 +0000</pubDate> <dc:creator>Vineet Gupta</dc:creator> <category><![CDATA[Uncategorized]]></category><guid isPermaLink="false">http://www.vineetgupta.com/?p=10150</guid> <description>Why does one write? So that others read. And react to what you have written. Now while I get a fairly steady volume on this site, it is nothing to write home about, which is not surprising given that I rarely post anyway. Of late, I have been thinking of posting more often &amp;#8211; mostly &lt;a
href='http://www.vineetgupta.com/2013/03/moving-blog-to-quora/'&gt;[...]&lt;/a&gt;</description> <content:encoded><![CDATA[<p>Why does one write? So that others read. And react to what you have written. Now while I get a fairly steady volume on this site, it is nothing to write home about, which is not surprising given that I rarely post anyway.</p><p>Of late, I have been thinking of posting more often &#8211; mostly about my learnings in building software products. But you know, if you write you want people to read. Now coincidentally, Quora has just recently <a
href="http://blog.quora.com/Introducing-Blogs-on-Quora">launched a blogging platform</a>. I have been in love with Quora since a while. It has a highly knowledgeable audience, which is very engaged. And it is viral &#8211; as people comment and upvote your content, more people get to discover it.</p><p>And therefore I have decided to switch over my writing to Quora. The tech content would go on <a
href="http://softwaredev.quora.com/">http://softwaredev.quora.com/</a> and the non-tech ones on <a
href="http://www.quora.com/Vineet-Gupta/Posts">http://www.quora.com/Vineet-Gupta/Posts</a>. Or at least that&#8217;s the plan.</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/VineetGupta?a=xslWzkIyy4c:EwwpDPsLo0I:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/VineetGupta?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VineetGupta?a=xslWzkIyy4c:EwwpDPsLo0I:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/VineetGupta?i=xslWzkIyy4c:EwwpDPsLo0I:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VineetGupta?a=xslWzkIyy4c:EwwpDPsLo0I:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/VineetGupta?i=xslWzkIyy4c:EwwpDPsLo0I:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VineetGupta?a=xslWzkIyy4c:EwwpDPsLo0I:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/VineetGupta?i=xslWzkIyy4c:EwwpDPsLo0I:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VineetGupta?a=xslWzkIyy4c:EwwpDPsLo0I:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/VineetGupta?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/VineetGupta/~4/xslWzkIyy4c" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://www.vineetgupta.com/2013/03/moving-blog-to-quora/feed/</wfw:commentRss> <slash:comments>0</slash:comments> <feedburner:origLink>http://www.vineetgupta.com/2013/03/moving-blog-to-quora/</feedburner:origLink></item> <item><title>App Hub Annual Membership Cancellation</title><link>http://feedproxy.google.com/~r/VineetGupta/~3/EwYvCZFImuQ/</link> <comments>http://www.vineetgupta.com/2013/01/app-hub-annnual-membership-cancellation/#comments</comments> <pubDate>Tue, 01 Jan 2013 10:35:39 +0000</pubDate> <dc:creator>Vineet Gupta</dc:creator> <category><![CDATA[Uncategorized]]></category><guid isPermaLink="false">http://www.vineetgupta.com/?p=10136</guid> <description>My new year has started on an interesting note &amp;#8211; I received an email today morning from Microsoft indicating that our App Hub annual subscription has been cancelled: This was surprising since I most certainly did not cancel the subscription. Note that the mail provides no context as to how this cancellation took place &amp;#8211; no &lt;a
href='http://www.vineetgupta.com/2013/01/app-hub-annnual-membership-cancellation/'&gt;[...]&lt;/a&gt;</description> <content:encoded><![CDATA[<p>My new year has started on an interesting note &#8211; I received an email today morning from Microsoft indicating that our App Hub annual subscription has been cancelled:</p><p><img
class="alignnone" title="Cancellation of App Hub Subscription" src="https://public.bay.livefilestore.com/y1pfprknZUVc3ZCiik2LCggUHREkpJcO0U9lzXeQe3QbKv72_lcBcHXchRzd1BtCtIkHl-4zl_IqNMTllkZ1uxykw/Confirmation_of_cancellation_of_app_hub_membership.jpg?psid=1" alt="Cancellation of App Hub Subscription" width="738" height="442" /></p><p>This was surprising since I most certainly did not cancel the subscription. Note that the mail provides no context as to how this cancellation took place &#8211; no tracking id, order-id, issue-id, etc.  It just says that it is confirmed that the subscription is cancelled.</p><p>I was worried that this may compromise our ability to publish updates to <a
href="http://www.windowsphone.com/en-us/store/app/talk-to/f5722c63-e94c-40b8-bc14-2bc374c18188">Talk.To for Windows Phone</a>. In fact, just two weeks back I had renewed subscription to our Windows Developer account:</p><p><img
class="alignnone" title="Confirmation of Developer Account" src="https://public.bay.livefilestore.com/y1pPnpyodfYQkKrbSNpLOvmDKpExJD2RlLg_yINHv1JlM9Z-rHy0DDtIjuYRXud4VWlC0advYPoutBhnWB0jPWF1w/Confirmation_of_developer_account.jpg?psid=1" alt="Confirmation of Developer Account" width="761" height="372" /></p><p>So I quickly logged into the marketplace to check what&#8217;s wrong and saw that there are two subscription options there:</p><p><img
class="alignnone" title="Two Types of Subscriptions" src="https://hsp4ng.bay.livefilestore.com/y1pyG8hzNssoL1Ffds733zItGQhokmQ5F29jdK8QEfzh_Idfvb32vsha4i20AARmObmmOj8wb6IyRGOLsnLBrcN9KwIDTgXUJes/two_subscriptions.jpg?psid=1" alt="Two Types of Subscriptions" width="848" height="387" /></p><p>The Windows Store Developer account was valid, but the App Hub Annual Membership was expired. Do I need one or both? If one, which one? Note that there is not much to distinguish between the two:</p><p><strong>App Hub Annual Membership:</strong></p><div><p>Be a part of a vibrant community of app and game developers for Windows Phone. App Hub has the tools, the content, and the community you need to create and publish amazing apps and games for Windows Phone 7. With an annual subscription of 4500 INR (no taxes charged), your subscription enables you to publish Windows Phone apps using Silverlight or the XNA Framework to the Windows Phone Marketplace.</p></div><div><strong>Windows Store Developer Account:</strong></div><div><p>Become a Windows Store developer, and put your apps at the fingertips of millions of Windows 8 users all over the world. This account gives you access to all the tools you need to submit and publish your app on the Windows Store, plus detailed reports that you can use to track the performance of each app.</p><p>So I contacted support, where I was finally rescued by the helpful Jeremiah:</p><p><img
class="alignnone" title="Chat Excerpt" src="https://public.bay.livefilestore.com/y1psli4VFHDrtVwsaQpupKmL_p5uGoBpPGmej6Y3aCPc4Vklm-H_PRY77FpHYSbqNH5F9y2_wL9qXYoruJ0aSQ1fA/chat_excerpt.jpg?psid=1" alt="Chat Excerpt" width="828" height="189" /></p><p>Key takeaways:</p><ul><li>Apphub membership subscription has been discontinued by Microsoft and it has been divided into separate sites, Xbox LIVE Indie Games and the Windows Phone Dev Center</li><li>The Windows Developer account is basically the subscription for Windows Phone</li><li>As a Windows Phone publisher you only need to have a Windows Developer account</li></ul></div><p>Now apparently Microsoft had announced some changes in Aug 2012 of App Hub transitioning over to Windows Phone Dev Center. I vaguely recall the announcement, but it seemed more like a branding change &#8211; I did not realize that it would lead to mails regarding account cancellation and such.</p><p>What does not help is:</p><p>1) The mail is a confirmation of subscription cancellation with no reference to how the cancellation took place, leave alone mentioning that this is part of an automated process and in what scenarios should a customer take some action.</p><p>2) On the <a
href="https://dev.windowsphone.com/en-us/dashboard">Dashboard</a>, there is a message that says that Subscription Status is <a
href="https://dev.windowsphone.com/en-us/account">Approaching renewal</a></p><p><img
class="alignnone" title="Dashboard Subscription Status: Approaching renewal" src="https://public.bay.livefilestore.com/y1pL_qkqK6gw_YBoE3cDAC3049SAQhrKb_XZFuB8wIEBsM-Lcig8Iomr5jfiYgoDAte0_ivZqZ_yhxkcYTowqbvfg/dashboard-expiration.JPG?psid=1" alt="Dashboard Subscription Status: Approaching renewal" width="670" height="166" /></p><p>3) If you click on that link, it takes you to <a
href="https://dev.windowsphone.com/en-us/account">Account Summary</a> where you are prompted to Renew your subscription.</p><p><img
class="alignnone" title="Account Summary - Prompt to Renew Subscription" src="https://public.bay.livefilestore.com/y1pJQmlhfnh-S23sUgYn2SI7vG2LdwEEFZzSiYhO_JQa69BIAkkjAT4V2WaSuSkhT-npO6A7nUEqBXfacUh27wLzA/account-status.JPG?psid=1" alt="Account Summary - Prompt to Renew Subscription" width="749" height="151" /></p><p>4) However, you have just renewed the windows developer account subscription and it shows correctly under https://commerce.microsoft.com/PaymentHub/Subscription?accountid=&lt;your id&gt; as being <em>11 months away</em>!</p><p><img
class="alignnone" title="Subscriptions Options correct status" src="https://public.bay.livefilestore.com/y1pKWHRwx14iMViC974enh3mycjM3Oi0gmbDnuNjOFRVSDZqHgHuNoHQ-ofLbbi9eD00_MKnNeLNbu1lSqbQf3iHw/windows-store-dev-account-expiration.jpg?psid=1" alt="Subscriptions Options correct status" width="836" height="378" /></p><p>5) So you think that perhaps you need both subscriptions since in any case the descriptions are similar &#8211; you cannot tell which one you do not need.</p><p>Could have been much better handled.</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/VineetGupta?a=EwYvCZFImuQ:08gv4gFA8SE:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/VineetGupta?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VineetGupta?a=EwYvCZFImuQ:08gv4gFA8SE:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/VineetGupta?i=EwYvCZFImuQ:08gv4gFA8SE:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VineetGupta?a=EwYvCZFImuQ:08gv4gFA8SE:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/VineetGupta?i=EwYvCZFImuQ:08gv4gFA8SE:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VineetGupta?a=EwYvCZFImuQ:08gv4gFA8SE:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/VineetGupta?i=EwYvCZFImuQ:08gv4gFA8SE:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VineetGupta?a=EwYvCZFImuQ:08gv4gFA8SE:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/VineetGupta?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/VineetGupta/~4/EwYvCZFImuQ" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://www.vineetgupta.com/2013/01/app-hub-annnual-membership-cancellation/feed/</wfw:commentRss> <slash:comments>0</slash:comments> <feedburner:origLink>http://www.vineetgupta.com/2013/01/app-hub-annnual-membership-cancellation/</feedburner:origLink></item> <item><title>cygwin permissions bug on Windows 8</title><link>http://feedproxy.google.com/~r/VineetGupta/~3/xsIuBM_k_WQ/</link> <comments>http://www.vineetgupta.com/2012/12/cygwin-permissions-bug-on-windows-8/#comments</comments> <pubDate>Tue, 25 Dec 2012 08:27:49 +0000</pubDate> <dc:creator>Vineet Gupta</dc:creator> <category><![CDATA[Programming]]></category><guid isPermaLink="false">http://www.vineetgupta.com/?p=10132</guid> <description>I recently upgraded to Windows 8, installed cygwin, copied my keys and config files, etc. only to find that things stopped working. Try ssh git@github.com and you get: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: UNPROTECTED PRIVATE KEY FILE! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Permissions 0660 for '/home/Vineet/.ssh/id_rsa' are too open. It is required that your private key files are NOT accessible &lt;a
href='http://www.vineetgupta.com/2012/12/cygwin-permissions-bug-on-windows-8/'&gt;[...]&lt;/a&gt;</description> <content:encoded><![CDATA[<p>I recently upgraded to Windows 8, installed cygwin, copied my keys and config files, etc. only to find that things stopped working.</p><p>Try <code>ssh git@github.com</code> and you get:</p><p><code>@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@<br
/> @         WARNING: UNPROTECTED PRIVATE KEY FILE!          @<br
/> @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@<br
/> Permissions 0660 for '/home/Vineet/.ssh/id_rsa' are too open.<br
/> It is required that your private key files are NOT accessible by others.<br
/> This private key will be ignored.<br
/> bad permissions: ignore key: /home/Vineet/.ssh/id_rsa<br
/> Permission denied (publickey).<br
/> </code></p><p>You check permissions and find out:<br
/> <code>-rw-rw----  1 Vineet None  1704 Dec 23 22:57 id_rsa</code></p><p>So you run:<br
/> <code>$ chmod 600 ~/.ssh/id_rsa</code></p><p>You expect the permission on the file to change, but it does not.  The reason is that the group in cygwin is set to &#8216;None&#8217; whereas it should be set to &#8216;Users&#8217;</p><p>The quick fix is to change the group on all existing entries:<br
/> <code>$ chgrp -R Users ~/.ssh</code>.</p><p>Now run:<br
/> <code>$ chmod 600 ~/.ssh/id_rsa</code>,</p><p>This time the permission does change:<br
/> <code>-rw-------  1 Vineet Users  1704 Dec 23 22:57 id_rsa</code></p><p>You can now ssh successfully. However, every time you create a new file, the group is set to None and you keep running into the issue of wrong permissions. Here&#8217;s how you can fix the root cause:</p><p>1) Check the group Id of the &#8216;Users&#8217; group in /etc/group &#8211; it is the third field on the line starting with &#8216;Users&#8217;:<br
/> <code>$ cat /etc/group | egrep '^Users:' | cut -f3 -d':'</code><br
/> In my case the value was 545</p><p>2) Check the primary group for your user in /etc/passwd &#8211; it is the fourth field on the line starting with &lt;your username&gt;<br
/> <code>$ cat /etc/passwd | egrep '^Vineet:' | cut -f4 -d':'</code>.<br
/> In my case the value was 513 (which was the value for the &#8216;None&#8217; group in /etc/group).</p><p>3) Change this value to the one found in the previous step for &#8216;Users&#8217; (545 in this example)</p><p>4) Exit cygwin and restart</p><p>Create a new file and the group should now be set to &#8216;Users&#8217; by default. You should no longer get any permission errors.</p><p>Figuring out all this and fixing it took me well over 2 hours and all because of a silly bug in cygwin. I hope they fix it soon.</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/VineetGupta?a=xsIuBM_k_WQ:jPm3H-ylQxk:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/VineetGupta?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VineetGupta?a=xsIuBM_k_WQ:jPm3H-ylQxk:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/VineetGupta?i=xsIuBM_k_WQ:jPm3H-ylQxk:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VineetGupta?a=xsIuBM_k_WQ:jPm3H-ylQxk:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/VineetGupta?i=xsIuBM_k_WQ:jPm3H-ylQxk:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VineetGupta?a=xsIuBM_k_WQ:jPm3H-ylQxk:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/VineetGupta?i=xsIuBM_k_WQ:jPm3H-ylQxk:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VineetGupta?a=xsIuBM_k_WQ:jPm3H-ylQxk:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/VineetGupta?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/VineetGupta/~4/xsIuBM_k_WQ" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://www.vineetgupta.com/2012/12/cygwin-permissions-bug-on-windows-8/feed/</wfw:commentRss> <slash:comments>5</slash:comments> <feedburner:origLink>http://www.vineetgupta.com/2012/12/cygwin-permissions-bug-on-windows-8/</feedburner:origLink></item> <item><title>We all owe big to Dennis Ritchie</title><link>http://feedproxy.google.com/~r/VineetGupta/~3/ER3LQLrIUtQ/</link> <comments>http://www.vineetgupta.com/2011/10/we-all-owe-big-to-dennis-ritchie/#comments</comments> <pubDate>Thu, 13 Oct 2011 21:27:11 +0000</pubDate> <dc:creator>Vineet Gupta</dc:creator> <category><![CDATA[Personal]]></category><guid isPermaLink="false">http://www.vineetgupta.com/?p=10108</guid> <description>I just came back from IIT Guwahati and discovered that Dennis Ritchie has passed away Most people would know of Dennis Ritchie as the person who invented C and Unix. What most folks do not realize is how profound C and Unix were when they were created and what amazing impact they have had on &lt;a
href='http://www.vineetgupta.com/2011/10/we-all-owe-big-to-dennis-ritchie/'&gt;[...]&lt;/a&gt;</description> <content:encoded><![CDATA[<p>I just came back from IIT Guwahati and discovered that Dennis Ritchie has passed away</p><p>Most people would know of Dennis Ritchie as the person who invented C and Unix. What most folks do not realize is how profound C and Unix were when they were created and what amazing impact they have had on the industry.</p><p>Consider this &#8211; before C, you had to program directly to the instruction set of the machine you were programming on. Today when most hardware happens to be x86 or ARM, this seems simple, but back then, the variety of hardware was far more. And this hardware was different not just in terms of instruction sets, but also in terms of information representation, memory addressing, etc. Sure enough there were languages like Fortran and COBOL which could do math and data, but there was no general purpose language which could produce programs that could compete in terms of performance with custom code written for the hardware. Writing a portable program, much less a portable operating system was un-imaginable.</p><p>And yet, Dennis Ritchie imagined just such a world and invented a highly performant, high level programming language and then used that to write an operating system which could be ported to any hardware. This one change meant that programmers did not have to create a new OS for every new piece of hardware that got thrown at them &#8211; they could take for granted a set of tools, calls and programs, as being available and could spend time going up the value chain and doing more interesting things than just re-inventing the wheel. The result was a spurt of innovation and growth which allowed the industry to grow exponentially into a myriad different directions leading to the world we are in.</p><p>If you are a programmer, you owe a lot to Ritchie, whether you have ever programmed in C or worked on Unix or not.</p><p>[Edit: Bjarne Stroustrup expresses the same sentiment way more eloquently: <a
href="http://herbsutter.com/2011/10/12/dennis-ritchie/">http://herbsutter.com/2011/10/12/dennis-ritchie/</a></p><p>Most of us are happy to settle for incremental change. People like Ritchie don’t, and that’s what sets them apart.]</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/VineetGupta?a=ER3LQLrIUtQ:_DBykPKFuT4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/VineetGupta?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VineetGupta?a=ER3LQLrIUtQ:_DBykPKFuT4:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/VineetGupta?i=ER3LQLrIUtQ:_DBykPKFuT4:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VineetGupta?a=ER3LQLrIUtQ:_DBykPKFuT4:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/VineetGupta?i=ER3LQLrIUtQ:_DBykPKFuT4:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VineetGupta?a=ER3LQLrIUtQ:_DBykPKFuT4:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/VineetGupta?i=ER3LQLrIUtQ:_DBykPKFuT4:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VineetGupta?a=ER3LQLrIUtQ:_DBykPKFuT4:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/VineetGupta?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/VineetGupta/~4/ER3LQLrIUtQ" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://www.vineetgupta.com/2011/10/we-all-owe-big-to-dennis-ritchie/feed/</wfw:commentRss> <slash:comments>1</slash:comments> <feedburner:origLink>http://www.vineetgupta.com/2011/10/we-all-owe-big-to-dennis-ritchie/</feedburner:origLink></item> <item><title>The True Legacy of Steve Jobs</title><link>http://feedproxy.google.com/~r/VineetGupta/~3/-yIeHSX_4nY/</link> <comments>http://www.vineetgupta.com/2011/10/the-true-legacy-of-steve-jobs/#comments</comments> <pubDate>Thu, 06 Oct 2011 03:46:25 +0000</pubDate> <dc:creator>Vineet Gupta</dc:creator> <category><![CDATA[Personal]]></category><guid isPermaLink="false">http://www.vineetgupta.com/?p=10102</guid> <description>Steve Jobs passed away today &amp;#8211; I woke up and read the news on my iPhone, like much of the world. I never thought I would be so affected by the passing away of someone I never knew personally. But if you are in the world of tech and developing consumer products, it is not &lt;a
href='http://www.vineetgupta.com/2011/10/the-true-legacy-of-steve-jobs/'&gt;[...]&lt;/a&gt;</description> <content:encoded><![CDATA[<p>Steve Jobs passed away today &#8211; I woke up and read the news on my iPhone, like much of the world.</p><p>I never thought I would be so affected by the passing away of someone I never knew personally. But if you are in the world of tech and developing consumer products, it is not possible to have not thought about life as Steve Jobs &#8211; how his brain functions, how he figures out what should be built, how he sets the bar, how he hires and build teams, how he delves upon every aspect of the product, &#8230; you wish you had 0.1% of his ability, you wish you could be more like him, since being him means creating profound impact, and that is what you are really here for.</p><p>And this I believe is his true legacy. The products he helped create would have a shelf life of maybe a decade, Apple as a company would be perhaps super successful for another 2-3 decades, but what would inspire generations of current and future entrepreneurs, programmers and designers is the way he set about building products:</p><ul><li>leapfrogging the current state of the art, not incremental change</li><li>relentless focus on the user</li><li>not settling for less than perfection</li></ul><p>This approach to building products is his true legacy, and for that, the world would be a better place.</p><div></div> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/VineetGupta?a=-yIeHSX_4nY:lm3HinE0fls:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/VineetGupta?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VineetGupta?a=-yIeHSX_4nY:lm3HinE0fls:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/VineetGupta?i=-yIeHSX_4nY:lm3HinE0fls:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VineetGupta?a=-yIeHSX_4nY:lm3HinE0fls:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/VineetGupta?i=-yIeHSX_4nY:lm3HinE0fls:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VineetGupta?a=-yIeHSX_4nY:lm3HinE0fls:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/VineetGupta?i=-yIeHSX_4nY:lm3HinE0fls:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VineetGupta?a=-yIeHSX_4nY:lm3HinE0fls:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/VineetGupta?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/VineetGupta/~4/-yIeHSX_4nY" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://www.vineetgupta.com/2011/10/the-true-legacy-of-steve-jobs/feed/</wfw:commentRss> <slash:comments>2</slash:comments> <feedburner:origLink>http://www.vineetgupta.com/2011/10/the-true-legacy-of-steve-jobs/</feedburner:origLink></item> <item><title>Deciphering Complex C Declarations</title><link>http://feedproxy.google.com/~r/VineetGupta/~3/SoclXVUdbk4/</link> <comments>http://www.vineetgupta.com/2011/03/deciphering-complex-c-declarations/#comments</comments> <pubDate>Thu, 17 Mar 2011 12:47:40 +0000</pubDate> <dc:creator>Vineet Gupta</dc:creator> <category><![CDATA[Languages]]></category> <category><![CDATA[C declarations]]></category><guid isPermaLink="false">http://www.vineetgupta.com/?p=10094</guid> <description>As I have mentioned in earlier posts, we are building a x-platform mobile chat client. One of the platforms is iPhone and that means that the team is having to learn Objective C, and therefore C. Last couple of days, I have been spending time  helping my team understand and appreciate C better. Yesterday, we &lt;a
href='http://www.vineetgupta.com/2011/03/deciphering-complex-c-declarations/'&gt;[...]&lt;/a&gt;</description> <content:encoded><![CDATA[<p>As I have mentioned in <a
href="http://www.vineetgupta.com/2011/03/mobile-platforms-part-1-android/"> earlier</a> <a
href="http://www.vineetgupta.com/2011/03/mobile-platforms-part-2-blackberry/"> posts</a>, we are building a x-platform mobile chat client. One of the platforms  is iPhone and that means that the team is having to learn Objective C, and  therefore C. Last couple of days, I have been spending time  helping my team understand and appreciate C better. Yesterday, we  got really deep on figuring out how to read a C declaration and it was a lot of  fun taking people thru the rules and examples of how to read some complex C  declarations. I am summarizing the key aspects over here.</p><p>PS: Could not cross link to references since there is no authoritative version  of the <a
href="http://en.wikipedia.org/wiki/C99">C-99</a> standard in an HTML  form &#8211; the <a
href="http://www.open-std.org/jtc1/sc22/wg14/www/standards">standard docs</a> are all in <a
href="http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf"> PDF</a>.</p><h3>C Declaration Grammar</h3><p>Understanding a C declaration requires that we understand what elements can a  C declaration have. While I will describe the overall syntax over here, I will  not go into semantics:</p><pre><em>declaration:
	declaration-specifiers init-declarator-list<sub>opt</sub> ;
declaration-specifiers:
	storage-class-specifier declaration-specifiers<sub>opt</sub>
	type-specifier declaration-specifiers<sub>opt</sub>
	type-qualifier declaration-specifiers<sub>opt</sub>
	function-specifier declaration-specifiers<sub>opt</sub>
init-declarator-list:
	init-declarator
	init-declarator-list , init-declarator
init-declarator:
	declarator
	declarator = initializer</em></pre><p>This is what the above grammar is saying:</p><ul><li>A declaration is:<ul><li>declaration-specifiers followed by an optional list of  		init-declarators</li></ul></li><li>The declaration-specifiers are:<ul><li>A storage-class specifier, followed by other optional declaration  		specifiers</li><li>A type-specifier, followed by other optional declaration specifiers</li><li>A type-qualifier, followed by other optional declaration specifiers</li><li>A function-specifier, followed by other optional declaration  		specifiers</li></ul></li><li>List of init-declarators is:<ul><li>An init-declarator</li><li>An init-declarator list, followed by a comma, followed by an  		init-declarator</li></ul></li><li>An init-declarator is:<ul><li>A declarator</li><li>A declarator followed by an assignment operator (=),  followed  		by an initializer</li></ul></li></ul><h3>Declaration Specifiers</h3><p>As per the grammar defined  above, a declaration starts with a declaration specifier. A  declaration-specifier can be:</p><ul><li><strong>Storage-class specifier:</strong> These are: <code>auto</code>, <code>static</code>, <code>extern</code>, <code>register</code> and <code>typedef</code>. Default is <code>auto</code>, so if nothing is specified, <code>auto</code> is assumed.</li><li><strong>Type-specifier:</strong> A type-specifier is one of the following. Default is <code>int</code><ul><li><code>void</code></li><li><code>char</code></li><li><code>signed char</code></li><li><code>unsigned char</code></li><li><code>short</code>, <code>signed short</code>, <code>short int</code>, or <code>signed short int</code></li><li><code>unsigned short</code> or <code>unsigned short int</code></li><li><code>int</code>, <code>signed</code> or <code>signed int</code></li><li><code>unsigned</code> or <code>unsigned int</code></li><li><code>long</code>, <code>signed long</code>, <code>long int</code> or <code>signed long int</code></li><li><code>unsigned long</code> or <code>unsigned long int</code></li><li><code>long long</code>, <code>signed long long</code>, <code>long long int</code>, or <code>signed long long int</code></li><li><code>unsigned long long</code> or <code>unsigned long long int</code></li><li><code>float</code></li><li><code>double</code></li><li><code>long double</code></li><li><code>_Bool</code></li><li><code>float _Complex</code></li><li><code>double _Complex</code></li><li><code>long double _Complex</code></li><li><em>struct-or-union-specifier</em></li><li><em>enum-specifier</em></li><li><em>typedef-name</em></li></ul></li><li><strong>Type-Qualifer:</strong> Applicable only to <a
href="http://en.wikipedia.org/wiki/Value_(computer_science)">l-values</a>: <code>const</code>, <code>volatile</code>, <code>restrict</code></li><li><strong>Function-specifier:</strong> There is only one function specifier: <code>inline</code></li></ul><h3>Declarators</h3><p>What follows a declaration-specifier is a init-declarator-list &#8211; a comma  separated sequence of declarators that may optionally be initialized. A declarator [2] is defined as:</p><pre><em>declarator:
	pointer<sub>opt</sub> direct-declarator
direct-declarator:
	identifier
	( declarator )
	direct-declarator [ type-qualifier-list<sub>opt</sub> assignment-expression<sub>opt</sub> ]
	direct-declarator [ static type-qualifier-list<sub>opt</sub> assignment-expression ]
	direct-declarator [ type-qualifier-list static assignment-expression ]
	direct-declarator [ type-qualifier-list<sub>opt</sub> * ]
	direct-declarator ( parameter-type-list )
	direct-declarator ( identifier-list<sub>opt</sub> )
pointer:
	* type-qualifier-list<sub>opt</sub>
	* type-qualifier-list<sub>opt</sub> pointer
type-qualifier-list:
	type-qualifier
	type-qualifier-list type-qualifier
parameter-type-list:
	parameter-list
	parameter-list , ...
parameter-list:
	parameter-declaration
	parameter-list , parameter-declaration
parameter-declaration:
	declaration-specifiers declarator
	declaration-specifiers abstract-declarator<sub>opt</sub>
identifier-list:
	identifier
	identifier-list , identifier</em></pre><p>We can break down the above grammar the same way we did for the grammar of a  declaration, but I&#8217;m gonna skip that and give some examples of declarators, just  to give an idea of what declarators are supposed to be:</p><ul><li><code>i</code> &#8211; An identifier (and hence a direct-declarator)</li><li><code>i, j</code> &#8211; A list of identifiers</li><li><code>i = 10</code> &#8211; An Identifer followed by an assignment expression</li><li><code>*p</code> &#8211; A pointer declarator</li><li><code>* const p</code> &#8211; A pointer declarator with a type-qualifer (<code>const</code>)</li><li><code>a[10]</code> &#8211; An array declarator with a constant size</li><li><code>a[*]</code> &#8211; An array declarator with a variable size</li><li><code>a[]</code> &#8211; An array declarator with an unspecified size &#8211; the size will need to be defined somewhere else</li><li><code>f()</code> &#8211; A function declarator</li><li><code>f(void)</code> &#8211; A function declarator with no parameters</li><li><code>f(int i)</code> &#8211; A function declarator with a parameter</li><li><code>f(int i, int j)</code> &#8211; A function declarator with a parameter-list</li></ul><h3>Structure of a Declaration</h3><p>Now that we have developed an idea of declaration-specifiers and declarators,  we can see that the overall structure of a declaration is of the following form:</p><ol><li>One or more declaration-specifiers followed by</li><li>One or more declarators (separated by commas)</li></ol><p>However, not all combinations are valid. The following are not allowed:</p><pre>f()[] // function can't return an array
f()() // function can't return a function
a[]() // array can't hold a function</pre><p>The following, however, are allowed:</p><pre>(* f())[] // function returning pointer to an array
(* f())() // function returning pointer to a function
(* a[])() // array holding pointers to functions</pre><p>If you are flummoxed by the last three examples of combining pointers,  functions and arrays, you are not alone. Such declarations can look scary till  you develop a technique to start deciphering them. In order to do that however,  we need to know the basic order of precedence</p><h3>Operator Precedence</h3><ol><li>Parentheses grouping together parts of a declaration</li><li>Postfix operators: parentheses (for a function), square brackets (for an  	array)</li><li>Prefix operator: Asterisk (for a pointer)</li></ol><p>Here are some examples of how this order applies:</p><table
style="width: 100%;"><tbody><tr><td>Declaration</td><td>Same as</td><td>Not Same as</td></tr><tr><td><code>int * f();</code></td><td><code>int * (f());</code></td><td><code>int (* f());</code></td></tr><tr><td><code>int * a[];</code></td><td><code>int * (a[]);</code></td><td><code>int (* a[]);</code></td></tr></tbody></table><p>Now the way to use these rules is as follows:</p><ol><li>Read from left to right</li><li>For the first identifier you encounter (or if there is no identifier,  	then look for the inner-most construct), look to the immediate right<ul><li>If there is nothing, or if you have a closing parenthesis, go to 3</li><li>Otherwise you have a function declarator indicated by () or an array  		declarator indicated by [] to the right of the identifier</li><li>Read left to right &#8211; you will have a &#8220;function returning&#8221; or &#8220;array  		of&#8221;</li><li>This would typically end with a right parenthesis, or the end of the  		declarator (semi-colon or assignment)</li></ul></li><li>Look to the left<ul><li>If you find nothing on the left, or if you find an opening  		parenthesis, go to 4</li><li>Otherwise you have a pointer declarator indicated by an asterisk to  		the left of the identifier. Read right to left &#8211; you will get a &#8220;pointer  		to&#8221;</li><li>This would end with a left parenthesis, or start of declarator</li></ul></li><li>At this point you have either<ul><li>A complete declarator &#8211; then you are done</li><li>Or an expression in parenthesis &#8211; go back to step 2.</li></ul></li></ol><p>If you did not realize this on reading the above description, what we are  really doing in steps 2 and 3 is to convert the C declaration into a postfix  expression by taking into account the lower predence of the asterisk. This same  approach is used in the <a
href="http://www.cdecl.org/">cdecl</a> program given in K&amp;R.</p><p>This will become clear with a few examples:</p><pre>int * f();</pre><ul><li>Start with identifer &#8211; f</li><li>Parenthesis to the right &#8211; &#8220;function returning&#8221;</li><li>Asterisk to the left &#8211; &#8220;pointer to&#8221;</li><li>int</li></ul><p>The postfix expression is:</p><pre>f () * int // "f is" "a function returning" "pointer to int"</pre><p>Here are a few more examples:</p><pre>int * a[10];
// postfix expression: a [10] * int
// "a is" "array of 10" "pointers to int"</pre><pre>int (* a)[10]
// postfix: a * [10] int
// "a is" "pointer to" "array of 10" "int"</pre><pre>int **p;
// postfix: p * * int
// "p is" "pointer to" "pointer to" int</pre><pre>int **p[10];
// postfix: p [10] * * int
// "p is" "array of 10" "pointer to" "pointer to" int</pre><pre>int *f();
// postfix: f () * int
// "f is" "function returning" "pointer to" int</pre><pre>int (*f)();
// postfix: f * () int
// "f is" "a pointer to" "function returning" int</pre><pre>int (* vtable[])();
// postfix: vtable [] * () int
// vtable is an array of pointer to function returning int</pre><pre>int (* a[])(int, int);
// postfix: a [] * (int, int) int
// a is an array of pointer to function returning int
// and taking (int, int) as parameters</pre><h3>Applying Type-Qualifiers</h3><p>The way you apply a type-qualifier (<code>const</code>, <code>volatile</code>) is that:</p><ol><li>If next to a type-specifer, it applies to the type-specifier</li><li>Otherwise applies to the asterisk (pointer) on its immediate left</li></ol><p>Examples:</p><pre>const int * p;
// postfix: p * const int
// p is a pointer to a const int</pre><pre>int const * p;
// postfix: p * const int
// p is a pointer to a const int</pre><pre>int * const p;
// postfix: p const * int
// p is a const pointer to int</pre><pre>int * const * p;
// postfix: p * const * int
// p is a pointer to a const pointer to int</pre><pre>int * const * (* p)();
// postfix: p * () * const * int
// p is a pointer to a function returning a
// pointer to const-pointer-to-int</pre><h3>Abstract Declarators</h3><p>An abstract declarator is a declarator without an identifer. However, lack of  an identifier does not mean that we can&#8217;t interpret such declarators, since the  missing identifier&#8217;s position can be determined by the placement of (), [] and *  Some examples will help clarify this:</p><pre>int *
// pointer to int</pre><pre>int * [10]
// array of 10 pointers to int</pre><pre>int * (*)
// function returing a pointer to int and taking no arguments</pre><pre>int (*) [10]
// pointer to array of 10 int</pre><pre>int (*) (*)
// pointer to a function returning an int and taking no arguments</pre><p>With this background, lets tackle this gem from Andrew Koenig&#8217;s C Traps and  Pitfalls (<a
href="http://www.literateprogramming.com/ctraps.pdf">PDF</a>):</p><pre>(*(void(*)())0)();</pre><p>Clearly, we are casting 0 to some type here. The type being:</p><pre>void(*)()</pre><p>We know this type:</p><pre>// postifx: * () void
// pointer to function returning void</pre><p>In the next step, this pointer is de-referenced and then called. So what is  happening here is that zero is being cast to a pointer to a function returning  void, then dereferenced and called!</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/VineetGupta?a=SoclXVUdbk4:sflFZcBsr4g:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/VineetGupta?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VineetGupta?a=SoclXVUdbk4:sflFZcBsr4g:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/VineetGupta?i=SoclXVUdbk4:sflFZcBsr4g:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VineetGupta?a=SoclXVUdbk4:sflFZcBsr4g:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/VineetGupta?i=SoclXVUdbk4:sflFZcBsr4g:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VineetGupta?a=SoclXVUdbk4:sflFZcBsr4g:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/VineetGupta?i=SoclXVUdbk4:sflFZcBsr4g:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VineetGupta?a=SoclXVUdbk4:sflFZcBsr4g:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/VineetGupta?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/VineetGupta/~4/SoclXVUdbk4" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://www.vineetgupta.com/2011/03/deciphering-complex-c-declarations/feed/</wfw:commentRss> <slash:comments>4</slash:comments> <feedburner:origLink>http://www.vineetgupta.com/2011/03/deciphering-complex-c-declarations/</feedburner:origLink></item> <item><title>Mobile Platforms – Part 2 – Blackberry</title><link>http://feedproxy.google.com/~r/VineetGupta/~3/q3t068xNfHc/</link> <comments>http://www.vineetgupta.com/2011/03/mobile-platforms-part-2-blackberry/#comments</comments> <pubDate>Sat, 12 Mar 2011 13:56:34 +0000</pubDate> <dc:creator>Vineet Gupta</dc:creator> <category><![CDATA[Mobile]]></category> <category><![CDATA[Blackberry Java Development]]></category><guid isPermaLink="false">http://www.vineetgupta.com/?p=10081</guid> <description>As I mentioned on my previous post, we are building a x-platform native mobile chat client for Android, iPhone and Blackberry. The earlier post was about the Android platform, this one is on Blackberry. After having gone thru the Android documentation and videos from Google IO, I found the documentation on Blackberry to be somewhat &lt;a
href='http://www.vineetgupta.com/2011/03/mobile-platforms-part-2-blackberry/'&gt;[...]&lt;/a&gt;</description> <content:encoded><![CDATA[<p>As I mentioned on my <a
href="http://www.vineetgupta.com/2011/03/mobile-platforms-part-1-android/"> previous post</a>, we are building a x-platform native mobile chat client  for Android, iPhone and Blackberry. The earlier post was about the Android  platform, this one is on Blackberry.</p><p>After having gone thru the Android  documentation and videos from Google IO, I found the <a
href="http://us.blackberry.com/developers">documentation</a> on Blackberry to  be somewhat disorganized &#8211; it is not easy to get the big picture and grasp key  concepts. You need to go thru a lot of documentation to figure out how things works  together as a system. I also tried to access the materials from <a
href="http://www.blackberrydevcon.com/2010-on-demand"> http://www.blackberrydevcon.com/2010-on-demand</a> but it turned out that it would  require a registration for $ 20. That was a bit of a WTF moment &#8230; I mean, you  want to make money by selling conference materials? Who does that?? Anyway I  proceeded to register on <a
href="https://www.eventreg.com/pls/pg_rim/reg_rim.reg_login?icpid=&amp;ipr_code=ONDNON"> https://www.eventreg.com/pls/pg_rim/reg_rim.reg_login?icpid=&amp;ipr_code=ONDNON</a> and after filling two lengthy forms, was unable to make a payment despite  getting a registration id. I wrote to <a
href="mailto:BlackBerryDEVCON@eventreg.com">BlackBerryDEVCON@eventreg.com</a> with my registration id (this was on 3rd Mar),  but am yet to hear from them. Rather discourgaing for somene starting off on a  new platform.</p><h2>The Blackberry Platform</h2><p>The Blackberry platform consists of the following key components:</p><ul><li><a
href="http://us.blackberry.com/developers/started/">Phone</a>:  	Blackberry phones support two kind of applications:<ul><li><a
href="http://us.blackberry.com/developers/javaappdev/">Java Apps</a>:  		These are native Blackberry apps which can take full advantages of all  		the features available in a Blackberry phone, for example the <a
href="http://us.blackberry.com/developers/blackberrymessenger/">BBM  		API</a>.</li><li><a
href="http://us.blackberry.com/developers/browserdev/index.jsp"> WebWorks Apps</a>: Browser based apps built using HTML, CSS, JS and capable  		of accessing native APIs thru the <a
href="http://us.blackberry.com/developers/browserdev/widgetsdk.jsp"> WebWorks SDK</a>.</li></ul></li><li><a
href="http://us.blackberry.com/developers/tablet/">Tablet</a>:  	One can build playbook tablet applications in two ways:<ul><li><a
href="http://us.blackberry.com/developers/tablet/adobe.jsp">Adobe  		AIR apps</a>: Based on Action Script 3 with a bunch of Blackberry  		specific APIs. Use this to build apps with a <a
href="http://docs.blackberry.com/en/developers/deliverables/24075/UI_APIs_for_Tablet_OS_look_and_feel_1354896_11.jsp"> native look and feel</a>.</li><li><a
href="http://us.blackberry.com/developers/tablet/webworks.jsp"> WebWorks apps</a>: Similar to WebWorks apps for the Blackberry phone.</li></ul></li><li><a
href="http://us.blackberry.com/developers/platform/">Platform Services</a>:  	Bunch of services provided by RIM including <a
href="http://us.blackberry.com/developers/platform/pushapi.jsp">Push</a>, <a
href="http://us.blackberry.com/developers/platform/locateservice/"> Location</a>, <a
href="http://us.blackberry.com/developers/platform/adservices/"> Advertising</a> and <a
href="http://us.blackberry.com/developers/platform/paymentservice.jsp"> Payment</a> services</li><li>Connectivity Services: RIM also provides a couple of connectivity  	services:<ul><li><a
href="http://us.blackberry.com/apps-software/server/">Blackberry  		Enterprise Server (BES)</a>: Enterprises can make their mail  		infrastructure available over the Blackberry network using BES which  		acts as a relay between the mail server and Blackberry&#8217;s NOC co-located  		with a carrier providing Blackberry services. One of the components of  		BES called the <a
href="http://docs.blackberry.com/en/admin/deliverables/7335/BB_MDS_267706_11.jsp"> Mobile Data System (MDS)</a> provides  HTTP and TCP proxies for a  		Blackberry application. This allows a Blackberry device to communicate  		with app / web-servers behind a corporate firewall without using VPN.</li><li><a
href="http://us.blackberry.com/support/software/internet.jsp"> Blackberry Internet Services (BIS)</a>: For individuals, the alternative  		to BES is the BIS. This provides the ability to access mail over POP and  		IMAP email without going thru BES. The service is provided in  		partnership with a carrier.</li></ul></li><li><a
href="http://us.blackberry.com/developers/appworld/distribution.jsp"> AppWorld</a>: The blackberry application store front, similar to the iPhone  	App Store</li></ul><p>This post is specific to Java development for the Blackberry phones.  Moreover, it is specific to Blackberry 5 since <a
href="http://us.blackberry.com/developers/choosingtargetos.jsp">75-85% of app  downloads from the App World are from Blackberry 5 devices</a>.</p><h2>Java ME</h2><p>Native apps on the Blackberry phone are Java apps that run on RIM&#8217;s JVM  implementation. This Java API is based on Java ME with Blackberry adding its own  extensions. If you are new to Java ME like I am, here is a quick review:</p><p>Java ME (Micro Edition) is Java targeted for small devices. It is a  collection of specs and technologies to address the needs of providing a  programming interface to small devices. Since there is a large variety in the  types of devices and their capabilities, it is quite likely that a device  manufacturer would implement some specs and not others, leading to API  fragmentation and hence non-portable code. To address this, Java ME defines  capabilities for devices which are organized into  Configurations, Profiles and Optional APIs:</p><p><img
src="http://developers.sun.com/mobility/getstart/articles/survey/fig1.jpg" alt="Organization of the Java ME technologies" /></p><p>(Organization of the Java ME technologies &#8211; source: <a
href="http://developers.sun.com/mobility/getstart/articles/survey"> http://developers.sun.com/mobility/getstart/articles/survey/</a>)</p><ul><li><strong>Configurations</strong>: A configuration is a specification for  	a virtual machine + some base APIs designed for a specific kind of device,  	based on memory constraints and processor power.<ul><li><a
href="http://jcp.org/en/jsr/detail?id=139">Connected Limited   		Device Configuration (CLDC)</a>: The CLDC is meant for small wireless  		devices with intermittent network connections, like pagers, mobile  		phones and PDAs</li><li><a
href="http://jcp.org/en/jsr/detail?id=218">Connected Device  		Configuration (CDC)</a>:  The CDC is a superset of the CLDC meant for larger devices with  		robust connections, like Set-top boxes and internet appliances.</li></ul></li><li><strong>Profiles:</strong> A profile is more specific than a  	configuration. A profile is based on a configuration and adds APIs for UI,  	Storage, or whatever else is required to develop apps. For CLDC, a profile called <a
href="http://jcp.org/en/jsr/detail?id=118">Mobile Information  		Device Profile (MIDP)</a> is specified. For CDC, there is a hierarchy of profiles:<ul><li><a
href="http://jcp.org/en/jsr/detail?id=219">Foundation Profile</a></li><li><a
href="http://jcp.org/en/jsr/detail?id=217">Personal Basis Profile</a></li><li><a
href="http://jcp.org/en/jsr/detail?id=215">Personal Profile</a></li><li><a
href="http://jcp.org/en/jsr/detail?id=228">Information Module Profile</a></li></ul></li><li><strong>Optional APIs:</strong> A device implementing Java ME may define  	additional optional APIs besides the ones that are defined as a part of a  	Java ME profile.</li></ul><p>Based on the configurations, profiles and optional APIs, Java ME is able to  address a wide variety of small devices including Handsets, Smart-cards and  embedded devices:</p><p><img
src="http://developers.sun.com/mobility/getstart/articles/survey/fig2.jpg" alt="Java ME technologies by device type" width="600" height="242" /></p><p>(Map of the Java ME Universe &#8211; source: <a
href="http://developers.sun.com/mobility/getstart/articles/survey/"> http://developers.sun.com/mobility/getstart/articles/survey/</a>)</p><p>A device implements a stack consisting of a Configuration, Profile and  Optional APIs. For wireless devices like mobile phones, the stack is based on  CLDC, MIDP and some optional APIs. An application targeting the MIDP profile is  called a MIDlet.</p><p><img
src="http://www.oracle.com/ocom/groups/public/@otn/documents/digitalasset/148676.jpg" alt="Stack for Wireless devices" width="358" height="277" /></p><p>(Stack for wireless devices. Source: <a
href="http://www.oracle.com/technetwork/java/javame/tech/technology-139316.html"> http://www.oracle.com/technetwork/java/javame/tech/technology-139316.html</a>)</p><p>As one can imagine, despite the CLDC and MIDP being defined, a lot of  commonly required functionality and the way it is provided remains un-defined,  thus introducing scope for API fragmentation and un-portable code. This was  addressed thru <a
href="http://jcp.org/en/jsr/detail?id=185">JSR 185 &#8211; Java  Technology for the Wireless Industry</a> &#8211; a specification that addresses  fragmentation by defining key APIs and code portability issues by clarifying  spces and providing a suite of compliance tests. JSR 185 consists of CLDC 1.0 or  1.1, MIDP 2.0 and WMA (Windows Messaging API &#8211; <a
href="http://jcp.org/en/jsr/detail?id=120">JSR 120</a> and <a
href="http://jcp.org/en/jsr/detail?id=205">JSR 205</a>), with support for  MMAPI (Mobile Media API &#8211; <a
href="http://jcp.org/en/jsr/detail?id=135">JSR 135</a>)  being optional:</p><p><img
src="http://developers.sun.com/mobility/getstart/images/stack2.jpg" alt="JSR 185 - JTWI Stack" width="330" height="208" /></p><p>(JSR 185 &#8211; JTWI Stack. Source: <a
href="http://developers.sun.com/mobility/getstart/"> http://developers.sun.com/mobility/getstart/</a>)</p><p>This was superseded by the <a
href="http://developers.sun.com/mobility/midp/articles/msaintro/">MSA (Mobile  Services Architecture) specification</a> which defined two stacks: a full stack  of 16 JSRs and a subset of 8 JSRs:</p><p><img
src="http://developers.sun.com/mobility/midp/articles/msaintro/fig1.gif" alt="MSA Stacks" width="359" height="320" /></p><p>(MSA Stacks. Source: <a
href="http://developers.sun.com/mobility/midp/articles/msaintro/"> http://developers.sun.com/mobility/midp/articles/msaintro/</a>)</p><p>Blackberry 5 <a
href="http://docs.blackberry.com/en/developers/deliverables/9095/Java_ME_and_Java_APIs_for_BB_446980_11.jsp"> is based on</a> <a
href="http://jcp.org/en/jsr/detail?id=139">CLDC 1.1</a>, <a
href="http://jcp.org/en/jsr/detail?id=118">MIDP 2.0</a> and is JSR-185 compliant. It also supports the full MSA stack except for JSR 184  (3-D graphics), JSR 180 (SIP) and JSR 229 (Payment). For other JSRs supported by  Blackberry 5, see <a
href="http://docs.blackberry.com/en/developers/deliverables/9095/Support_for_standard_Java_APIs_446981_11.jsp"> http://docs.blackberry.com/en/developers/deliverables/9095/Support_for_standard_Java_APIs_446981_11.jsp</a></p><h2>Blackberry Applications</h2><p>Blackberry applications are of two types:</p><ul><li> <a
href="http://docs.blackberry.com/en/developers/deliverables/9095/MIDlet_applications_446987_11.jsp">MIDlet  	Application</a>: A MIDlet is an application targeting MIDP  	(javax.microedition namespace). Such an app can run on other MIDP 2.0  	compliant phones from other vendors</li><li> <a
href="http://docs.blackberry.com/en/developers/deliverables/9095/BlackBerry_API_applications_647766_11.jsp">Blackberry Java Application</a>:  	A Blackberry Java Application (also called a RIMlet) targets the CLDC, but  	uses Blackberry specific APIs (from the net.rim namespace). Such an app can  	run only on a Blackberry device.</li></ul><p>Unless your code is targeting mulitple Java ME platforms, it makes sense to  build Blackberry Java applications since they tend to be a lot <a
href="http://docs.blackberry.com/en/developers/deliverables/9095/BlackBerry_API_applications_647766_11.jsp">richer</a> than  MIDlets. Specifically, if you want the look and feel of applications that RIM  ships with a Blackberry (also called &#8220;native apps&#8221;), then you should build a  Blackberry Java application by using <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/ui/package-summary.html"> net.rim.device.api.ui</a> and not use <a
href="http://www.blackberry.com/developers/docs/5.0.0api/javax/microedition/lcdui/package-summary.html"> javax.microedition.lcdui</a>. More differences on the UI capabilities of both  frameworks are given on <a
href="http://www.blackberry.com/developers/docs/5.0.0api/UI-summary.html"> http://www.blackberry.com/developers/docs/5.0.0api/UI-summary.html</a>.</p><p>Note that all APIs are always available to all apps. So if your app is using  the Blackberry UI, you can always invoke MIDP APIs. If your app is using the MIDP UI, you can always  invoke Blackberry APIs, but of course doing so would render the application  non-portable. The only exception to this is on mixing UI. The MIDP UI model  allows concurrent access while the Blackberry UI model does not and hence mixing  UI library calls is unsupported.</p><p>In the rest of this post, I would be focussing mostly on the Blackberry Java  Application.</p><h3>Startup</h3><p>A Blackberry application can start in one of the following ways:</p><ol><li>Use clicking an icon on the Home screen</li><li>By another app</li><li>OS starting an app automatically when the device starts</li><li>OS starting an app at a scheduled time</li></ol><p>This startup is managed by an entity called the <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/system/ApplicationManager.html"> Application Manager</a>. An running application can obtain a reference to the  Application Manager by calling <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/system/ApplicationManager.html#getApplicationManager()"> getApplicationManager()</a>, and then, can use this to:</p><ul><li> <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/system/ApplicationManager.html#runApplication(net.rim.device.api.system.ApplicationDescriptor, boolean)"> Run</a> or <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/system/ApplicationManager.html#launchApplication(java.lang.String)"> Launch</a> another application</li><li> <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/system/ApplicationDescriptor.html"> Schedule</a> an application to run at a specific time</li><li> <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/system/ApplicationManager.html#postGlobalEvent(int, long, int, int, java.lang.Object, java.lang.Object)"> Post</a> a global event to the OS</li><li> <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/system/ApplicationManager.html#lockSystem(boolean)"> Lock</a> and <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/system/ApplicationManager.html#unlockSystem()"> Unlock</a> the system</li></ul><p>To start an application, the App Manager creates a new process and a thread  within that process and then starts the main() function on that thread with a  set of input parameters. The parameters are specified in the <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/system/ApplicationDescriptor.html"> application descriptor</a>. It is possible to create multiple descriptors for  the same app and associate them with different icons on the screen, This allows  the <a
href="http://www.blackberry.com/knowledgecenterpublic/livelink.exe/fetch/2000/348583/800901/How_To_-_Setup_an_alternate_entry_point_for_my_application.html?nodeid=800820&amp;vernum=0"> creation of multiple entry points</a> for the same app.</p><h3>Event Processing</h3><p>Once started, an application can choose to do a series of operations and then  quit, never showing a UI. However, most applications want to stay around and  respond to system events, including UI events. For this, one of the threads of  the application needs to acquire what is called the Event Lock by calling <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/system/Application.html#getEventLock()"> Application.getEventLock()</a>. Only one thread in the application can acquire  this lock &#8211; this thread is then called the <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/system/Application.html#isEventThread()"> Event Thread</a>. Typically, the first thread acquires this lock by calling <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/system/Application.html#enterEventDispatcher()"> enterEventDispatcher()</a>. Once this method is called, the application starts  receiving system events. Note that this does not mean that the application is  showing a UI &#8211; just that is it receiving all system events, including UI events.  So as of now, the application is still running in the background. An application  can control whether it wants to continue processing systems events by toggling <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/system/Application.html#setAcceptEvents(boolean)"> setAcceptEvents()</a>.</p><h3>Showing a UI</h3><p>All the visible elements in a Blackberry Java Application are of three types:</p><ul><li> <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/ui/Field.html"> Fields</a>: A building block element that is used to work with a particular  	kind of data for which it draws the UI and if required handles user-input.  	It typically corresponds to a control like a <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/ui/component/ButtonField.html"> button</a> / <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/ui/component/TextField.html"> text-field</a>, etc. You can create custom Fields by sub-classing the Field  	class, implementing the <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/ui/Field.html#layout(int, int)"> layout()</a> and <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/ui/Field.html#paint(net.rim.device.api.ui.Graphics)"> paint()</a> abstract methods and optionally overriding <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/ui/Field.html#getPreferredHeight()"> getPreferredHeight()</a> and <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/ui/Field.html#getPreferredWidth()"> getPreferredWidth()</a> methods.</li><li> <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/ui/Manager.html"> Managers</a>: Responsible for arranging fields. Each field must belong to  	only one manager. Since a manager is also a field, managers are composable,  	making it possible to build complex, rich, UI layouts. There are several  	types of managers provided: <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/ui/container/HorizontalFieldManager.html"> Horizontal</a>, <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/ui/container/VerticalFieldManager.html"> Vertical</a>, <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/ui/container/GridFieldManager.html"> Grid</a>, <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/ui/container/FlowFieldManager.html"> Flow</a>, <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/ui/container/AbsoluteFieldManager.html"> Absolute</a>, etc., and you can also build your own by sub-classing the  	Manager class and implementing <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/ui/Manager.html#sublayout(int, int)"> sublayout()</a>, <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/ui/Field.html#getPreferredHeight()"> getPreferredHeight()</a> and <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/ui/Field.html#getPreferredWidth()"> getPreferredWidth()</a> methods and optionally overriding <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/ui/Manager.html#subpaint(net.rim.device.api.ui.Graphics)"> subpaint()</a> method.</li><li> <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/ui/Screen.html"> Screens</a>: A screen is a window that is active at any given time. There  	are two types of screens: <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/ui/container/PopupScreen.html"> PopupScreen</a> and a <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/ui/container/FullScreen.html"> FullScreen</a>.</li></ul><p><img
src="http://www.blackberry.com/developers/docs/5.0.0api/images/UI_BB.jpg" alt="Blackberry UI Framework" width="564" height="315" /></p><p>(Blackberry UI Framework. Source: <a
href="http://www.blackberry.com/developers/docs/5.0.0api/UI-summary.html"> http://www.blackberry.com/developers/docs/5.0.0api/UI-summary.html</a>)</p><p>The way the system works is that the <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/ui/UiEngine.html"> UI Engine</a> maintains a stack of Screen objects. As new screens are created,  they are <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/ui/UiApplication.html#pushScreen(net.rim.device.api.ui.Screen)"> pushed</a> on the display stack. Only the screen at the top receives input  events. When a screen is <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/ui/UiApplication.html#popScreen(net.rim.device.api.ui.Screen)"> popped</a> from the stack, the underlying screens are drawn as necessary. Note  that the Blackberry display stack is not the same as the Android back-stack. The  Android back-stack is a system-managed structure, scoped to a task with  acitivities from different processes getting interleaved. The Blackberry display  stack is a per-process application-managed stack of Screens.</p><p>To show a UI, the application extends the <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/ui/package-summary.html"> net.rim.device.api.ui.UiApplication</a> class (which implements <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/ui/UiEngine.html"> UiEngine</a> and extends the <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/system/Application.html"> Application</a> class), creates an instance of <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/ui/container/MainScreen.html"> MainScreen</a> (which is of type <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/ui/container/FullScreen.html"> FullScreen</a>) and then pushes this instance on the display stack.</p><pre>
class MyApp extends UiApplication {
	MyApp() {
		MyAppScreen myAppScreen = new MyAppScreen();
		pushScreen(myAppScreen);
	}

	public static void main(String[] args) {
		MyApp app = new MyApp();
		app.enterEventDispatcher();
	}
}

class MyAppScreen extends MainScreen {
	MyAppScreen() {
		// add fields etc.
	}
}
</pre><h3>Termination</h3><p>An application terminates when <a
href="http://www.blackberry.com/developers/docs/5.0.0api/java/lang/System.html#exit(int)"> System.exit()</a> is called. This method causes the Blackberry JVM to terminate  the process of the caller. For applications that show a UI, the typical way of  quitting is that when the <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/ui/Screen.html#close()"> close()</a> method is called on a screen, it pops the screen from the display  stack, and if the display stack is empty, calls <a
href="http://www.blackberry.com/developers/docs/5.0.0api/java/lang/System.html#exit(int)"> System.exit()</a>. So if the user keeps pressing back and hits the first screen  of your application, pressing back once again would by default exit the app. To  avoid this, one needs to override the close() method.</p><h2>Doing Long Running Work</h2><p>As described in the Event-Processing section above, the Blackberry UI model  is a single threaded one. That means that you cannot do long-running work on it,  and instead need to launch a worker thread. This worker thread can update the UI  in two ways:</p><ol><li><strong>Acquire and synchronize on the event lock:</strong> To do this, the  	worker  	thread invokes <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/system/Application.html#getEventLock()"> Application.getEventLock()</a> and then synchronizes this object to access  	the UI. While this is being done the Event Thread is paused, so the lock  	should be held for a really short period of time.<pre>// on the background thread
synchronized(Application.getEventLock()) {
    // update the UI
}</pre></li><li><strong>Inject an event in the UI message queue:</strong> To inject an event, you model it  	as a class that implements <a
href="http://www.blackberry.com/developers/docs/5.0.0api/java/lang/Runnable.html"> Runnable</a> and inject it into the Event Thread message queue by calling <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/system/Application.html#invokeAndWait(java.lang.Runnable)"> invokeAndWait()</a> or <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/system/Application.html#invokeLater(java.lang.Runnable)"> invokeLater()</a>. The event thread would then call the runnable&#8217;s <a
href="http://www.blackberry.com/developers/docs/5.0.0api/java/lang/Runnable.html#run()"> run()</a> method at the next available opportunity. While for  	invokeAndWait(), the worker thread would block till run() returns,  	invokeLater does not block and returns immediately.<pre>// on the background thread:
UiApplication.getUiApplication().invokeLater (new  Runnable() {
    public void run()
    {
        // update the UI - runs on the Event thread
    }
});</pre></li></ol><h2>Interprocess Communication</h2><p>There are two ways in which Blackberry applications can communicate with each  other:</p><ol><li>Using the <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/system/RuntimeStore.html">RuntimeStore</a>:  	The RuntimeStore is a system-wide volatile storage where applications can  	place data to share with other applications.</li><li>Using Global Events: Use <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/system/Application.html#addGlobalEventListener(net.rim.device.api.system.GlobalEventListener)"> Application.addGlobalEventListener()</a> to add a <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/system/GlobalEventListener.html"> GlobalEventListener</a> to listen to global events. Post a Global Event by  	calling <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/system/ApplicationManager.html#postGlobalEvent(long, int, int)"> ApplicationManager.postGlobalEvent()</a>.</li></ol><h2>Security Model</h2><p>Blackberry has a complex security model, owing to its roots in enterprise  software. When businesses issue their employees Blackberry devices, they also  expect to able to exercise control over what the user is able to do on the  device. This is made possible thru a <a
href="http://docs.blackberry.com/en/developers/deliverables/9095/Application_control_447165_11.jsp"> policy</a> which is pushed to the device using BES or the Blackberry Desktop  Manager. Such policies can limit the resources available to an  application, and to handle that gracefully, applications should:</p><ol><li>Find out what permissions they have: By calling <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/applicationcontrol/ApplicationPermissionsManager.html#getApplicationPermissions()"> ApplicationPermissionsManager.getApplicationPermissions()</a>. This returns  	an instance of <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/applicationcontrol/ApplicationPermissions.html"> ApplicationPermissions</a> class which gives all the permissions that are  	set.</li><li>Ask for permissions they need: By calling <a
href="http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/applicationcontrol/ApplicationPermissionsManager.html#invokePermissionsRequest(net.rim.device.api.applicationcontrol.ApplicationPermissions)"> ApplicationPermissionsManager.invokePermissionsRequest()</a> and passing it  	an instance of ApplicationPermissions with the requested permissions set.</li></ol><p>Besides this, RIM has marked a <a
href="http://docs.blackberry.com/en/developers/deliverables/9095/Java_APIs_with_controlled_access_447163_11.jsp"> number of APIs</a> as <a
href="http://docs.blackberry.com/en/developers/deliverables/9095/Controlled_APIs_and_code_signing_447162_11.jsp"> controlled APIs</a>. To access these APIs on the device, you must sign your  application using a key or signature obtained from RIM. For details, see <a
href="http://us.blackberry.com/developers/javaappdev/codekeys.jsp"> http://us.blackberry.com/developers/javaappdev/codekeys.jsp</a>. On the  simulators, these APIs are accessible without code-signing.</p><h2>Packaging</h2><p>When you build your app, you create a JAR, alongwith a manifest. Java ME <a
href="http://developers.sun.com/mobility/midp/ttips/getAppProperty/index.html"> defines certain mandatory and optional attributes</a> that applications should  include in the JAR manifest, besides any other app-specific info that maybe  present.</p><p>However, a Blackberry device cannot directly execute a JAR. It first needs to  be converted into a proprietary format file called a <a
href="http://drbolsen.wordpress.com/2006/07/26/blackberry-cod-file-format/"> .COD</a> file which is essentially RIM&#8217;s own version of the JAR. So if you want  to run a MIDlet on a Blackberry device, you first need to convert the JAR into a  COD file which can be done using the Eclipse plugin or by using the <a
href="http://supportforums.blackberry.com/t5/Java-Development/Use-the-RAPC-compiler/ta-p/444879"> RAPC compiler</a> on the command line. Some more details on using the RAPC  compiler are given <a
href="http://codeforfun.wordpress.com/2008/09/09/how-to-use-rapc-from-rim-dirty-details/"> here</a>.</p><p>However, the max size of a COD file is 128 kb with a 64 kb limit on compiled  code and 64-kb limit on resource data. In case the compiled code produced is  larger than these limits, the compiler breaks the code into mulitple COD files,  naming them in increasing numerical order like this:</p><ul><li>HelloWorld.cod</li><li>HelloWorld-1.cod</li><li>HelloWorld-2.cod</li><li>HelloWorld-3.cod</li><li>&#8230;</li></ul><p>The compiler then takes the numbered files (called sibling COD files), zips  them and names the zip as a COD file (HelloWorld.cod above) &#8211; this is called the  main COD file. There is a max limit to the main COD file too &#8211; it can contain up  to 127 sibling COD files, thus imposing a theoretical size limit. For more  details, see <a
href="http://supportforums.blackberry.com/t5/Java-Development/The-maximum-size-of-a-BlackBerry-smartphone-application/ta-p/502534"> http://supportforums.blackberry.com/t5/Java-Development/The-maximum-size-of-a-BlackBerry-smartphone-application/ta-p/502534</a>.</p><p>Packaging the application for Wireless or Over-the-Air (OTA) distribution requires more work. For this, Java ME defines an additional manifest called  a JAD (Java Application Descriptor) that Java ME applications should provide for  OTA distribution. The main purpose of a JAD is for locating a JAR and figuring  out its size. Besides the JAR URL and JAR size, the JAD must also contain  certain other attributes that are also required in a JAR manifest and may  contain any attribute that is in a JAR manifest. For details, see <a
href="http://developers.sun.com/mobility/midp/ttips/getAppProperty/index.html"> here</a>. Blackberry specific attributes for a JAD are given <a
href="http://docs.blackberry.com/en/developers/deliverables/7693/Attributes_for_jad_files_513047_11.jsp"> here</a>. Also, for OTA distribution, you need to extract the sibling COD files  from the main COD file. For details see <a
href="http://docs.blackberry.com/en/developers/deliverables/7693/Extract_sibling_cod_files_512523_11.jsp"> here</a>.</p><h2>Distribution</h2><p>Blackberry applications can be distributed in two ways:</p><ol><li> <a
href="http://docs.blackberry.com/en/developers/deliverables/7693/App_distribution_through_a_computer_connection_447181_11.jsp"> Direct Connection</a>: Connect the device to your computer and install the  	app. There are two possibilities here:<ul><li> <a
href="http://docs.blackberry.com/en/developers/deliverables/7693/Distribute_an_application_from_a_computer_447182_11.jsp"> Using the Blackberry Desktop Manager</a>: The application needs to have  		a COD file alongwith an additional manifest file called the<a
href="http://docs.blackberry.com/en/developers/deliverables/7693/Elements_and_attributes_for_alx_files_513046_11.jsp"> ALX file</a>.</li><li> <a
href="http://docs.blackberry.com/en/developers/deliverables/7693/Distribute_an_application_from_a_web_page_447183_11.jsp"> Using a Web Page</a>: For this, you need to put up an ActiveX control  		called a  <a
href="http://docs.blackberry.com/en/developers/subcategories/?userType=21&amp;category=BlackBerry+Application+Web+Loader"> Web Loader</a> on the web-page from where you want the installation to  		happen. The user browses to a web-page on his desktop using IE and the  		control starts an installer. In case the user visits the page using a  		Blackberry device, the user is prompted to connect the device to a  		desktop.</li></ul></li><li> <a
href="http://docs.blackberry.com/en/developers/deliverables/7693/Distributing_BB_Java_Apps_over_wireless_network_512513_11.jsp"> OTA</a>: There are two ways in which OTA distribution may happen:<ul><li><strong>BES Push:</strong> An organization with a Blackberry  		Enterprise server deployment can push notifications to Blackberry  		devices for applications based on policies defined by an administrator.</li><li> <a
href="http://docs.blackberry.com/en/developers/subcategories/?userType=21&amp;category=BlackBerry+App+World+storefront"> Blackberry App-World</a>: The process is described <a
href="http://docs.blackberry.com/en/developers/deliverables/24398/Process_flow_title_647894_11.jsp"> here</a>.</li></ul></li></ol> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/VineetGupta?a=q3t068xNfHc:gyFLeT9eaE0:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/VineetGupta?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VineetGupta?a=q3t068xNfHc:gyFLeT9eaE0:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/VineetGupta?i=q3t068xNfHc:gyFLeT9eaE0:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VineetGupta?a=q3t068xNfHc:gyFLeT9eaE0:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/VineetGupta?i=q3t068xNfHc:gyFLeT9eaE0:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VineetGupta?a=q3t068xNfHc:gyFLeT9eaE0:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/VineetGupta?i=q3t068xNfHc:gyFLeT9eaE0:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VineetGupta?a=q3t068xNfHc:gyFLeT9eaE0:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/VineetGupta?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/VineetGupta/~4/q3t068xNfHc" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://www.vineetgupta.com/2011/03/mobile-platforms-part-2-blackberry/feed/</wfw:commentRss> <slash:comments>5</slash:comments> <feedburner:origLink>http://www.vineetgupta.com/2011/03/mobile-platforms-part-2-blackberry/</feedburner:origLink></item> <item><title>Mobile Platforms – Part 1 – Android</title><link>http://feedproxy.google.com/~r/VineetGupta/~3/mQvRIRIZH1U/</link> <comments>http://www.vineetgupta.com/2011/03/mobile-platforms-part-1-android/#comments</comments> <pubDate>Sun, 06 Mar 2011 19:36:38 +0000</pubDate> <dc:creator>Vineet Gupta</dc:creator> <category><![CDATA[Mobile]]></category> <category><![CDATA[Android]]></category><guid isPermaLink="false">http://www.vineetgupta.com/?p=10071</guid> <description>One of the products we are building at Directi is a x-platform mobile chat client. Developing it has been arduous &amp;#8211; we experimented with Phonegap and then Titanium and found both lacking (see this Quora thread for details). So now we are building this as three native apps, targeting iPhone, Android and Blackberry. In this &lt;a
href='http://www.vineetgupta.com/2011/03/mobile-platforms-part-1-android/'&gt;[...]&lt;/a&gt;</description> <content:encoded><![CDATA[<p>One of the products we are building at Directi is a x-platform mobile chat client.     Developing it has been arduous &#8211; we experimented with Phonegap and then Titanium     and found both lacking (see this <a
href="http://www.quora.com/How-do-you-decide-whether-to-go-with-a-native-iPhone-Android-app-or-a-web-app-that-pretends-to-be-an-iPhone-Android-app/answer/Vineet-Gupta?srid=Ysz"> Quora thread</a> for details). So now we are building this as three native apps,     targeting iPhone, Android and Blackberry. In this post I am going to cover the Android platform, and would follow up with iOS and Blackberry.</p><h2>Android Architecture</h2><p>The following diagram (from <a
href="http://developer.android.com/guide/basics/what-is-android.html"> http://developer.android.com/guide/basics/what-is-android.html</a>) gives the     overall architecture of the Android OS:</p><p><img
src="http://developer.android.com/images/system-architecture.jpg" alt="Android Architecture" /></p><p>The Android OS is basically a Linux 2.6.4 kernel fork. The Linux kernel is used     for memory management, process management, security, driver model, shared lib model.     Google has added Android specific enhancements: Power management, Kernel debugger,     Logger, Low Memory killer, Shared Memory Driver, IPC Driver, etc.</p><p>Above the kernel, in the user space, sits the Hardware abstraction layer &#8211; this     deals with stuff like Radio, Wifi, GPS, Graphics, Audio, Camera, Bluetooth, etc.     Basically this defines a set of interfaces that drivers need to implement. These     libaries are loaded by the system at runtime on a need basis.</p><p>Above the HAL, sit a bunch of libraries &#8211; the most important of course is libc &#8211;     Google has written a port called Bionic libc which is optimized for embedded use     &#8211; in terms of being small in size (since it is loaded in every process) and fast     (since CPU is limited), but also because libc is GPL and Google wanted to protect     apps from being GPLed. Besides there is webkit of course and SQLite. Google also     provides a Media Framework, OpenGL library, and libraries for UI rendering and audio.</p><p>The Android programming environment is based on Java. For this, the OS ships with     Dalvik &#8211; a custom implementation of the JVM optimized for the embedded environment.     Dalivk does not run the Java bytecode, but its own custom bytecode called Dex &#8211;     Dalvix Executable. It uses runtime memory very efficiently, the bytecode interpreter     is highly CPU optimized, and because of this low footprint, the VM can be run in     multiple processes &#8211; basically each app gets its own Linux process with its own     instance of a Dalvik VM. The VM is exposed by a set of core Java APIs which provide     the familiar Java library.</p><p>All of the above is wrapped in a set of platform services called the Android Application     Framework &#8211; these services work behind the scenes to provide abstractions like Activities,     Packages, Windows, Resources, Content Providers, View System, hardware access, etc.</p><h2>Startup</h2><p>Like a typical Linux system, in Android, the bootstrapper loads the Linux kernel     and starts the init process, which in turn starts various daemons like Android Debug     Bridge (adbd), Radio Interface Layer Daemon (rild), etc. After this, init starts     what is called the Zygote process. The purpose of this process is to kick off the     rest of the Android system and later help in the instantiation of apps. The Zygote     process initializes a Dalvik VM instance and loads a bunch of libraries and starts     listening on a socket for requests to spawn more processes (with VM instances).     As requests come in, it forks to create new processes with VM instances. Copy-on-write     is used to maximize reuse and minimize footprint.</p><p><img
class="alignnone" alt="Android Startup Sequence" src="http://farm6.static.flickr.com/5291/5502863911_40f78966b5_z.jpg" /></p><p>(Android Startup Sequence &#8211; source: <a
href="http://sites.google.com/site/io/anatomy--physiology-of-an-android"> http://sites.google.com/site/io/anatomy&#8211;physiology-of-an-android</a>)</p><p>Once Zygote is in place, the init process starts what is called the Runtime process.     This basically does two things:</p><ol><li>Start the Service Manager &#8211; this is responsible for managing IPC and all services         are required to register with it. It acts like a local DNS providing a way to bind         to a service given its name.</li><li>Ask Zygote to fork what is called the System Server. This is the first process (besides         Zygote) that has a running VM instance. The System server starts services for display         (Surface Flinger) and audio (Audio Flinger). These services register with the service         manager like all services are expected to. Now other apps can start using display         and audio. After this, the System server starts up all the core platform services         &#8211; Window manager, Telephony manager, Power manager, Activity manager, etc. Each         one of these services also registers with the Service Manager, so that apps can         use these services.</li></ol><p>At this stage, we have the following processes in place:</p><ol><li>Init &#8211; the original init process started by the bootstrapper</li><li>Daemons &#8211; started by init</li><li>Runtime &#8211; also started by init</li><li>Zygote &#8211; the original zygote which will continually get forked as new apps get launched</li><li>System Server &#8211; the first managed process which contains all the core services and         platform components.</li></ol><p>After this, the Home Screen or the Idle screen is launched &#8211; basically the Activity     Manager (which is inside the System Server) sends a message to Zygote to start the     &#8220;Home&#8221; Activity, which causes Zygote to fork into a new process with a     Dalvik VM and the Home activity. Now depending on the action carried out by the     user, the appropriate app would be launched with the Zygote forlking each time to     create a new VM instance inside a new process. So for example, if the user starts     the Contacts app, the apt process would be setup:</p><p><img
class="alignnone" alt="Android Startup Processes" src="http://farm6.static.flickr.com/5171/5503452198_4f8d649c05_z.jpg" /></p><p>(Startup processes in Android -  source: <a
href="http://sites.google.com/site/io/anatomy--physiology-of-an-android"> http://sites.google.com/site/io/anatomy&#8211;physiology-of-an-android</a>)</p><p>Each new app gets a unique user Id which is opaque to the app, and the system sets     permissions for all files in the app so that only the user id assigned to the app     can access those files.This makes the system secure since the app only has access     to the components that it needs to do its work and nothing else. However,      apps may need to communicate with each other and the system services, which are     all running in separate processes. This is accomplished thru Inter Process Communication</p><h2>IPC</h2><p>With its emphasis on isolating apps and services in process boundaries, it is clear     that Android requries a lightweight IPC. The IPC mechanism in Android is called     Binder and is based on shared memory. Recall that when a process starts it registers     itself with the Service Manager. This happens behind the scenes, and on registeration,     each process gets what is called a <a
href="http://developer.android.com/reference/android/content/Context.html"> Context</a> object &#8211; a reference to the Service manager. Now lets say app A     needs to communicate with service B, and the two are running in two separate processes.     To do this, app A asks the Context for the Service B by passing the well known name     of the service. The Context returns a reference to the service to A, on which A     can call a method &#8211; say foo. This method call is intercepted by the Binder driver.     The driver marshals the object and passes a reference of it to the receiver &#8211; B.     Note that this is passing by reference, not passing by value, in which the object     is serialized. On the side of the service B, the Binder maintains a thread-pool     (transparent to the service). One of the threads in this pool receives the incoming     call, locates the actual object in the service B and make the call. The return value     is then similarly passed back to the caller. The following diagram (from <a
href="http://sites.google.com/site/io/anatomy--physiology-of-an-android"> http://sites.google.com/site/io/anatomy&#8211;physiology-of-an-android</a>) illustrates     this:</p><p><img
alt="Android IPC - Binder" src="http://farm6.static.flickr.com/5015/5503451932_08abdba708_z.jpg" /></p><p>The entire operation is synchronous, and the objects are reference counted so that     when they are no longer in use, they can be deleted. Since there is no serialization     / de-serialization, there is no overhead and therefore this model can also be used     to communicate with services that run in your own process without any penalty.</p><h2>Applications</h2><p>An application in Android is a collection of components. There are four types of     components:</p><ul><li><a
href="http://developer.android.com/guide/topics/fundamentals/activities.html"> Activity</a>: An Activity is a UI component corresponding to one screen with which         a user interacts in order to do something.</li><li><a
href="http://developer.android.com/guide/topics/fundamentals/services.html">Service</a>:         A Service is an application component without a UI used to perform long running         operations in the background.</li><li><a
href="http://developer.android.com/reference/android/content/BroadcastReceiver.html"> Broadcast Receiver</a>: A broadcast receiver is a component that responds to system-wide         broadcasts (for example screen turned off, battery low, etc.)</li><li><a
href="http://developer.android.com/guide/topics/providers/content-providers.html"> Content Provider</a>: A content provider is a component that stores and retrieves         data and makes it available to all applications. There are different types of content         providers: audio, video, contacts, etc. and you can create your own custom provider         also.</li></ul><p>As mentioned earlier, each application runs in its own process. By default, all     components used by that app also run in the same process, and on the main thread.     However, it is possible to make a component of your app run in a separate process     thru the manifest file. Thus, an application in Android may span multiple processes.</p><h2>Application Startup</h2><p>Android follows a fairly unique model in that there is no single entry point for     an application &#8211; there is no main() function. Instead, a component in one application     can start another application&#8217;s component, thus bringing the application to life.     This communication across apps happens thru the IPC mechanism descibed above. So     while an Activity is owned by an application, it is possible for another application     to start it (if the owning application allows it). An example is clicking on a hyperlink     in an app opening up the browser. This applies for not just Activities, but other     types of components also. In order for this to happen, there are two steps required:</p><ol><li>In case the application is not already running, the Android system would bring the         application to life in a new process forked from Zygote.</li><li>The desired component inside the app would need to be activated.</li></ol><p>Note that in case the application is already running, the new component would be     by default instantiated in the same process.</p><p>As mentioned above, IPC happens thru a <a
href="http://developer.android.com/reference/android/content/Context.html"> Context</a> object. So when a component A inside one app needs to activate another     component B in a different app, or give it something new to do, it basically uses     the Context object to send a message to the other component. In the case of an Activity,     Service or a BroadcastReceiver, this takes the form of a what is called an <a
href="http://developer.android.com/guide/topics/intents/intents-filters.html"> Intent</a> &#8211; a passive data structure that defines the operation to be performed     for an Activity and a Service, and for a Broadcast Receiver, a defintion of the     announcement being broadcast.</p><p>Content Providers however are not activated thru Intents. Instead, activation happens     on a request from a <a
href="http://developer.android.com/reference/android/content/ContentResolver.html"> ContentResolver</a>, which acts as a mediator between the requesting component     and the Content Provider.</p><h2>The Activity Back-Stack</h2><p>Consider the following scenario:</p><ol><li>You are on the Home Screen. This is Activity 1</li><li>You click on the Mail app icon, and that activates the main activity in the Mail         app which comes to the foreground. This is Activity 2</li><li>You now click on Compose and that activates the Compose activity in the Mail app.         This is Activity 3</li><li>You decide to cancel out of composing a new message and press the back button. You         come back to Activity 2</li></ol><p>Here is what happens in the background:</p><ul><li>When one activity starts another activity, it stops and its state is saved. So when         Activity 1 starts activity 2, activity 1 is stopped, its state saved and so on</li><li>The system maintains a stack (called a back-stack) with the latest activity on top         and the oldest activity at the bottom.</li><li>When the user presses the back-key, Activity 3 is popped and Activity 2 is started         from its saved state</li></ul><p><img
src="http://developer.android.com/images/fundamentals/diagram_backstack.png" alt="Activity Back Stack" width="700" height="300" /></p><p>(The Activity Back Stack &#8211; source: <a
href="http://developer.android.com/guide/topics/fundamentals/tasks-and-back-stack.html"> http://developer.android.com/guide/topics/fundamentals/tasks-and-back-stack.html</a>)</p><p>This approach allows Android to seamlessly transition from one app to the other     in a consistent way.</p><h2>Tasks</h2><p>In the scenario described above, assume that when the user was in Compose mail (Activity     3), he decided to call someone and pressed the Home key. This would not unwind the     back-stack, but start a new stack. In order to do this, the collection of Activities     in the first stack needs to go into the background. This is achieved thru the notion     of a Task &#8211; a cohesive unit of Acitivities. When a task moves to the background,     all activities in the Task are stopped but the back-stack for the task remains intact,     so that when the user returns back to the Task, she can resume where she left off.     However, to save memory, the back-stack for a background Task is not retained for     a very long period and if the user does not go back to the task, the back-stack     is cleared except for the root activity.</p><p><img
src="http://developer.android.com/images/fundamentals/diagram_multitasking.png" alt="Tasks" width="331" height="202" /></p><p>(Background and Foreground Tasks &#8211; source: <a
href="http://developer.android.com/guide/topics/fundamentals/tasks-and-back-stack.html"> http://developer.android.com/guide/topics/fundamentals/tasks-and-back-stack.html</a>)</p><h2>Activity Life Cycle</h2><p>The lifecycle of an activity is affected by its association with other activities,     its task and its back-stack. There are three states in which an activity can exist:</p><ul><li><strong>Resumed / Running:</strong> Activity is in the foreground and has user focus.         Such an activity is never killed by the system,</li><li><strong>Paused:</strong> Activity is visible, but another activity is in the foreground         and has user focus. This could happen if the other activity is at the top, but is         translucent, or because it does not cover the entire screen. In the paused state,         the Activity object is retained in memory, maintains all state and member info and         remains attached to the Window manager. However it can be killed in extremely low         memory conditions.</li><li><strong>Stopped:</strong> The Activity is not visible to the user.While the Activity         object is retained in memory, maintains all state and member info, it does not remain         attached to the Window manager. The activity can be killed by the system to reclaim         memory if required.</li></ul><p><img
src="http://developer.android.com/images/activity_lifecycle.png" alt="Activity State Transitions" width="545" height="711" /></p><p>(Activity Lifecycle &#8211; source: <a
href="http://developer.android.com/guide/topics/fundamentals/activities.html#Lifecycle"> http://developer.android.com/guide/topics/fundamentals/activities.html#Lifecycle</a>)</p><h2>Saving Activity State</h2><p>Note that it is entirely possible that the system, in order to reclaim memory, may     destroy an Activity, or even the process in which the Activity was running. However,     when the user comes back to the activity (thru the back-stack), you still want to     resume at the point the user left. To do this, an activity must save its state.     This happens thru the <a
href="http://developer.android.com/reference/android/app/Activity.html#onSaveInstanceState(android.os.Bundle)"> Activity.onSaveInstanceState()</a> method.</p><p><img
src="http://developer.android.com/images/fundamentals/restore_instance.png" alt="Saving Activity State" width="612" height="400" /></p><p>(Saving and restoring Activity State &#8211; source: <a
href="http://developer.android.com/guide/topics/fundamentals/activities.html#SavingActivityState"> http://developer.android.com/guide/topics/fundamentals/activities.html#SavingActivityState</a>)</p><h2>Process Lifecycle</h2><p>The Android system may need to kill a process in order to reclaim memory. To ensure     that this creates minimal impact on the user expereince, Android ranks processes     in a priority order:</p><ul><li><strong>Foreground Process</strong>: A process that is required for what the user         is currently doing. Such a process is killed only as a last resort</li><li><strong>Visible Process</strong>: This process is not in the foreground but can         affect what the user is seeing on the screen. For example it may host a paused Activity.         Such a process is not killed unless doing so is required to keep all foreground         processes running</li><li><strong>Service Procress</strong>: A process that is running a service and is not         one of the two types above. For example the service may be playing music or downloading         something. The system would keep such a process running unless there is not enough         memory to keep Foreground and Visible processes running.</li><li><strong>Background Process</strong>: A process that is holding an activity not currently         visible to the user (the activity is stopped). Such a process has no impact on the         user experience (if the activity lifecycle is correctly implemented and the activity         state is being properly saved and restored) The system can kill such a process any         time. Typically there are mulitple background processes running and the system maintains         a LRU list which is used to kill such processes.</li><li><strong>Empty Process</strong>: An empty process does not hold any active component.         The only reason such a process is kept alive in the first place is for caching and         to improve startup time. The system often kills such processes to maintain the balance         between process caches and underlying kernel caches.</li></ul><p>Of course it can so happen that a higher priority process is dependent on a lower     priority process. In such a case the ranking of the serving process is increased     to the same level as that of the dependent process.</p><p>A situation where this ranking has a direct impact is this:</p><ul><li>Your app needs to download something big which may take time and the user is likely         to move out of the app&#8217;s activity to something else.</li><li>If you spawn a worker thread for this task and the user moves out, the process would         become a background process.</li><li>However, if you instead spawn a service, the process would be a service process         and be less likely to be killed</li></ul><h2>Main / UI Thread</h2><p>When an application is launched and a new process created to host it, the application     gets a single thread called the main thread or the UI thread since this thread is     responsible for servicing the UI. The way this works is mostly the same for almost     any UI implementation &#8211; be it desktop operating systems or mobile OS. Basically,     the UI thread runs an infinite loop which checks a queue to see if there are any     pending UI events. In the case of Android, this concept is formalized in the form     of a <a
href="http://developer.android.com/reference/android/os/Looper.html">Looper</a>.      The looper loops over a <a
href="http://developer.android.com/reference/android/os/MessageQueue.html"> MessageQueue</a> which contains the <a
href="http://developer.android.com/reference/android/os/Message.html"> messages</a> to be dispatched. The actual task of managing the queue is     done by a <a
href="http://developer.android.com/reference/android/os/Handler.html">Handler</a> which is responsible for handling (adding, removing, dispatching) messages in the     message queue.</p><p><img
src="http://farm6.static.flickr.com/5295/5502982451_1f78830c9e_z.jpg" alt="Android Threading"  /></p><p>(Android Threading &#8211; source: <a
href="http://sites.google.com/site/io/inside-the-android-application-framework">http://sites.google.com/site/io/inside-the-android-application-framework</a>)</p><p>For the main thread, a Looper is setup by the system. However, you can also associate     a Looper with your own thread. Note that the Looper can be associated only with     one thread and that association cannot be changed. The way Android ensures this     is by putting the Looper on the <a
href="http://developer.android.com/reference/java/lang/ThreadLocal.html"> thread local storage</a> of the thread and not exposing a constructor for the     Looper. You get a Looper by calling the static <a
href="http://developer.android.com/reference/android/os/Looper.html#prepare"> prepare</a> method which first checks the TLS to see if there is already a Looper,     and if not creates one. You then call the <a
href="http://developer.android.com/reference/android/os/Looper.html#loop"> loop</a> method on it to start pumping messages. Unlike a Looper, mulitple handlers     can be associated with a message queue.</p><p>So quite obviously, one should not run a blocking operation on the UI thread. If     you do, messages would stop getting processed from the Message Queue and your app     would become unresponsive. This is what leads to the famous <a
href="http://developer.android.com/guide/practices/design/responsiveness.html"> Application Not Responding (ANR) dialog</a>. One solution is decsribed <a
href="http://developer.android.com/guide/appendix/faq/commontasks.html#threading"> here</a>: create a handler, spawn a worker thread, post results back from     the worker thread to the handler, update the UI. But this is a bit cumbersome to     do. A simpler solution is to use a <a
href="http://developer.android.com/reference/android/os/AsyncTask.html"> AysncTask</a> which takes care of the underlying plumbing.</p><h2>Service</h2><p>As mentioned earlier, a Service is a type of component that is used to carry out     a background operation, and does not provide a UI. An app component can start a     service, and even if the user switches out of the application, the service would     keep running. Typical use cases include playing music and downloading a file. Android     ensures that a process running a Service is not killed as far as possible (see Process     lifecycle above).</p><p>Note that a service by default runs on the main UI thread in the same process. This     means that if it carries out a blocking operation, your UI would become unresponsive     since the thread would not be available to run the Activity. To circumvent this,     you should launch a worker thread inside the service.</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/VineetGupta?a=mQvRIRIZH1U:X1QMVJUfXwM:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/VineetGupta?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VineetGupta?a=mQvRIRIZH1U:X1QMVJUfXwM:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/VineetGupta?i=mQvRIRIZH1U:X1QMVJUfXwM:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VineetGupta?a=mQvRIRIZH1U:X1QMVJUfXwM:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/VineetGupta?i=mQvRIRIZH1U:X1QMVJUfXwM:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VineetGupta?a=mQvRIRIZH1U:X1QMVJUfXwM:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/VineetGupta?i=mQvRIRIZH1U:X1QMVJUfXwM:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VineetGupta?a=mQvRIRIZH1U:X1QMVJUfXwM:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/VineetGupta?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/VineetGupta/~4/mQvRIRIZH1U" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://www.vineetgupta.com/2011/03/mobile-platforms-part-1-android/feed/</wfw:commentRss> <slash:comments>10</slash:comments> <feedburner:origLink>http://www.vineetgupta.com/2011/03/mobile-platforms-part-1-android/</feedburner:origLink></item> </channel> </rss><!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using apc
Page Caching using apc
Database Caching using apc
Object Caching 616/792 objects using apc

Served from: www.vineetgupta.com @ 2013-05-12 16:21:52 -->
