Category Archives: Android

The Pains and Remedies of Android HTML5

Prologue: I’ve written most of this post some months ago and somehow didn’t publish it. Looking at it now, it’s a good reminder of some of the pains I already forgotten. The Android version statistics already changed a bit by now, but, still today and even with the new type of measuring by Google – the most problematic Andorid versions which are 2.2.x – 4.0.x are still running more than 50% of Androids out there. Hence everything here still applies. (note that most of the bugs are in 4.0.x and not in 4.1.x and above).
I’ve updated all the stats in the article to reflect the latest published stats.

These issues refer to HTML5 content running inside the native Android browser as well as  inside the native WebView (i.e. PhoneGap and alike)

———————————–

The promise of HTML5 is great, to be able to use the same code base on all clients and even on the server is really compelling.  While iOS has provided what it promise long time ago already – you can relatively easily create compelling HTML5 apps that will run on the iOS. Android HTML5 capabilities are still lagging far behind.

On paper Android 4.0.x (20.6%) was enhanced with many awaited features of HTML5. Similar to iOS 5. For example, Android 4.0.x was added with the important overflow:scroll, but, the Android 4.0 version is flawed. It has many other great features which are, sadly, mostly buggy. In fact this version is a buggy regression to the Android browser and WebView HTML5 capabilities.

It gets much better in Android 4.1, but this version still only holds only (36.5%) of Androids (48.6% including 4.2 & 4.3). Still today the most common version is 2.3.x which holds (44%) and that version can not be avoided. Generally, if you’ll try to push the HTML5 envelop of the Android it’ll probably push you back.

Even with the new and optimistic way of Google to measure Android versions distribution it’s still clear that 2.2.x and 2.3.x and 4.0.x are still massively out there and needs to be supported.

Having said all that, it doesn’t mean you can’t create decent apps with HTML5 that will run properly on the Android. But you’ll have to consider its lacking abilities from the get go. Design the UI as simple as possible, without too many fancy CSS, images, and animations.

I will put here a list of some of the issues I had to go through while adopting HTML5 on the Android, I will keep this list updated.

Canvas:
Pain:
 Android 4.1 – 4.3 render duplicated HTML5 Canvas
Remedy: None of the parents HTML elements to the canvas should have overflow: hidden or overflow:scroll

Pain: In all Androids and especially 4.x canvas drawing performance are extremely reduced by using canvas effects like shadowColor.
Remedy: Try pre-rendering or adding the effects only when needed and/or once in every drawing cycles. For example, in a live drawing app – adding the effects only when the user stops to draw.

Network:
Pain: Android 2.x.x Making PUT (protocol) requests with no body will have no Content-Length header, it’s rejected by some servers/proxies i.e. NGNIX
Remedy: Configure NGNIX to accept it or send a {dummy: ‘data’} in the payload. i.e. $.ajax(‘PUT’, url, {dummy: ‘1’});

Pain: Android 2.x.x PUT (protocol) is cached on some versions of Android
Remedy: Cache-bust it, cache-bust all requests to the server even if it’s PUT.

Content:
Pain: Box-scroll was introduced in Android 4.0.x  but it has numerous issue on that version.
Remedy: Don’t use box-scroll for anything under than 4.1, or use iScroll or similar. The best, most performant, solution is to use postion:fixed for headers and footer and to simulate box-scroll.

Pain: CSS pseudo :active selector is not working on 2.x, working badly on 4.0.x.
Remedy: It is only perfect from Android 4.1 and above, try to use your own implementation using touch events.

Pain: Making fixed content (position: fixed) issues on 2.x.x
Remedy: Works fine only  when the ViewPort is not resizable, use this in the html head:
<meta name=”viewport” content=”width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no” />

Pain: Scrollbars shows over fixed content.
Reedy: When using a native shell, scrollbars can be removed using
webView.setVerticalScrollBarEnabled(false);
webView.setHorizontalScrollBarEnabled(false;

Pain: Jumpy text inputs
Remedy (native shell): <activity android:windowSoftInputMode=”adjustNothing” />
Remedy 2 : don’t use *{ -webkit-backface-visibility: hidden} or try to override it with *{ -webkit-backface-visibility:visible !important; }

Pain: Styling text-inputs that has focus
Remedy: http://stackoverflow.com/a/9464837/275333, http://java-cerise.blogspot.co.nz/2011/10/dodgy-double-input-fields-on-android.html

Pain: Android 4.0.x, any tap implementation will not be responsive enough, it will miss a lot of taps. (works fine with all other versions)
Remedy: Essiest will be to revert to clicks on this buggy 4.0.x version

Pain: In Android 4.0.x long press is selecting text, on all other OSs it’s resolved with the css *{ -webkit-touch-callout: none; }
Remedy (native shell): Use this Java snippet http://stackoverflow.com/a/11872686/275333

Pain: Duplicated Input fields on Android 4.0.x. it happens because android uses another native input for fast typing response, it doesn’t work well with scrollable content. (very ugly hack google, if I may)
There are tones of hacks for that out there, most of it doesn’t work or at least doesn’t work good across devices.
Remedy (native shell): If you run in WebView – Don’t put text inputs inside a scrollable iframe or content with overflow:scroll. Putting this in the activity will auto scroll to the text-input (similar to iOS) android:windowSoftInputMode=”adjustPan” – only works on Android 4.0.x, not working on Android 4.1 and above (yeah really).
adjustResize is working on all Androids I’ve tested, but that is less pretty and leads to jumpy inputs on older androids 2.x. adjustResize needs to be on the tags in order for it to work. I do not recommend that as well.
So to summarize the fiasco, adjustPan which give the best UX (similar to the iPhone) is only working on Android 4.0.x.
adjustResize which is still nice in terms of UX can be made to work with all versions of Android, but can cause issues (jumpy text-inputs) for old 2.x
Remedy 2: Put this style on the text input -webkit-user-modify: read-write-plaintext-only;  Not great since it’ll make typing slower, it’ll be up to impossible to enter text on some devices. Swype keyboard won’t work either.
Remedy 3: Shift the input element off the screen, and use the change event to render the text into another element. (this is too cumbersome, try to avoid it)

Misc:
Pain: HTML5 PushState is supported since Android 2.2, but somehow it was forgotten on Android 4.0 – 4.0.2 and some 4.0.3 devices. Told you these 4.0.x are cr*p…
Remedy: Make sure your HTML5 app works well for devices without pushState support. Try a 4.0 emulator.

Pain: Incorrect dimensions, sometimes innerWidth & innerHeight might still read 0 even after the DOM is ready.
Remedy:  Wait a few (~100 millisecond) after the DOM is ready to ask it what’s the window size is.
Remedy 2: Use screen.width & screen.height (you’ll have to calculate the toolbar height)
Remedy 3: get the width/height from the server (using something like wufl)
Remedy 4 (native shell):  Get the size from the native shell.

Pain: WebSockets are not supported at all.
Remedy (native shell): Use this WebSockets PhoneGap plugin. Don’t get bothered by sockets unless you really need to.

Pain: Web Workers doesn’t work at all
Remedy: Who cares..?!
Remedy 2 (native shell): Multi threaded, yeah baby.

Pain: Android 2.x misses a lot of scrolls attempt because it’s stuck in touchmove event (error is: “Miss a drag as we are waiting for WebCore’s response for touch down.”)
Remedy :( No real remedy, I’m pretty sure there is no sulotion for that and using something like iScroll won’t solve it either.

Pain: DOM manipulation is extremely slow.
Remedy: documentFragments might help but don’t count on it.
You’re left with tricks, for example, It far smother to change visibility than to add/remove DOM elements.
It’s better to pre-render and just show() or hide() as needed, especially when animations are involved.

Some related links:
PhoneGap vs. Native: Some Thoughts on Going Native
Discussion in Hacker News
These are one year old but still very relevant (sadly)
Regarding point 1: Don’t remove images from the DOM, instead replace the src to a very small image (leason learned by the linkedin mobile team), 2: You can handle that, 3: There are good ways to do caching, 4: These days there’s reasonable debuging tools.

HTML5 for extending the device battery life (PDF)

Some other pains & remedies

 

Epilogue:  Everytime I come across a cool HTML5 example and wonder how well it tuns on mobile, I try it on iOS  and mostly like what I see. Only to be disappointed with the way Android native browser run it. And I’m not talking solely about the old 2.x.x androids that mostly run these in an unacceptable way. Even the newer androids with new version of the OS doesn’t play smoothly as the mobile safari or even UIWebView. The only solution to HTML5 on Android at the moment, is to keep it simple, very simple.

When targeting an HTML5 app to run on mobile browsers, one can not assume that  her users will use anything other than the native browser (as opposed to the more capable Chrome for Android, for example). But,  if your running your HTML5 inside a native shell (i.e. PhoneGap) There are few projects that attempt to solve the native WebView problem, by letting us bundle a better webview.
https://github.com/thedracle/cordova-android-chromeview
https://github.com/davisford/android-chromium-view
https://wiki.mozilla.org/Mobile/Projects/GeckoWebView
More on these will follow…

 

Protecting Your Smart Phone, the Basics

iPhone

  1. Don’t jailbreak, a not jailbroken iPhone is a pretty secure device.
  2. Use PIN code Settings -> General -> Passcode (and not something like 1234)
  3. Make sure data is really encrypted – default since iPhone 4 (which have hardware encryption). If you have an older version go to Settings -> General -> Passcode and look for “Data Protection is Enabled” on the bottom.
  4. Don’t install any profiles you’re not absolutely sure about. I saw that some ads company started to use these profiles in order to overcome the App Store restrictions. If you see something like this don’t approve it unless your absolutely sure. Here’s some more info about the danger of malicious profiles.
  5. Consider using alphanumeric passcode by setting “Simple Passcode” to “Off”
  6. Don’t use Consider not using “Find My iPhone”. This is a trade off, “Find My iPhone” is really great tool for finding your lost phone. But, there is a 1 failure point which is your apple ID. Accessing it will gives attackers your exact position and an easy way to wipe all of your phone data.

Android

  1. Don’t root your phone
  2. Use a screen lock
  3. Encrypt data – works better from Android 4.0 and above, might affect performance (it does not encrypt external SD card)
  4. Use a security app like Lookout or AVast – it’s free!
  5. Don’t install an app unlesss you have decent amount of confidance in it, also check the permisisons it requires. Remeber to uninstall it if it’s useless.

We all know that Android is open and its apps needs no approval, which make it more vurenable by nature. This openness has another aspect of vurnability, external SD cards will have variant quality and because of that the Android OS doesn’t encrypt it. It can’t promise a good enough performance on cheap external memory. Which make sense in a way, your somewhat compromising security by being open.

Windows 8 Phone
Never had a windows 8 phone only 7.5, but it’s obvious that Microsoft is batting big on their most loyal enterprise consumers, that need enterprise security. From reading online it seems that it has a built in encryption but not for the SD card (same as Android).

Common sense still applies.

  1. Use screen lock 
  2. Encryption is built in for you, just don’t save anything important on the external SD card.

The Promise of Mobile HTML5

Less than a year ago it seemed like HTML5 was going strong. With Facebook and Linkedin adopting the technology to reach most of the screens on the mobile and on the desktop.

Linkedin had the better hybrid mobile app (HTML5 + native) and published a series of videos and articles about how they successfully did it with a team of “just” 5 developers.
Admittedly Linkedin app was really nice, but, after learning more about the internals of their app I’ve realized it wasn’t perfect.
For example the way they manage the application cache is not as good as the HTML5 app-cache that just works well out of the box. Using the term “it wasn’t documented” is not a good enough excuse, it was working well long before the debute of their app.
Also, their infinit scroll is just a not so infinit swipe, etc’

Anyhow, it appears that linkedin, similar to her bigger sister Facebook, ditched its mobile HTML5 in favor of native.
Linkedin senior director for mobile engineering Kiran Prasad claims are that there is not a good debuger and no performance measuring tool.
Firstly the debuggers are getting there every day (there are many more).
Secondly, profiling in the desktop and mobile Chrome will give you a general idea where memory is going. Profiling hybrid apps in iOS6 is also available.
I don’t think that these are really the reasons, they simply needed a stronger platform and HTML5 became too difficult to scale to their needs. That’s reasonable, mobile HTML5 is definitely not for everything.

Yet, the promise is still here – use the same code base and the same web development skillset to deploy for: native apps for mobile, browser apps for mobile, cross platform for the desktop (also outside of the browser), and so much more.

So why mobile HTML5 is not there yet? I’ll outline some of the main reasons here:

1. It’s not realy the same web development skillset
Well it is in a way, for the simple stuff it is still mostly HTML, Javasctipt and CSS. But, even for the simple stuff, things that works just fine on the desktop browser can greatly affet smoothness, battery consumption, memory usage, and eventually crashes, when used in mobile.
Every bit of code needs to be perfected in order to maintain the user experiance. Not even talking about specific glitches in specific versions and OSes.

2. Android – when it comes to HTML5 Android sux big time.
iOS had good HTML5 support from the get go. It reached full maturity from iOS 5 which is currently all that is needed to cover the great majority of devices out there.
Android on the other hand only reached HTML5 maturity with version 4.1 which is less than 25% and going up slowly. The notorious Android fragmentation is affecting HTML5 as well.

3. HTML5 apps doesn’t easily scale in terms of features
You needs to be vigilant about every piece of code that is added.
For example, adding just a small feature like an image or a text to every item in a list can greatly hurt performance.

4. HTML5 apps doesn’t easily scale in terms of crew
You needs to be vigilant about every piece of code that is added.
In order to deliver the promise of same code base in all mobile devices and in the desktop you firstly need that all of your crew will be highly proficient. Mobile HTML5 apps can easily be ruined.
Secondly if you want that code to be used in the desktop as well, you need a greater level of harmony between members.

5. Product ppl want stuff they see on other apps.
Some of these stuff are very easy to create nativly but are extremly painfull when created in HTML5.
Product ppl needs to better understand the technology that is used.

6. Native is not that hard to do
At the end of the day wrting native apps for iOS and Android is not that difficult, it’ll be easier than HTML5 in many cases.
It’s way more diffuclt to ruin the smothness in native UI though I see many apps that manage to achive that.
An avarage native developer can easily achive good user experiance.
When writing native you can get a way with poorly written apps. Even if you will make the UI render itself 10 times more than it really needs to, you can still achive good user experiance that will satidfy most users.

7. Peer presure, don’t be a chicken
Some idiot with a rooted and very old phone, will install Android 4.0 mod (worse Android OS for HTML5). And than will start to whine that things don’t work smothly.
– That’s not even a real phone, idiot.
Announcements from facebook and linkedin ditching HTML5 in favor of native lowers the moral of HTML5 supporters and help “classic” developers that are intimidated by stuff like javascript to raise their heads.
What?! Can’t you write it in native what are you chicken – nobody ever calls me chicken (btw, this is how we’ll be in 2 years)
You will (almost) always have doubts about switching to native.

∞. It’s not over, it’s barely just begun
Don’t be let down by facebook and linkedin moving to native, it’s always depends on the type of app, resources and the kind of people involved.
Mobile HTML5 apps are deliverable and in good quality for some time already.
You will gain the benefits mentioned above of same codebase and skillset along with way better deployment model.
Done right, you can deploy new app versions like deploying a website. Without the need for approval, and without sacrificing much user experience.

The bottom line is that mobile HTML5 is here for somewhat long time already, but it’s not for everything and definitely not for everyone – yet.

HTML5 Mobile Apps – Injection Heaven, Security Hell

Three weeks ago Path.com was fined for stupidly stealing their user’s contact list and saving it onto their servers. Path’s doing was obviously wrong but I’m not sure that their punishment was really justified, needing to pay this enormous bribe to the FTC using COPPA as an excuse. The lesson here is to always comply with COPPA.

Anyhow, in that same techcrunch article you can also find that “The FTC also took the opportunity to introduce a new set of guidelines for mobile developers“. Although they explain early in that article that it’s not meant to be a guideline, I still feel they misses a lot.

When it comes to HTML5 apps even the simplest app can greatly compromise the user privacy and security. If we’ll take the FTC example of a simple and harmless alarm clock app, If that app is built using HTML5 its size and complexity doesn’t matter. All that is needed is one javascript injection that will pass thorough.

How will that code be injected you may ask – all that is needed is for the app to load some content from a remote server the simplest example will be the “Terms And Condition” page which is mostly loaded into a WebView. It can be a more “complex” settings, like choosing the favorite color or loading the saved alarms. Any kind of sharing will probably be way more open to be exploited, i.e. “share your favorite alarms”. Push messages might also bring malicious code. ETC’

The bottom line is that any injection of javascript will give an attacker a lot of control over the device, more often than not it’ll be persistant. HTML5 apps usually use the localStorage that is rarely flushed, and leverage native DBs and the file system. The “page” or webview is rarly refreshed, so even if the injection is not persistant it’ll be alive for a long time.
Things like stealing the user’s contact list and tracking the user location are pretty common. Enabled by default in iPhone PhoneGap for example.

It’s only limited by the native API that is opened to Javascript, generally it’s very open, even more than the PhoneGap default API. I know of at least 1 popular HTML5 app that opens almost all of the Android native API.

You see, Javascript is one tough beast – it can run almost anywhere.
Javascript was designed basically as a none important sidekick to the browser’s HTML, “it should not cause any problems by being poorly written and should fail silently and not interfere with the main thing that is HTML.” Seriously that how it was, we’re lucky it’s not case insensitive. I’m sure that back than some people though it’ll make it simpler and better.
So, Javascript will run in any dom element no matter how naive you may think it is, it will run in unexpected parts of the element without needing the <script> tag, i.e. onerror=”attack()”. It used to even run from CSS and from images, but we’re over that now asfaik in mobile browsers.

As opposed to that, it’ll take a very special case for injection to be able to execute arbitrary native code. You can make a native android app that will run anything – even get root, but I doubt that any legitimate app regularly download strings and run it as commands. (basically on rooted Android you can do exec(“su”) and everything else)

With Javascript the app does not need to be designed in any special way, an unsanitizes string will likely to execute.

These kind of injection are not the sole problem of PhoneGap based applications.
Any app that uses HTML5, even if it’s mostly native, any API that is opened to javascript can be leveraged by an attacker.

Phonegap (Cordova) has a mechanism to white list remote hosts which is really only effective on the iOS. It adds a little bit of security, but many apps anyway uses a wildecard “*” to allow all hosts. The wildcard is used by default in the phonegap cloud (saas solution to build phonegap apps)

As you can see the option for an attacker are enourmoe, all it needs is one vector of injection and there is an open path (no phan) to take over all of the devices of all of the users.

HTML5 apps that runs inside the mobile browser are also a nice target for injection attacks, althouygh it’s lacking most of the native api, there is still access to location in all mobile browsers. It’s less powerful for the attacker since it’ll prompt the user way more vigusly.
The Dolphin Mobile Browser implement the full phonegap native api, for example (which is generally a good thing), but it makes in-the-browser websites and apps more exposed to attacks.

So what to do than?!
– Sanitize sanitize sanitize all user input, server and client!

I Didn’t Wait for the iPhone 5

I was an happy Android user ever since the Nexus One came out (the One was the first decent Android, btw). Since than I used a few Android phones and never thought I will switch. Android is open, free, power to the people, and all that – but the fact is that the iPhone is still the best phone there is.

Last Android I used a lot is the Samsung Galaxy Nexus, it has an impressive 720 x 1280 pixels, 4.65 inches screen, and overall a very nice spec. But overall it’s a bad phone. I was totaly not impressed by it. It only become good with the Android 4.1 Jelly Bean update (only 1.2% of Androids). Google even use this phone in the Gelly Bean screenshots.

Developing mainly for mobile, I have an iPhone 4S laying around, I knew the iPhone is better but didn’t want to switch yet because I was used to the Android ecosystem, the great Gmail app and the way it sync everything nicely – this is  an area where the iOS is still lacking.

I always postpond it saying – I will switch with the iPhone 5.

But, one day it happened, I stuck my sim into the 4S and never looked back.The small screen got some time to get used to, but after a short while, you realize its qaulity is far superior than anything else.

When I first saw the leaked iPhone case I was a bit shocked – it can’t be only that, it’s exactly the same just a bit longer. If this is for real than Apple might be in trouble. Then I relized, it doesn’t matter if that only what we get, it’s still gonna be the best phone. The iPhone 4S is already the best phone, so any improvement of that is still the best phone.

Yeah, there is the note with the huge screen, and the S3 is impressive, but still these are niche phones.

Apple will not be able to go on forever with improving what they already have, they will have to reinvent the wheel – again. Hopefully that will arrive as well.

I’m still excited about every new Android version and device, but for now I’m on an iPhone.

 

Lose when you’re better

Microsoft was always used to win with inferior products. Windows was inferior to the Mac OS for many years and yet it dominated the market. Internet Explorer, the infamous browser, was the best browser for a few seconds in history when it triumphed over Netscape when both were at version 4. We still feel the stagnation it created since than being the most inferior browser ever since.

Lately Microsoft started to create better products and yet instead of winning they fail. Silverlight is better than Flash & Flex and yet it lost to it not being able to gain any significant market share (Flash is better than HTML5 but lost to it as well, but that’s a different story).

What worries me a bit now is that the truly impressive Windows 7 mobile won’t be able to gain any significance market share. Not yet saying that it’s better than the iOS (iPhone) and/or Android, but it is an impressive OS that didn’t just copy the concepts of the other two. It’ll be interesting to see what will come out of it.

Phones

Now the world is gone, Nexus one

My Nexus has finally reached it’s final destination. It travel all over the US and some other countries switched 5 hands, before ending at it’s new home, and into my arms :)

It was a lengthy and cumbersome process for one to order a Nexus one. I wouldn’t have imagined it will take so much. Special thanx goes to the special girl that coordinated the delivery.

In order to order the Nexus I had to use a proxy, as described in here. proxz.com seemed good enough. On my machine I had an issue with an anti-virus blocking proxies. Shutting down or uninstalling the AV required a password, so I had to tweak the registry in order to remove it.

I’ve paid for a 1 month US proxy from proxz, to go on the safe side. I didn’t care so much for my credit card to be stolen, anyway it’s insured. But for my google account I’ve changed the password, just in case. Loosing my gmail seems much more dangerous than loosing my CC.

I’ve pimped my Nexus with some ASCII art:

my_nexus_ascii

Beside a few tiny glitches it seems great so far. The new software update is immediately installed so I don’t have to suffer from a missing multitouch.

Many things to do now, need to play with openplug, though their best sample TweetMWC looks only OK. And where is that Flash 10.1 I was promised?