Thursday, March 31, 2011

Blogger Views

Blogger added five dynamic templates that transform blogs into interactive apps. Just add /view to the URL of a blog that offers full feeds (for example: googlesystem.blogspot.com/view) and you'll be able to try the new views: flipcard, mosaic, sidebar, snapshot and timeline. Blogger's templates offer features like infinite scrolling, progressive image loading, smart search, filtering posts by date, author or label. "These new views use the latest in web technology, including AJAX, HTML5 and CSS3," explains Google.




In the near future, bloggers will be able to customize the templates and use them without having to change the URL.

Microsoft's Antitrust Complaint

Microsoft will file a formal antitrust complaint against Google "as part of the European Commission's ongoing investigation into whether Google has violated European competition law". Brad Smith, Senior Vice President at Microsoft, says that Google's questionable business practices prevented competitors from gaining market share. As Brad Smith puts it, "Google has done much to advance its laudable mission to organize the world's information, but we're concerned by a broadening pattern of conduct aimed at stopping anyone else from creating a competitive alternative".

I was surprised to read some of the complaints.

"In 2006 Google acquired YouTube — and since then it has put in place a growing number of technical measures to restrict competing search engines from properly accessing it for their search results. Without proper access to YouTube, Bing and other search engines cannot stand with Google on an equal footing in returning search results with links to YouTube videos and that, of course, drives more users away from competitors and to Google."

YouTube is just a video sharing site. Google could prevent all the other search engines from indexing it and this shouldn't be a legal problem. But Google doesn't prevent other search engines from indexing YouTube: there are 284 million pages from youtube.com in Bing's index. Google returns more results from youtube.com (about 443 million pages), but Google owns YouTube and it can easily index all the pages. If Google prevents other search engines from indexing some videos, it's Google's problem: YouTube loses a lot of views and money from advertising.

"In 2010 and again more recently, Google blocked Microsoft's new Windows Phones from operating properly with YouTube. Google has enabled its own Android phones to access YouTube so that users can search for video categories, find favorites, see ratings, and so forth in the rich user interfaces offered by those phones. It's done the same thing for the iPhones offered by Apple, which doesn't offer a competing search service."

YouTube has some APIs for building apps, so you don't have to be a big company to develop YouTube apps. As a result, you'll find a lot of third-party YouTube apps in Apple's App Store, for example. Unfortunately, third-party apps can't use YouTube's official logo, YouTube's trademarks and there are other usage restrictions. That's probably the reason why companies like Apple, Microsoft, HTC need to partner with Google to create YouTube apps. If Microsoft couldn't reach an agreement with Google, then it's a business issue. Google has no obligation to allow other companies to create software that uses its APIs.

"Google is even restricting its customers'—namely, advertisers'—access to their own data. Advertisers input large amounts of data into Google's ad servers in the course of managing their advertising campaigns. This data belongs to the advertisers: it reflects their decisions about their own business. But Google contractually prohibits advertisers from using their data in an interoperable way with other search advertising platforms, such as Microsoft's adCenter."

AdWords offers some exporting features and even Microsoft admits that you can export AdWords data.

"One of the ways that search engines attract users is through distribution of search boxes through Web sites. Unfortunately, Google contractually blocks leading Web sites in Europe from distributing competing search boxes. It is obviously difficult for competing search engines to gain users when nearly every search box is powered by Google. Google's exclusivity terms have even blocked Microsoft from distributing its Windows Live services, such as email and online document storage, through European telecommunications companies because these services are monetized through Bing search boxes."

This seems to be a valid concern that needs to be addressed by Google. AdSense has some similar terms that prohibit using competing ad/search services on the same page, but not on the same site. The good news is that Google doesn't force the "leading Web sites in Europe" to use Google's search box and they can easily switch to Bing.

All in all, Microsoft doesn't have a strong case, but that doesn't mean that Google hasn't abused its power and that the investigation won't slow down Google. When you have 95% market share in Europe, you're almost a monopoly and an easy target for antitrust investigations.

More Google Social Search Results

When Social Search was released, Google displayed a small OneBox at the bottom of the first search results page that included relevant pages shared by your friends. A few weeks ago, Google started to show social search results anywhere on the page.

If that wasn't enough, Google added huge lists of social search results at the bottom of the second, third and fourth page of results. After the ten regular results, Google shows other ten results from your social circle. Sometimes Google's social results are useful, but that's not always the case. For example, a search for [Firefox 4] returns many outdated pages about Firefox.


It's interesting to notice that social search results need more space than the regular results:

Wednesday, March 30, 2011

Identifying App Installations

[The contents of this post grew out of an internal discussion featuring many of the usual suspects who’ve been authors in this space. — Tim Bray]

In the Android group, from time to time we hear complaints from developers about problems they’re having coming up with reliable, stable, unique device identifiers. This worries us, because we think that tracking such identifiers isn’t a good idea, and that there are better ways to achieve developers’ goals.

Tracking Installations



It is very common, and perfectly reasonable, for a developer to want to track individual installations of their apps. It sounds plausible just to call TelephonyManager.getDeviceId() and use that value to identify the installation. There are problems with this
: First, it doesn’t work reliably (see below). Second, when it does work, that value survives device wipes (“Factory resets”) and thus you could end up making a nasty mistake when one of your customers wipes their device and passes it on to another person.

To track installations, you could for example use a UUID as an identifier, and simply create a new one the first time an app runs after installation. Here is a sketch of a class named “Installation” with one static method Installation.id(Context context). You could imagine writing more installation-specific data into the INSTALLATION file.

public class Installation {
private static String sID = null;
private static final String INSTALLATION = "INSTALLATION";

public synchronized static String id(Context context) {
if (sID == null) {
File installation = new File(context.getFilesDir(), INSTALLATION);
try {
if (!installation.exists())
writeInstallationFile(installation);
sID = readInstallationFile(installation);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
return sID;
}

private static String readInstallationFile(File installation) throws IOException {
RandomAccessFile f = new RandomAccessFile(installation, "r");
byte[] bytes = new byte[(int) f.length()];
f.readFully(bytes);
f.close();
return new String(bytes);
}

private static void writeInstallationFile(File installation) throws IOException {
FileOutputStream out = new FileOutputStream(installation);
String id = UUID.randomUUID().toString();
out.write(id.getBytes());
out.close();
}
}

Identifying Devices

Suppose you feel that for the needs of your application, you need an actual hardware device identifier. This turns out to be a tricky problem.

In the past, when every Android device was a phone, things were simpler: TelephonyManager.getDeviceId() is required to return (depending on the network technology) the IMEI, MEID, or ESN of the phone, which is unique to that piece of hardware.

However, there are problems with this approach:

  • Non-phones: Wifi-only devices or music players that don’t have telephony hardware just don’t have this kind of unique identifier.


  • Persistence: On devices which do have this, it persists across device data wipes and factory resets. It’s not clear at all if, in this situation, your app should regard this as the same device.


  • Privilege:It requires READ_PHONE_STATE permission, which is irritating if you don’t otherwise use or need telephony.


  • Bugs: We have seen a few instances of production phones for which the implementation is buggy and returns garbage, for example zeros or asterisks.


Mac Address

It may be possible to retrieve a Mac address from a device’s WiFi or Bluetooth hardware. We do not recommend using this as a unique identifier. To start with, not all devices have WiFi. Also, if the WiFi is not turned on, the hardware may not report the Mac address.

Serial Number

Since Android 2.3 (“Gingerbread”) this is available via android.os.Build.SERIAL. Devices without telephony are required to report a unique device ID here; some phones may do so also.

ANDROID_ID

More specifically, Settings.Secure.ANDROID_ID. This is a 64-bit quantity that is generated and stored when the device first boots. It is reset when the device is wiped.

ANDROID_ID seems a good choice for a unique device identifier. There are downsides: First, it is not 100% reliable on releases of Android prior to 2.2 (“Froyo”). Also, there has been at least one widely-observed bug in a popular handset from a major manufacturer, where every instance has the same ANDROID_ID.

Conclusion

For the vast majority of applications, the requirement is to identify a particular installation, not a physical device. Fortunately, doing so is straightforward.

There are many good reasons for avoiding the attempt to identify a particular device. For those who want to try, the best approach is probably the use of ANDROID_ID on anything reasonably modern, with some fallback heuristics for legacy devices.

Google +1

Google +1 is yet another attempt to make Google more social. It's Google's version of the Facebook "likes", a simple feature that's very powerful because it's part of a social network.

Google will show +1 buttons next to all search results and ads, while encouraging other sites to include the buttons. All +1's are public and they're tied to Google Profiles. The goal is to use this data to personalize search results and ads by recommending sites +1'd by your friends. Google Social Search already does this, but there's no support for Facebook likes, so Google had to come up with a substitute.

"+1 is the digital shorthand for 'this is pretty cool.' To recommend something, all you have to do is click +1 on a webpage or ad you find useful. These +1's will then start appearing in Google's search results," explains Google.


This feature is slowly rolled out to Google.com, but you can try it by enabling the +1 search experiment.


One thing is clear: Google won't have to translate "+1" when it will localize the service, but it will have a hard time translating "+1's", "+1'd" and other cryptic constructs. Google +1's URLs already look weird (here's the homepage: http://www.google.com/+1).

Your +1's are listed in a profile tab, where you can manage them. There's also a page that lets you disable personalizing Google ads using +1's and other information from your Google profile.

Google now has the most important pieces of a social network (profiles, activity stream, likes, apps), but there's still no social network, no magic "glue" that connects the existing pieces. As Danny Sullivan explains, the "+1 social network" is made up of your Google Talk friends, the people from Gmail's "My contacts" group and the people you follow in Google Reader and Google Buzz, but you'll soon be able to connect other services like Twitter and Flickr. It's actually a meta social network, an artificial service that won't have too many enthusiastic users, just like Friend Connect.

Future Gmail Option: Disable Auto-Adding Contacts

Google's video that introduces the new Gmail ads shows another option that's not yet available outside Google. In the near future you'll be able to disable a feature that's often useful and sometimes annoying: automatically creating contacts when you send a message.

At the moment, "email addresses are automatically added to your Contacts list each time you use the Reply, Reply to all, or Forward functions to send messages to addresses not previously stored in your Contacts list," according to Gmail's help center. Gmail also adds the email addresses used when you compose a message.

The new option will allow you to disable this feature, but Google's description is strange: "Create contacts (sets whether sending or receiving a message can create a new contact)." Right now, Gmail doesn't automatically create contacts when you receive new messages. You need to reply to the messages first.


Here's the video (you can fast forward to 1:14 min).


{ Thanks, François. }

Tuesday, March 29, 2011

In-app Billing Launched on Android Market

[This post is by Eric Chu, Android Developer Ecosystem. —Dirk Dougherty]

Today, we're pleased to announce the launch of Android Market In-app Billing to developers and users. As an Android developer, you will now be able to publish apps that use In-app Billing and your users can make purchases from within your apps.

In-app Billing gives you more ways to monetize your apps with try-and-buy, virtual goods, upgrades, and other billing models. If you aren’t yet familiar with In-app Billing, we encourage you to learn more about it.

Several apps launching today are already using the service, including Tap Tap Revenge by Disney Mobile; Comics by ComiXology; Gun Bros, Deer Hunter Challenge HD, and WSOP3 by Glu Mobile; and Dungeon Defenders: FW Deluxe by Trendy Entertainment.

To try In-app Billing in your apps, start with the detailed documentation and complete sample app provided, which show how to implement the service in your app, set up in-app product lists in Android Market, and test your implementation. Also, it’s absolutely essential that you review the security guidelines to make sure your billing implementation is secure.

We look forward to seeing how you’ll use this new service in your apps!

Google Docs Tests Pagination

Google Docs tests a new feature that paginates documents. It will be available from View > Document view > Paginated and you'll still be able to use the compact view.

Right now, you can paginate documents using print preview, but this only shows a read-only view and it's slow.



{ Thanks, Cédric. }

Personalized Gmail Ads

Gmail will soon start to personalize ads based on your preferences.
For example, if you've recently read a lot of messages about cameras, maybe you'd like to see an offer from your local camera shop. On the other hand, if you've reported these messages as spam, or marked them 'not important' you might not want to see that offer. Soon, some of you will start seeing fewer ads overall, and focused on subjects we hope will be important to you, at the right time.

Unlike Google Search, you can disable personalized ads from Gmail's settings page. Just make sure that this option is not checked: "Show more useful ads by using importance signals from across my messages".

"Only a few users will notice the change to begin with, but as we improve it we'll roll it out more widely. As always, ads in Gmail are fully automated - no humans read your messages - and no messages or personally identifiable information about you is shared with advertisers. We've already cut down the number of ads shown per Gmail user by more than a third, and we hope these signals will enable us to continue to show fewer, better ads in Gmail," explains Google.

Google also tests a new ad format that includes offers and coupons for your local area, which might be related to Google Offers, a service that will compete with Groupon.

Google Talk Guru

Google Talk Guru is a new Google bot that lets you ask simple questions. It's "an experimental service that allows people to get information like sports results, weather forecasts, definitions etc via chat. It works on many popular chat applications that support Google Talk."

Send an invitation to guru@googlelabs.com in Gmail Chat, Google Talk or any other Jabber client and find simple facts like "weather in London", "amplitude definition", "translate souris", "2^8", "web stanford" (which returns the top Google result for [stanford]).


The service is not as powerful as Google SMS, but it's still handy.

{ Thanks, Michael. }

Monday, March 28, 2011

Chrome Bookmarks Integrate with Google Search

Until recently, Google Bookmarks and Chrome Bookmarks were two separate features that didn't speak the same language. Even if you could save your Chrome bookmarks to a Google account, they weren't saved to Google Bookmarks. For some reason, your bookmarks are available in a special Google Docs folder.

Chrome bookmarks have a web interface, but it's likely that the obvious will happen: Chrome bookmarks could be saved to Google Bookmarks. Jérôme Flipo noticed that the Google Bookmarks OneBox already includes Chrome bookmarks. I've tried to find SmallNetBuilder.com and Google's OneBox returned it even if it was starred in Chrome, not in Google Bookmarks.


Thursday, March 24, 2011

Google Video Previews

Google's instant previews for video sites weren't very useful because most video sites use Flash and the software that generates thumbnails can't handle Flash. That's probably one of the reasons why Google replaced the standard screenshots with short clips from the videos. By default, the sound is muted, but you can change this setting. The feature is also available at Google Video next to some search results.

"When it comes to videos, people want to spend less time searching and more time watching. That's why we added an enhancement to Instant Previews—the ability to preview videos. Click once on the magnifying glass next to the title of any video search result in universal or video mode. For some videos, you'll now be able to play through a set of four short segments from the video to see if it’s what you’re looking for (video providers have to opt to make the previews available, so you won't find it for every video yet)," explains Google.


Even if Google announced this feature a couple of weeks ago, it's still spotty, so it may not be available for you. You can also try Bing's Video Search, which offers a similar feature that probably inspired Google.

Yahoo Search Direct

Yahoo has recently launched a new feature called Yahoo Search Direct that aims to find answers for simple questions. "Search Direct is the first fundamental shift in search in more than a decade. For the first time, driving users to a results page filled with an overwhelming number of links is not the end game. We believe Search Direct will be the simplest and fastest way to find answers, not links," suggests Yahoo.

Yahoo Search Direct doesn't show new information, but it highlights the top results and the instant answers, while displaying them as you type a query. It's a simplified version of Google Instant that only focuses on the navigational queries and the queries that request simple facts.

When I tried Yahoo Search Direct, I noticed at least two features that aren't Googley. Yahoo shows a list of "trending searches" when you click on the search box and even highlights the first suggestion. This is both distracting and confusing for the average user that expects relevant suggestions.


Another feature that's not very helpful is promoting your own services, instead of showing unbiased suggestions. When you type "w", Yahoo shows only two suggestions that seem to be manually added: "Yahoo! Weather" and "Yahoo! Widgets". Type "m" and Yahoo shows 8 suggestions that are related to Yahoo.


Yahoo Search Direct works best for queries that already returned OneBox-like instant answers: [weather in london], [MSFT], [SF Giants] and the main advantage is that the answers are displayed faster. Google tried something similar with Google Suggest, but this feature is no longer necessary now that the results are displayed as you type.


Yahoo's tool doesn't even show previews for long-tail searches, so it can't replace Google Instant.


Yahoo promises that this is "the beginning of a new era in search", but this seems to be just an exaggeration. "We've been focused on refining how you use search, enabling awesome experiences for search intents about sports, news, TV, movies, local, finance, shopping, travel, weather, trending searches or pretty much anything else. But this is just the beginning. The coverage and rich content currently available in Search Direct is a fraction of the future state. Users can expect search coverage and the use of rich content to increase dramatically in the weeks, months, and years ahead. Get ready to be more social and personalized, through a richer and more interactive experience – it's going to be sweet."

You can try the beta version of Yahoo Search Direct at search.yahoo.com, but it will soon be available at yahoo.com.

{ Thanks, Niraj. }

In-App Billing on Android Market: Ready for Testing

[This post is by Eric Chu, Android Developer Ecosystem. —Dirk Dougherty]

Back in January we announced our plan to introduce Android Market In-app Billing this quarter. We're pleased to let you know that we will be launching In-app Billing next week.

In preparation for the launch, we are opening up Android Market for upload and end-to-end testing of your apps that use In-app Billing. You can now upload your apps to the Developer Console, create a catalog of in-app products, and set prices for them. You can then set up accounts to test in-app purchases. During these test transactions, the In-app Billing service interacts with your app exactly as it will for actual users and live transactions.

Note that although you can upload apps during this test development phase, you won’t be able to actually publish the apps to users until the full launch of the service next week.


To get you started, we’ve updated the developer documentation with information about how to set up product lists and test your in-app products. Also, it is absolutely essential that you review the security guidelines to make sure your billing implementation is secure.

We encourage you start uploading and testing your apps right away.

Upgrading Documents to the New Google Docs Editor

Last year's update of the Google Docs word processor had an important flaw: no backwards compatibility. You couldn't open your old documents in the new editor and you couldn't even upgrade your existing documents to the new format. Even if it's not obvious, Google Docs has two word processors that handle two incompatible native formats.

The bad news is that Google can't provide a smooth upgrade path. The changes are so profound that the new Google Docs editor can't import your old documents properly. If you open a document created using the old Google Docs editor, you'll notice a message informing you that the document can be previewed in the latest version of the editor. After previewing the document, you have the option to update the document.




Unfortunately, if you update the document, you'll lose the revision history and some formatting options that were available in the old Google Docs.


"When you preview your upgraded document, you may notice that the formatting looks different. Older documents were basically webpages. To use them in the new version of Google documents, they need to be converted to a traditional word processing format. This conversion can be imperfect. It's not possible to edit the HTML of your document or use CSS after you upgrade," explains Google.

Another drawback is that you need to manually update each document. To make sure that you won't miss some features that were available in the old editor, Google didn't provide an automatic conversion option. Most people won't bother updating their documents and Google will be forced to keep the old Google Docs editor forever.

{ Thanks, Bogdan. }

Memory Analysis for Android Applications

[This post is by Patrick Dubroy, an Android engineer who writes about programming, usability, and interaction on his personal blog. — Tim Bray]

The Dalvik runtime may be garbage-collected, but that doesn't mean you can ignore memory management. You should be especially mindful of memory usage on mobile devices, where memory is more constrained. In this article, we're going to take a look at some of the memory profiling tools in the Android SDK that can help you trim your application's memory usage.

Some memory usage problems are obvious. For example, if your app leaks memory every time the user touches the screen, it will probably trigger an OutOfMemoryError eventually and crash your app. Other problems are more subtle, and may just degrade the performance of both your app (as garbage collections are more frequent and take longer) and the entire system.

Tools of the trade

The Android SDK provides two main ways of profiling the memory usage of an app: the Allocation Tracker tab in DDMS, and heap dumps. The Allocation Tracker is useful when you want to get a sense of what kinds of allocation are happening over a given time period, but it doesn't give you any information about the overall state of your application's heap. For more information about the Allocation Tracker, see the article on Tracking Memory Allocations. The rest of this article will focus on heap dumps, which are a more powerful memory analysis tool.

A heap dump is a snapshot of an application's heap, which is stored in a binary format called HPROF. Dalvik uses a format that is similar, but not identical, to the HPROF tool in Java. There are a few ways to generate a heap dump of a running Android app. One way is to use the Dump HPROF file button in DDMS. If you need to be more precise about when the dump is created, you can also create a heap dump programmatically by using the android.os.Debug.dumpHprofData() function.

To analyze a heap dump, you can use a standard tool like jhat or the Eclipse Memory Analyzer (MAT). However, first you'll need to convert the .hprof file from the Dalvik format to the J2SE HPROF format. You can do this using the hprof-conv tool provided in the Android SDK. For example:

hprof-conv dump.hprof converted-dump.hprof

Example: Debugging a memory leak

In the Dalvik runtime, the programmer doesn't explicitly allocate and free memory, so you can't really leak memory like you can in languages like C and C++. A "memory leak" in your code is when you keep a reference to an object that is no longer needed. Sometimes a single reference can prevent a large set of objects from being garbage collected.

Let's walk through an example using the Honeycomb Gallery sample app from the Android SDK. It's a simple photo gallery application that demonstrates how to use some of the new Honeycomb APIs. (To build and download the sample code, see the instructions.) We're going to deliberately add a memory leak to this app in order to demonstrate how it could be debugged.

Imagine that we want to modify this app to pull images from the network. In order to make it more responsive, we might decide to implement a cache which holds recently-viewed images. We can do that by making a few small changes to ContentFragment.java. At the top of the class, let's add a new static variable:

private static HashMap<String,Bitmap> sBitmapCache = new HashMap<String,Bitmap>();

This is where we'll cache the Bitmaps that we load. Now we can change the updateContentAndRecycleBitmap() method to check the cache before loading, and to add Bitmaps to the cache after they're loaded.

void updateContentAndRecycleBitmap(int category, int position) {
if (mCurrentActionMode != null) {
mCurrentActionMode.finish();
}

// Get the bitmap that needs to be drawn and update the ImageView.

// Check if the Bitmap is already in the cache
String bitmapId = "" + category + "." + position;
mBitmap = sBitmapCache.get(bitmapId);

if (mBitmap == null) {
// It's not in the cache, so load the Bitmap and add it to the cache.
// DANGER! We add items to this cache without ever removing any.
mBitmap = Directory.getCategory(category).getEntry(position)
.getBitmap(getResources());
sBitmapCache.put(bitmapId, mBitmap);
}
((ImageView) getView().findViewById(R.id.image)).setImageBitmap(mBitmap);
}

I've deliberately introduced a memory leak here: we add Bitmaps to the cache without ever removing them. In a real app, we'd probably want to limit the size of the cache in some way.

Examining heap usage in DDMS

The Dalvik Debug Monitor Server (DDMS) is one of the primary Android debugging tools. DDMS is part of the ADT Eclipse plug-in, and a standalone version can also be found in the tools/ directory of the Android SDK. For more information on DDMS, see Using DDMS.

Let's use DDMS to examine the heap usage of this app. You can start up DDMS in one of two ways:

  • from Eclipse: click Window > Open Perspective > Other... > DDMS
  • or from the command line: run ddms (or ./ddms on Mac/Linux) in the tools/ directory

Select the process com.example.android.hcgallery in the left pane, and then click the Show heap updates button in the toolbar. Then, switch to the VM Heap tab in DDMS. It shows some basic stats about our heap memory usage, updated after every GC. To see the first update, click the Cause GC button.

We can see that our live set (the Allocated column) is a little over 8MB. Now flip through the photos, and watch that number go up. Since there are only 13 photos in this app, the amount of memory we leak is bounded. In some ways, this is the worst kind of leak to have, because we never get an OutOfMemoryError indicating that we are leaking.

Creating a heap dump

Let's use a heap dump to track down the problem. Click the Dump HPROF file button in the DDMS toolbar, choose where you want to save the file, and then run hprof-conv on it. In this example, I'll be using the standalone version of MAT (version 1.0.1), available from the MAT download site.

If you're running ADT (which includes a plug-in version of DDMS) and have MAT installed in Eclipse as well, clicking the “dump HPROF” button will automatically do the conversion (using hprof-conv) and open the converted hprof file into Eclipse (which will be opened by MAT).

Analyzing heap dumps using MAT

Start up MAT and load the converted HPROF file we just created. MAT is a powerful tool, and it's beyond the scope of this article to explain all it's features, so I'm just going to show you one way you can use it to detect a leak: the Histogram view. The Histogram view shows a list of classes sortable by the number of instances, the shallow heap (total amount of memory used by all instances), or the retained heap (total amount of memory kept alive by all instances, including other objects that they have references to).

If we sort by shallow heap, we can see that instances of byte[] are at the top. As of Android 3.0 (Honeycomb), the pixel data for Bitmap objects is stored in byte arrays (previously it was not stored in the Dalvik heap), and based on the size of these objects, it's a safe bet that they are the backing memory for our leaked bitmaps.

Right-click on the byte[] class and select List Objects > with incoming references. This produces a list of all byte arrays in the heap, which we can sort based on Shallow Heap usage.

Pick one of the big objects, and drill down on it. This will show you the path from the root set to the object -- the chain of references that keeps this object alive. Lo and behold, there's our bitmap cache!

MAT can't tell us for sure that this is a leak, because it doesn't know whether these objects are needed or not -- only the programmer can do that. In this case, the cache is using a large amount of memory relative to the rest of the application, so we might consider limiting the size of the cache.

Comparing heap dumps with MAT

When debugging memory leaks, sometimes it's useful to compare the heap state at two different points in time. To do this, you'll need to create two separate HPROF files (don't forget to convert them using hprof-conv).

Here's how you can compare two heap dumps in MAT (it's a little complicated):

  1. Open the first HPROF file (using File > Open Heap Dump).
  2. Open the Histogram view.
  3. In the Navigation History view (use Window > Navigation History if it's not visible), right click on histogram and select Add to Compare Basket.
  4. Open the second HPROF file and repeat steps 2 and 3.
  5. Switch to the Compare Basket view, and click Compare the Results (the red "!" icon in the top right corner of the view).

Conclusion

In this article, I've shown how the Allocation Tracker and heap dumps can give you get a better sense of your application's memory usage. I also showed how The Eclipse Memory Analyzer (MAT) can help you track down memory leaks in your app. MAT is a powerful tool, and I've only scratched the surface of what you can do with it. If you'd like to learn more, I recommend reading some of these articles:

Sunday, March 20, 2011

Google Chrome's Experimental New Tab Page for Touch Screens

A recent Chromium build added a new option to the about:flags page: an experimental new tab page. The updated new tab page is a work in progress and it's optimized for touch screens. Right now, it only includes the web apps you've previously installed, which can be organized in multiple home screens.

"The idea with this touch NTP is to focus (for now) on apps, and make it easy
to arrange them into pages. You can swipe/drag to switch pages, and press
and hold to lift an app and rearrange it," explains Google.


I found an interesting comment in one of Google's JavaScript files: "Note that, while the product portion of the touch NTP is designed to work just in the latest version of Chrome, this hack attempts to add some support for working in older browsers to enable testing and demonstration on existing tablet platforms. In particular, this code has been tested to work on Mobile Safari in iOS 4.2. The goal is that the need to support any other browser should not leak out of this file - and so we will hack global JS objects as necessary here to present the illusion of running on the latest version of Chrome."

{ via ConceivablyTech. Thanks, François Beaufort. }

Installing an Application Using Internet Explorer 9

I tried to download the latest Chromium build using Internet Explorer 9 and it was one of the most painful downloading experiences. Microsoft tries to protect users from downloading malware and uses a feature called SmartScreen Filter that "checks software downloads against a dynamically updated list of reported malicious software sites". This feature was available in IE8, but the latest version of IE tried to improve it by analyzing application reputation.

"In analyzing software downloads actively in use on the internet today, we found that most have an established download footprint and no history of malware. This was the genesis of SmartScreen application reputation. By removing unnecessary warnings, the remaining warnings become relevant. With SmartScreen Application Reputation, IE9 warns you before you run or save a higher risk program that may be an attempt to infect your computer with socially engineered malware. IE9 also stays out of the way for downloads with an established reputation. Based on real-world data we estimate that this new warning will be seen only 2-3 times a year for most consumers compared to today where there is a warning for every software download."

Here's how difficult is to run mini_installer.exe, Chromium's installer:

Step 1: "Do you want to run or save this program"? Click "run".


Step 2: "This file is not commonly downloaded and could harm your computer." You have two options: "delete" and "actions". It's quite uncommon to label a button using a noun, but the only reasonable option is the generic "actions".

A help page explains that "when you download a program from the Internet, SmartScreen Filter will check the program against a list of programs that are downloaded by a significant number of other Internet Explorer users and a list of programs that are known to be unsafe. If the program you're downloading isn't on either list, SmartScreen Filter will display a warning that the file isn't 'commonly downloaded.' It doesn't necessarily mean the website is fraudulent or that the program is malware, but you probably shouldn't download or install the program unless you trust the website and the publisher."


Step 3: IE9 shows a modal dialog which informs you that "this program might harm your computer". Even though "SmartScreen Filter has little or no information" about the program, Microsoft's engineers thought it's a good idea to show two main options "don't run this program" and "delete program", followed by a cryptic "more options" drop-down. I clicked "more options" because I really wanted to install the program. (Update: this step was skipped the second time I tried to install the same file.)


Step 4: Microsoft finally shows the obvious option: "run anyway", but still recommends not to run the program.


There's a fine line between protecting users and annoying them, but IE9 managed to cross it.

Saturday, March 19, 2011

Quickly Edit Google Calendar Events

You no longer have to double click on a Google Calendar event to edit its name. Now you can just click on the event's name and quickly edit it from the description balloon.


{ Thanks, Maarten. }

Wednesday, March 16, 2011

Google Docs Discussions

Google Docs improved the commenting system, by adding support for conversations.


"To start, we've improved the discussion flow by adding ownership and edit rights to individual comments. Each comment now has a timestamp and profile picture. Google Docs doesn't force you to delete comments. Instead, you can resolve comments to remove them from the visible document and view them later by clicking the discussions button at the top of any document," mentions Google.

One of the most useful new features is the support for notifications, which works just like in Google Buzz. Reply to a comment and the author of that comment will get an email notification. He'll be able to answer to your reply from the email interface, without having to visit Google Docs. Google also sends notifications if you're mentioned in a thread.

Unfortunately, discussions are only available for new documents. Google says that the explanation is that the new feature includes "a number of significant improvements".



{ Thanks, Andrew. }

New Chrome Logo

The latest Chrome Dev Channel release comes with a new Chrome logo that's more plain and boring, but looks better as a desktop icon. Even if not many people will switch to a different browser just because they don't like the new logo, Chrome lost some of its magic by switching to a visual identity that's no longer vibrant and picturesque. Here's the new Chrome icon:



... and the old Chrome icon:





There's also a new logo for Chromium, the open source browser that powers Google Chrome:

{ Thanks, Kuba, Stefan, Dani, Daniel and Cameron. }

Google's iPhone App, a Preview of the Mobile Search Interface

Google updated the search app for iPhone and unveiled a completely new interface that uses gestures for navigation. There are only two gestures, but they're so simple, powerful and intuitive that I'm sure they'll be used in other mobile Google interfaces.

"When browsing through search results or looking at a webpage, you can swipe down to see the search bar or change your settings. (...) We also included a new toolbar that will make it easier for you to filter your results. You can open this toolbar by swiping from left to right — either before you search or once you've got your results," explains Google.

The new gestures are easy to learn and they're more expressive than buttons. You can swipe down to see the search box even after clicking a search result.



Application Stats on Android Market

[This post is by Eric Chu, Android Developer Ecosystem. —Dirk Dougherty]

On the Android Market team, it’s been our goal to bring you improved ways of seeing and understanding the installation performance of your published applications. We know that this information is critical in helping you tune your development and marketing efforts. Today I’m pleased to let you know about an important new feature that we’ve added to Android Market called Application Statistics.

Application Statistics is a new type of dashboard in the Market Developer Console that gives you an overview of the installation performance of your apps. It provides charts and tables that summarize each app’s active installation trend over time, as well as its distribution across key dimensions such as Android platform versions, devices, user countries, and user languages. For additional context, the dashboard also shows the comparable aggregate distribution for all app installs from Android Market (numbering in the billions). You could use this data to observe how your app performs relative to the rest of Market or decide what to develop next.


To start with, we’ve seeded the application Statistics dashboards with data going back to December 22, 2010. Going forward, we’ll be updating the data daily.

We encourage you to check out these new dashboards and we hope they’ll give you new and useful insights into your apps’ installation performance. You can access the Statistics dashboards from the main Listings page in the Developer Console.

Watch for more announcements soon. We are continuing to work hard to deliver more reporting features to help you manage your products successfully on Android Market.

Tuesday, March 15, 2011

No More Starred Results in Google Search

Last year, Google replaced SearchWiki with starred results. You only had to click on a star to bookmark a search result and to quickly find it later.

Unfortunately, this feature is no longer available and you have to find other ways to bookmark search results: bookmarklets, Google Toolbar and other extensions.

A Google employee confirmed this change. "The Star feature no longer exists on Google. The Star function continues to exist through google.com/bookmarks though. Anything you previously starred will show up when you visit bookmarks."


Starred results and SearchWiki were really useful for refinding web pages, but probably not many people used them. These features were a lot more useful than Instant Preview, which is still available.

{ Thanks, Joel. }

Monday, March 14, 2011

Android 3.0 Hardware Acceleration

[This post is by Romain Guy, who likes things on your screen to move fast. —Tim Bray]

One of the biggest changes we made to Android for Honeycomb is the addition of a new rendering pipeline so that applications can benefit from hardware accelerated 2D graphics. Hardware accelerated graphics is nothing new to the Android platform, it has always been used for windows composition or OpenGL games for instance, but with this new rendering pipeline applications can benefit from an extra boost in performance. On a Motorola Xoom device, all the standard applications like Browser and Calendar use hardware-accelerated 2D graphics.

In this article, I will show you how to enable the hardware accelerated 2D graphics pipeline in your application and give you a few tips on how to use it properly.

Go faster

To enable the hardware accelerated 2D graphics, open your AndroidManifest.xml file and add the following attribute to the <application /> tag:

    android:hardwareAccelerated="true"

If your application uses only standard widgets and drawables, this should be all you need to do. Once hardware acceleration is enabled, all drawing operations performed on a View's Canvas are performed using the GPU.

If you have custom drawing code you might need to do a bit more, which is in part why hardware acceleration is not enabled by default. And it's why you might want to read the rest of this article, to understand some of the important details of acceleration.

Controlling hardware acceleration

Because of the characteristics of the new rendering pipeline, you might run into issues with your application. Problems usually manifest themselves as invisible elements, exceptions or different-looking pixels. To help you, Android gives you 4 different ways to control hardware acceleration. You can enable or disable it on the following elements:

  • Application

  • Activity

  • Window

  • View

To enable or disable hardware acceleration at the application or activity level, use the XML attribute mentioned earlier. The following snippet enables hardware acceleration for the entire application but disables it for one activity:

    <application android:hardwareAccelerated="true">
<activity ... />
<activity android:hardwareAccelerated="false" />
</application>

If you need more fine-grained control, you can enable hardware acceleration for a given window at runtime:

    getWindow().setFlags(
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);

Note that you currently cannot disable hardware acceleration at the window level. Finally, hardware acceleration can be disabled on individual views:

    view.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

Layer types have many other usages that will be described later.

Am I hardware accelerated?

It is sometimes useful for an application, or more likely a custom view, to know whether it currently is hardware accelerated. This is particularly useful if your application does a lot of custom drawing and not all operations are properly supported by the new rendering pipeline.

There are two different ways to check whether the application is hardware accelerated:

If you must do this check in your drawing code, it is highly recommended to use Canvas.isHardwareAccelerated() instead of View.isHardwareAccelerated(). Indeed, even when a View is attached to a hardware accelerated window, it can be drawn using a non-hardware accelerated Canvas. This happens for instance when drawing a View into a bitmap for caching purpose.

What drawing operations are supported?

The current hardware accelerated 2D pipeline supports the most commonly used Canvas operations, and then some. We implemented all the operations needed to render the built-in applications, all the default widgets and layouts, and common advanced visual effects (reflections, tiled textures, etc.) There are however a few operations that are currently not supported, but might be in a future version of Android:

  • Canvas
    • clipPath

    • clipRegion

    • drawPicture

    • drawPoints

    • drawPosText

    • drawTextOnPath

    • drawVertices


  • Paint
    • setLinearText

    • setMaskFilter

    • setRasterizer


In addition, some operations behave differently when hardware acceleration enabled:

  • Canvas
    • clipRect: XOR, Difference and ReverseDifference clip modes are ignored; 3D transforms do not apply to the clip rectangle

    • drawBitmapMesh: colors array is ignored

    • drawLines: anti-aliasing is not supported

    • setDrawFilter: can be set, but ignored


  • Paint
    • setDither: ignored

    • setFilterBitmap: filtering is always on

    • setShadowLayer: works with text only


  • ComposeShader
    • A ComposeShader can only contain shaders of different types (a BitmapShader and a LinearGradientShader for instance, but not two instances of BitmapShader)

    • A ComposeShader cannot contain a ComposeShader


If drawing code in one of your views is affected by any of the missing features or limitations, you don't have to miss out on the advantages of hardware acceleration for your overall application. Instead, consider rendering the problematic view into a bitmap or setting its layer type to LAYER_TYPE_SOFTWARE. In both cases, you will switch back to the software rendering pipeline.

Dos and don'ts

Switching to hardware accelerated 2D graphics is a great way to get smoother animations and faster rendering in your application but it is by no means a magic bullet. Your application should be designed and implemented to be GPU friendly. It is easier than you might think if you follow these recommendations:

  • Reduce the number of Views in your application: the more Views the system has to draw, the slower it will be. This applies to the software pipeline as well; it is one of the easiest ways to optimize your UI.

  • Avoid overdraw: always make sure that you are not drawing too many layers on top of each other. In particular, make sure to remove any Views that are completely obscured by other opaque views on top of it. If you need to draw several layers blended on top of each other consider merging them into a single one. A good rule of thumb with current hardware is to not draw more than 2.5 times the number of pixels on screen per frame (and transparent pixels in a bitmap count!)

  • Don't create render objects in draw methods: a common mistake is to create a new Paint, or a new Path, every time a rendering method is invoked. This is not only wasteful, forcing the system to run the GC more often, it also bypasses caches and optimizations in the hardware pipeline.

  • Don't modify shapes too often: complex shapes, paths and circles for instance, are rendered using texture masks. Every time you create or modify a Path, the hardware pipeline must create a new mask, which can be expensive.

  • Don't modify bitmaps too often: every time you change the content of a bitmap, it needs to be uploaded again as a GPU texture the next time you draw it.

  • Use alpha with care: when a View is made translucent using View.setAlpha(), an AlphaAnimation or an ObjectAnimator animating the “alpha” property, it is rendered in an off-screen buffer which doubles the required fill-rate. When applying alpha on very large views, consider setting the View's layer type to LAYER_TYPE_HARDWARE.

View layers

Since Android 1.0, Views have had the ability to render into off-screen buffers, either by using a View's drawing cache, or by using Canvas.saveLayer(). Off-screen buffers, or layers, have several interesting usages. They can be used to get better performance when animating complex Views or to apply composition effects. For instance, fade effects are implemented by using Canvas.saveLayer() to temporarily render a View into a layer and then compositing it back on screen with an opacity factor.

Because layers are so useful, Android 3.0 gives you more control on how and when to use them. To to so, we have introduced a new API called View.setLayerType(int type, Paint p). This API takes two parameters: the type of layer you want to use and an optional Paint that describes how the layer should be composited. The paint parameter may be used to apply color filters, special blending modes or opacity to a layer. A View can use one of 3 layer types:

  • LAYER_TYPE_NONE: the View is rendered normally, and is not backed by an off-screen buffer.

  • LAYER_TYPE_HARDWARE: the View is rendered in hardware into a hardware texture if the application is hardware accelerated. If the application is not hardware accelerated, this layer type behaves the same as LAYER_TYPE_SOFTWARE.

  • LAYER_TYPE_SOFTWARE: the View is rendered in software into a bitmap

The type of layer you will use depends on your goal:

  • Performance: use a hardware layer type to render a View into a hardware texture. Once a View is rendered into a layer, its drawing code does not have to be executed until the View calls invalidate(). Some animations, for instance alpha animations, can then be applied directly onto the layer, which is very efficient for the GPU to do.

  • Visual effects: use a hardware or software layer type and a Paint to apply special visual treatments to a View. For instance, you can draw a View in black and white using a ColorMatrixColorFilter.

  • Compatibility: use a software layer type to force a View to be rendered in software. This is an easy way to work around limitations of the hardware rendering pipeline.

Layers and animations

Hardware-accelerated 2D graphics help deliver a faster and smoother user experience, especially when it comes to animations. Running an animation at 60 frames per second is not always possible when animating complex views that issue a lot of drawing operations. If you are running an animation in your application and do not obtain the smooth results you want, consider enabling hardware layers on your animated views.

When a View is backed by a hardware layer, some of its properties are handled by the way the layer is composited on screen. Setting these properties will be efficient because they do not require the view to be invalidated and redrawn. Here is the list of properties that will affect the way the layer is composited; calling the setter for any of these properties will result in optimal invalidation and no redraw of the targeted View:

  • alpha: to change the layer's opacity

  • x, y, translationX, translationY: to change the layer's position

  • scaleX, scaleY: to change the layer's size

  • rotation, rotationX, rotationY: to change the layer's orientation in 3D space

  • pivotX, pivotY: to change the layer's transformations origin

These properties are the names used when animating a View with an ObjectAnimator. If you want to set/get these properties, call the appropriate setter or getter. For instance, to modify the alpha property, call setAlpha(). The following code snippet shows the most efficient way to rotate a View in 3D around the Y axis:

    view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
ObjectAnimator.ofFloat(view, "rotationY", 180).start();

Since hardware layers consume video memory, it is highly recommended you enable them only for the duration of the animation. This can be achieved with animation listeners:

    view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
ObjectAnimator animator = ObjectAnimator.ofFloat(
view, "rotationY", 180);
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
view.setLayerType(View.LAYER_TYPE_NONE, null);
}
});
animator.start();

New drawing model

Along with hardware-accelerated 2D graphics, Android 3.0 introduces another major change in the UI toolkit’s drawing model: display lists, which are only enabled when hardware acceleration is turned on. To fully understand display lists and how they may affect your application it is important to also understand how Views are drawn.

Whenever an application needs to update a part of its UI, it invokes invalidate() (or one of its variants) on any View whose content has changed. The invalidation messages are propagated all the way up the view hierarchy to compute the dirty region; the region of the screen that needs to be redrawn. The system then draws any View in the hierarchy that intersects with the dirty region. The drawing model is therefore made of two stages:

  1. Invalidate the hierarchy

  2. Draw the hierarchy

There are unfortunately two drawbacks to this approach. First, this drawing model requires execution of a lot of code on every draw pass. Imagine for instance your application calls invalidate() on a button and that button sits on top of a more complex View like a MapView. When it comes time to draw, the drawing code of the MapView will be executed even though the MapView itself has not changed.

The second issue with that approach is that it can hide bugs in your application. Since views are redrawn anytime they intersect with the dirty region, a View whose content you changed might be redrawn even though invalidate() was not called on it. When this happens, you are relying on another View getting invalidated to obtain the proper behavior. Needless to say, this behavior can change every time you modify your application ever so slightly. Remember this rule: always call invalidate() on a View whenever you modify data or state that affects this View’s drawing code. This applies only to custom code since setting standard properties, like the background color or the text in a TextView, will cause invalidate() to be called properly internally.

Android 3.0 still relies on invalidate() to request screen updates and draw() to render views. The difference is in how the drawing code is handled internally. Rather than executing the drawing commands immediately, the UI toolkit now records them inside display lists. This means that display lists do not contain any logic, but rather the output of the view hierarchy’s drawing code. Another interesting optimization is that the system only needs to record/update display lists for views marked dirty by an invalidate() call; views that have not been invalidated can be redrawn simply by re-issuing the previously recorded display list. The new drawing model now contains 3 stages:

  1. Invalidate the hierarchy

  2. Record/update display lists

  3. Draw the display lists

With this model, you cannot rely on a View intersecting the dirty region to have its draw() method executed anymore: to ensure that a View’s display list will be recorded, you must call invalidate(). This kind of bug becomes very obvious with hardware acceleration turned on and is easy to fix: you would see the previous content of a View after changing it.

Using display lists also benefits animation performance. In the previous section, we saw that setting specific properties (alpha, rotation, etc.) does not require invalidating the targeted View. This optimization also applies to views with display lists (any View when your application is hardware accelerated.) Let’s imagine you want to change the opacity of a ListView embedded inside a LinearLayout, above a Button. Here is what the (simplified) display list of the LinearLayout looks like before changing the list’s opacity:

    DrawDisplayList(ListView)
DrawDisplayList(Button)

After invoking listView.setAlpha(0.5f) the display list now contains this:

    SaveLayerAlpha(0.5)
DrawDisplayList(ListView)
Restore
DrawDisplayList(Button)

The complex drawing code of ListView was not executed. Instead the system only updated the display list of the much simpler LinearLayout. In previous versions of Android, or in an application without hardware acceleration enabled, the drawing code of both the list and its parent would have to be executed again.

It’s your turn

Enabling hardware accelerated 2D graphics in your application is easy, particularly if you rely solely on standard views and drawables. Just keep in mind the few limitations and potential issues described in this document and make sure to thoroughly test your application!

WebM Plugin for Internet Explorer 9

Internet Explorer 9 will be released later today and one of the many new features is the native support for videos. Unfortunately for Google, Microsoft decided to only support H.264 videos by default, so you can't watch WebM videos without installing additional software.

To solve this problem, Google developed a WebM plugin for IE9. "They said elephants couldn't ride flying dolphins. They said that one of the world's most popular browsers couldn't play WebM video in HTML5. They were wrong," mentions Google half-jokingly.

The plugin only works on Windows 7 and Windows Vista, the two operating systems supported by IE9. Google suggests to search for WebM videos on YouTube, but I'm not sure if the plugin was really necessary since YouTube's HTML5 player also works with H.264 videos.


Last month, Microsoft released a plugin for watching H.264 videos in Google Chrome that will be useful when Google drops support for the popular codec.

Google Toolbar 8, Powered by Google Chrome

After Google released Chrome, Google Toolbar's development slowed down. That's because Google Toolbar is no longer the primary vehicle for adding browser features and Google mostly focused on improving Chrome.

Google Toolbar 8 is a completely new version of Google's add-on that was available as part of Google Labs. "Google Toolbar 8 is actually built and runs on top of the Google Chrome Frame platform. This means that Toolbar 8 will run more like a web app in that it can be customized and updated much more frequently and easily. It also means that Google Chrome Frame is installed at the time of Toolbar 8 installation," explains Google.


The new version of Google's toolbar only works in Internet Explorer right now and it doesn't include all the features that are currently available in the latest public version. Google included some new features: buttons for the most visited sites, Google Dictionary integration and Google Instant. "Google Toolbar displays up to seven of your most visited sites as buttons. Click on a button to go directly to its site. When you download the new Google Toolbar your toolbar will display buttons for Gmail, Google Calendar, Google Docs, Youtube, Google News, Google Reader and Google Tasks by default."

Upcoming Blogger Features

Google rarely preannounces new features, so I was really surprised to see a video that highlights some upcoming Blogger features. Google's video does a great job at enumerating the latest Blogger improvements, while asking people: "Have you looked at Blogger lately?".

Google plans to unveil a completely new Blogger interface, mobile templates for blogs (which are already available at Blogger in Draft) and a feature that lets you find related posts and videos.






Here's the video: