Friday, February 20, 2009

[Gd] Developer Preview Releases for the Visualization API

| More

Google Code Blog: Developer Preview Releases for the Visualization API

By Nir Bar-Lev, Google Product Management

We are now offering Visualization API developers an opportunity to preview upcoming release candidates.  Developers can opt in to these bleeding-edge builds simply by changing one line of code when loading the Visualization library.

Developers can use these release candidates as an opportunity to see what new features being developed, test upcoming changes in their applications in advance, and provide the Google team with valuable feedback on the Visualization API discussion group.

More details of the new process can be found in our Release Notes documentation.  And please be sure to check out all the available visualizations and new Tools Gallery while you're there.

We hope to see you at Google I/O in May where we will be hosting several sessions to teach you how to be more productive than ever with the Visualization API.
URL: http://google-code-updates.blogspot.com/2009/02/developer-preview-releases-for.html

[Gd] SketchUp in your language

| More

Official Google SketchUp Blog: SketchUp in your language

Google SketchUp is '3D for Everyone' but, of course, not everyone speaks English. For some time now, SketchUp has been available in French, Italian, German, Spanish, and Japanese. But that still left out lots of the people in the world.

Today, I'd like to say "witamy, bem-vindo, Добро пожаловать, and welkom" as we release new language support for SketchUp in Polish, Brazilian Portuguese, Russian, and Dutch. If you don't see your language yet, don't worry. We're not done yet, and we'll have more news to announce soon. Enjoy, and happy modeling!

Posted by John Bacus, SketchUp Product Manager
URL: http://sketchupdate.blogspot.com/2009/02/sketchup-in-your-language.html

[Gd] Fast exploratory tests with IFrames

| More

Google Testing Blog: Fast exploratory tests with IFrames

by Håvard Rast Blok

While working with a search quality development team, I was asked to collect information from their result pages across all the supported languages. The aim was to quickly get an overview, and then manually look through them for irregularities. One option would have been to grab the pages using tools like Selenium or WebDriver. However, this would have been complex and expensive. Instead, I opted for a much simpler solution: Display each language variation in a separate IFrame within the same HTML page.



An example of how this looks, can be seen here, where the Google Search page is shown in 43 different languages. There are also some links for other Google sites, or you can type in your own link, and the query attribute for language, "hl=", will be appended at the end.



(Warning: Do not try this with YouTube, as 43 Flash windows on the same pages will crash your browser. Also, Firefox 2 is known to be slow, while Firefox 3 works fine.)



The JavaScript Code



Creating the IFrames is easy using JavaScript, as can be seen in the example below. I assume that the array of languages to iterate over is retrieved by the function getLanguages(). Then a simple loop uses document.write(...) to dynamically add the IFrames. It is worth mentioning that this method seemed to be the best way of dynamically creating them; using the document.createElement(...) resulted in some complex race condition issues when adding the IFrames and their content at the same time.



var languages = getLanguages();
for (var lang, i = 0; lang = languages[i]; i++) {
  document.write('<hr><a name="' + lang + '"/>' +
                 '<h2>' + lang + '</h2><center>' +
                 '<iframe src="' + url + lang +
                 '" width="' + queryMap['width'] +
                 '" height="' + queryMap['height'] +
                 '"></iframe>' +
                 </center><br/><br/>');
}



The rest of the source code, can be seen in this example. Nothing else is needed to get the overview.



Conclusion


The example in this article shows that a very simple and inexpensive solution can be useful for exploratory testing of web pages; especially when quickly looking over the same pages in multiple languages. The small amount of code required, makes it easy to customize for any project or page, and the fact that the requests are done dynamically, gives a view which is always up to date.



Of course, this type of overview lends itself best to very simple stateless pages, which do not require complex navigation. It would for example be more difficult to get the same list of IFrames for Gmail, or other complex applications. Also, as the IFrames are loaded dynamically, no history is kept, so tracking when a potential bug was introduced in the page under test might prove more tedious.



Furthermore, it should be noted that the overview only simplifies a manual process of looking at the pages. In some situations, this might be very beneficial, and enough for the developer, while in other projects more automated tests might be designed. E.g., it could be difficult to automate tests for aesthetic issues, but easy to spot them manually, while it may prove more beneficial to automate checks for English terms in other languages.



Finally, a word on the issue of translations and language skills. The overview in this example, quickly highlights issues like incorrect line wrapping, missing strings, etc. in all variations of the page. Also, it was easy to spot strings not already translated in some of the languages, like Japanese, and in fact I reported a bug against the Search front page for this. However, for other issues, more language specific skills are necessary to spot and file bugs: E.g. should the Arabic page show Eastern or Western Arabic numerals? And have the Danes picked the English term for "Blogs", while the Norwegians and Swedish prefer a localized term? I don't know.

URL: http://googletesting.blogspot.com/2009/02/fast-exploratory-tests-with-iframes.html

[Gd] OpenSocial App Developer Mentez Expanding into China

| More

OpenSocial API Blog: OpenSocial App Developer Mentez Expanding into China

2008 was a great year for OpenSocial, with dozens of social networks all over the world adopting this standard as their technology of choice for open application platforms. This has greatly expanded the reach of OpenSocial applications to over 600 million users, and social app developers stand to benefit from this global expansion.

At Mentez, our goals are to create useful apps for consumers and to help international brands extend their reach. With OpenSocial, we have learned a lot about building social apps for global audiences, especially for users in Latin America, Europe and Asia.

Late in 2008 many top Chinese social networks, namely xiaonei, 51, MySpace.cn, Tianya, and YiQi all rolled out their support for OpenSocial. We helped sponsor OpenSocial hackathons in December in Beijing and Shanghai, China. Since then we have successfully migrated some of our applications such as 好友方格 (FriendGrid), Popularity, Soccermania to xiaonei and 51.com.

Through this experience we have learned a lot about the market of Chinese social networks. For example, as app developers, it is very important to know who these users are. Xiaonei has a strong presence among university students while 51.com is especially popular with young people who frequent Internet cafes, each with over 30 million monthly active users.

A second critical stumbling block for foreign apps ported to Chinese containers is network latency. Finding local hosting can help here. We are currently on track for procuring servers inside China for large scale deployment as we execute on our goal in 2009 of reaching over 1 million users in China. Visit the OpenSocial wiki for more info on resources (e.g. hosting) about Chinese containers.

Another common issue that app developers face, especially on new social networks that support OpenSocial, is how to monetize. To this end we at Mentez bring a network of 200 developers and a strong team of business developers that let brands and their agencies integrate social channels and networks within their online strategy. Through our deep-rooted connections in advertising industry, we bring advertising dollars, especially from big brand names, to the application ecosystems on social networks, and we are looking forward to working with both social networks and app developers to enhance monetary value for the entire ecosystem.

As OpenSocial continues to take root and gains stronger adoption around the world, we look forward to many exciting opportunities in 2009 and beyond.

Posted by Juan Franco, CEO, Mentez
URL: http://opensocialapis.blogspot.com/2009/02/opensocial-app-developer-mentez.html

[Gd] Android Market update: priced applications for US users

| More

Android Developers Blog: Android Market update: priced applications for US users

Last Friday, we enabled developers to upload priced apps and saw a flurry of activity in the days that followed. Today, it is my pleasure to let you know that we have begun the phased rollout of priced applications to T-Mobile G1 users in the US. Once the service is enabled on their devices, T-Mobile G1 users will be able to see the priced apps immediately without the need to reboot. For more details on this update to Android Market, please see last week's blogpost.

URL: http://android-developers.blogspot.com/2009/02/android-market-update-priced.html

[Gd] Best practices against hacking

| More

Official Google Webmaster Central Blog: Best practices against hacking

These days, the majority of websites are built around applications to provide good services to their users. In particular, are widely used to create, edit and administrate content. Due to the interactive nature of these systems, where the input of users is fundamental, it's important to think about security in order to avoid exploits by malicious third parties and to ensure the best user experience.

Some types of hacking attempts and how to prevent them

There are many different types of attacks hackers can conduct in order to take partial or total control of a website. In general, the most common and dangerous ones are SQL injection and cross-site scripting (XSS).

SQL injection is a technique to inject a piece of malicious code in a web application, exploiting a security vulnerability at the database level to change its behavior. It is a really powerful technique, considering that it can manipulate URLs (query string) or any form (search, login, email registration) to inject malicious code. You can find some examples of SQL injection at the Web Application Security Consortium.

There are definitely some precautions that can be taken to avoid this kind of attack. For example, it's a good practice to add a layer between a form on the front end and the database in the back end. In PHP, the PDO extension is often used to work with parameters (sometimes called placeholders or bind variables) instead of embedding user input in the statement. Another really easy technique is character escaping, where all the dangerous characters that can have a direct effect on the database structure are escaped. For instance, every occurrence of a single quote ['] in a parameter must be replaced by two single quotes [''] to form a valid SQL string literal. These are only two of the most common actions you can take to improve the security of a site and avoid SQL injections. Online you can find many other specific resources that can fit your needs (programming languages, specific web applications ...).

The other technique that we're going to introduce here is cross-site scripting (XSS). XSS is a technique used to inject malicious code in a webpage, exploiting security vulnerabilities of web applications. This kind of attack is possible where the web application is processing data obtained through user input and without any further check or validation before returning it to the final user. You can find some examples of cross-site scripting at the Web Application Security Consortium.

There are many ways of securing a web application against this technique. Some easy actions that can be taken include:
  • Stripping the input that can be inserted in a form (for example, see the strip tags function in PHP);
  • Using data encoding to avoid direct injection of potentially malicious characters (for example, see the htmlspecialchars function in PHP);
  • Creating a layer between data input and the back end to avoid direct injection of code in the application.
Some resources about CMSs security

SQL injection and cross-site scripting are only two of the many techniques used by hackers to attack and exploit innocent sites. As a general security guideline, it's important to always stay updated on security issues and, in particular when using third party software, to make sure you've installed the latest available version. Many web applications are built around big communities, offering constant support and updates.
To give a few examples, four of the biggest communities of Open Source content management systems—Joomla, WordPress, PHP-Nuke, and Drupal—offer useful guidelines on security on their websites and host big community-driven forums where users can escalate issues and ask for support. For instance, in the Hardening WordPress section of its website, WordPress offers comprehensive documentation on how to strengthen the security of its CMS. Joomla offers many resources regarding security, in particular a Security Checklist with a comprehensive list of actions webmasters should take to improve the security of a website based on Joomla. On Drupal's site, you can access information about security issues by going to their Security section. You can also subscribe to their security mailing list to be constantly updated on ongoing issues. PHP-Nuke offers some documentation about Security in chapter 23 of their How to section, dedicated to the system management of this CMS platform. They also have a section called Hacked - Now what? that offers guidelines to solve issues related to hacking.

Some ways to identify the hacking of your site

As mentioned above, there are many different types of attacks hackers can perform on a site, and there are different methods of exploiting an innocent site. When hackers are able to take complete control of a site, they can deface it (changing the homepage), erase all the content (dropping the tables of your database), or insert malware or cookie stealers. They can also exploit a site for spamming, such as by hiding links pointing to spammy resources or creating pages that redirect to malware sites. When these changes in your application are evident (like defacing), you can easily spot the hacking activity; but for other types of exploits, in particular those with spammy intent, it won't be so obvious. Google, through some of its products, offers webmasters some ways of spotting if a site has been hacked or modified by a third party without permission. For example, by using Google Search you can spot typical keywords added by hackers to your website and identify the pages that have been compromised. Just open google.com and run a site: search query on your website, looking for commercial keywords that hackers commonly use for spammy purposes (such as viagra, porn, mp3, gambling, etc.):

[site:example.com viagra]

If you're not already familiar with the site: search operator, it's a way to query Google by restricting your search to a specific site. For example, the search site:googleblog.blogspot.com will only return results from the Official Google Blog. When adding spammy keywords to this type of query, Google will return all the indexed pages of your website that contain those spammy keywords and that are, with high probability, hacked. To check these suspicious pages, just open the cached version proposed by Google and you will be able to spot the hacked behavior, if any. You could then clean up your compromised pages and also check for any anomalies in the configuration files of your server (for example on Apache web servers: .htaccess and httpd.conf).
If your site doesn't show up in Google's search results anymore, it could mean that Google has already spotted bad practices on your site as a result of the hacking and may have temporarily removed it from our index, due to infringement of our webmaster quality guidelines.

In order to constantly keep an eye on the presence of suspicious keywords on your website, you could also use Google Alerts to monitor queries like:

site:example.com viagra OR casino OR porn OR ringtones

You will receive an email alert whenever these keywords are found in the content of your site.

You can also use Google's Webmaster Tools to spot any hacking activity on your site. Webmaster Tools provide statistics about top search queries for your site. This data will help you to monitor if your site is ranking for suspicious unrelated spammy keywords. The 'What Googlebot sees' data is also useful, since you'll see whether Google is detecting any unusual keywords on your site, regardless of whether you're ranking for them or not.

If you have a Webmaster Tools account and Google believes that your site has been hacked, often you will be notified according to the type of exploit on your site:
  • If a malicious third party is using your site for spammy behaviors (such as hiding links or creating spammy pages) and it has been detected by our crawler, often you will be notified in the Message Center with detailed information (a sample of hacked URLs or anchor text of the hidden links);
  • If your site is exploited to place malicious software such as malware, you will see a malware warning on the 'Overview' page of your Webmaster Tools account.
Hacked behavior removed, now what?

Your site has been hacked or is serving malware? First, clean up the malware mess and then do one of the following:
  • If your site was hacked for spammy purpose, please visit our reconsideration request page through Webmaster Tools to request reconsideration of your site;
  • If your site was serving malware to users, please submit a malware review request on the 'Overview' page of Webmaster Tools.
We hope that you'll find these tips helpful. If you'd like to share your own advice or experience, we encourage you to leave a comment to this blog post. Thanks!

Posted by Paolo Petrolini and Iris Mariano, Search Quality Team
URL: http://googlewebmastercentral.blogspot.com/2009/02/best-practices-against-hacking.html

Thursday, February 19, 2009

[Gd] Back to the Future for Data Storage

| More

Google App Engine Blog: Back to the Future for Data Storage

Building a massive, distributed datastore which can service requests at an extremely high throughput is something that we've focused on at Google. We created something called Big Table that underlies the datastore in App Engine. The design for Big Table focused on scalability across a distributed system so it may operate a bit differently than databases you've worked with before, such as not supporting joins. This isn't an accident -- when you build a system that can scale to the size that Big Table can there's no way to do a general purpose join on data sets that size and still have them be performant.

Google isn't alone in offering an non-Relational datastore to enable scaling. For example, Amazon has SimpleDB:

A traditional, clustered relational database requires a sizable upfront capital outlay, is complex to design, and often requires a DBA to maintain and administer. Amazon SimpleDB is dramatically simpler, requiring no schema, automatically indexing your data and providing a simple API for storage and access.

There are also a range of non-relational open source datastores now available such as CouchDB and Hypertable. Those are just two examples, there are many more.

While you might think this is all new, it's actually a bit of a return to the past. You see, there was a time when "RDBMS" wasn't always the answer regardless of what the question was. At the time Codd published his paper, "A Relational Model of Data for Large Shared Data Banks," there were many different approaches to datastores. It was only in the '80s that relational databases won the majority of the mindshare. Having settled on a single metaphor the industry has developed many tools and techniques to make developing on a relational database easier.

Unfortunately that majority mindshare is also a problem because while RDBMS' are useful in many situations, they are not useful in all situations. Their dominance in the mindshare means that useful alternatives aren't used, and huge amounts of time and money can be wasted trying to force non-relational problems into a relational model.

We are in the middle of a renaissance in data storage with the application of many new ideas and techniques; there's huge potential for breaking out of thinking about data storage in just one way. Michael Stonebraker pointed out in his paper, "One Size Fits All": An Idea Whose Time Has Come and Gone, that there are common datastore use cases, such as Data Warehousing and Stream Processing that are not well served by a general purpose RDBMS and that abandoning the general purpose RDBMS can give you a performance increase of one or two orders of magnitude.

It's an exciting time, and the takeaway here isn't to abandon the relational database, which is a very mature technology that works great in its domain, but instead to be willing to look outside the RDBMS box when looking for storage solutions.



Posted by Joe Gregorio, Google App Engine Team
URL: http://googleappengine.blogspot.com/2009/02/back-to-future-for-data-storage.html

[Gd] TotT: Partial Mocks using Forwarding Objects

| More

Google Testing Blog: TotT: Partial Mocks using Forwarding Objects

A Partial Mock is a mock that uses some behavior from a real object and some from a mock object. It is useful when you need bits of both. One way to implement this is often a Forwarding Object (or wrapper) which forwards calls to a delegate.

For example, when writing an Olympic swimming event for ducks, you could create a simple forwarding object to be used by multiple tests:

interface Duck {
  Point getLocation();
  void quack();
  void swimTo(Point p);
}

class ForwardingDuck implements Duck {
  private final Duck d;
  ForwardingDuck(Duck delegate) {
    this.d = delegate;
  }
  public Point getLocation() {
    return d.getLocation();
  }
  public void quack() {
    d.quack();
  }
  public void swimTo(Point p) {
    d.swimTo(p);
  }
}



And then create a test that uses all of the real OlympicDuck class's behavior except quacking.

public void testDuckCrossesPoolAndQuacks() {
  final Duck mock = EasyMock.createStrictMock(Duck.class);
  mock.swimTo(FAR_SIDE);
  mock.quack(); // quack after the race
  EasyMock.replay(mock);
  Duck duck = OlympicDuck.createInstance();
  Duck partialDuck = new ForwardingDuck(duck) {
    @Override public void quack() {
      mock.quack();
    }
    @Override public void swimTo(Point p) {
      mock.swimTo(p);
      super.swimTo(p);
    }
    // no need to @Override “Point getLocation()”
  }

  OlympicSwimmingEvent.createEventForDucks()
                      .withDistance(ONE_LENGTH)
                      .sponsoredBy(QUACKERS_CRACKERS)
                      .addParticipant(partialDuck)
                      .doRace();
  MatcherAssert.assertThat(duck.getLocation(), is(FAR_SIDE));
  EasyMock.verify(mock);



partialDuck is a complex example of a partial mock – it combines real and mock objects in three different ways:

  • quack() calls the mock object. It verifies that the duck doesn't promote the sponsor (by quacking) until after the race. (We skip the real quack() method so that our continuous build doesn't drive us crazy.)

  • getLocation() calls the real object. It allows us to use the OlympicDuck's location logic instead of rewriting/simulating the logic from that implementation.

  • swimTo(point) calls both objects. It allows us to verify the call to the real duck before executing it.


There is some debate about whether you should forward to the real or mock Duck by default. If you use the mock duck by default, any new calls to the mock will break the test, making them brittle. If you use the real duck, some very sensitive calls like submitToDrugTest() might get called by your test if your duck happens to win.

Consider using a Partial Mock in tests when you need to leverage the implementation of the real object, but want to limit, simulate or verify method calls using the power of a mock object.

Remember to download this episode of Testing on the Toilet and post it in your office.

[The pdf may not be available for a short while after this is posted. Check again in a while if it's not. -- Dave]
URL: http://googletesting.blogspot.com/2009/02/tott-partial-mocks-using-forwarding_19.html

[Gd] Constructor Injection vs. Setter Injection

| More

Google Testing Blog: Constructor Injection vs. Setter Injection

by Miško Hevery

There seems to be two camps in dependency-injection: (1) The constructor-injection camp and (2) the setter-injection camp. Historically the setter-injection camp come from spring, whereas constructor-injection camp are from pico-container and GUICE. But lets leave the history behind and explore the differences in the strategies.

Setter-Injection

The basic-ideas is that you have a no argument-constructor which creates the object with "reasonable-defaults" . The user of the object can then call setters on the object to override the collaborators of the object in order to wire the object graph together or to replace the key collaborators with test-doubles.

Constructor-Injection

The basic idea with constructor-injection is that the object has no defaults and instead you have a single constructor where all of the collaborators and values need to be supplied before you can instantiate the object.

At first it may seem that setter injection is preferred since you have no argument constructors which will make it easy for you to create the object in production and test. However, there is one non-obvious benefit with constructor injection, which in my opinion makes it a winner. Constructor-injection enforces the order of initialization and prevents circular dependencies. With setter-injection it is not clear in which order things need to be instantiated and when the wiring is done. In a typical application there may be hundreds of collaborators with at least as many setter calls to wire them together. It is easy to miss a few setter calls when wiring the application together. On the other hand constructor-injection automatically enforces the order and completeness of the instantiated. Furthermore, when the last object is instantiated the wiring phase of your application is completed. This further allows me to set the collaborators as final which makes the code easier to comprehend if you know a given field will not change during the lifetime of the application.

Let's look at an example as to how we would instantiate a CreditCardProcessor.
CreditCardProcessor processor = new CreditCardProcessor();

Great I have instantiated CreditCardProcessor, but is that enough? No, I somehow need to know to call, setOfflineQueue(). This information is not necessarily obvious.
OfflineQueue queue = new OfflineQueue();
CreditCardProcessor processor = new CreditCardProcessor();
processor.setOfflineQueue(queue);

Ok I have instantiated the OfflineQueue and remember to set the queue as a collaborator of the processor, but am I done? No, you need to set the database to both the queue and the processor.
Database db = new Database();
OfflineQueue queue = new OfflineQueue();
queue.setDatabase(db);
CreditCardProcessor processor = new CreditCardProcessor();
processor.setOfflineQueue(queue);
processor.setDatabase(db);

But wait, you are not done you need to set the Username, password and the URL on the database.
Database db = new Database();
db.setUsername("username");
db.setPassword("password");
db.setUrl("jdbc:....");
OfflineQueue queue = new OfflineQueue();
queue.setDatabase(db);
CreditCardProcessor processor = new CreditCardProcessor();
processor.setOfflineQueue(queue);
processor.setDatabase(db);

Ok, am I done now? I think so, but how do I know for sure? I know a framework will take care of it, but what if I am in a language where there is no framework, then what?

Ok, now let's see how much easier this will be in the constructor-injection. Lets instantiate CreditCardPrecossor.
CreditCardProcessor processor = new CreditCardProcessor(?queue?, ?db?);

Notice we are not done yet since CreditCardProcessor needs a queue and a database, so lets make those.
Database db = new Database("username", "password", "jdbc:....");
OfflineQueue queue = new OfflineQueue(db);
CreditCardProcessor processor = new CreditCardProcessor(queue, db);

Ok, every constructor parameter is accounted for, therefore we are done. No framework needed, to tell us that we are done. As an added bonus the code will not even compile if all of the constructor arguments are not satisfied. It is also not possible to instantiate things in the wrong order. You must instantiate Database before the OfflineQueue, since otherwise you could not make the compiler happy. I personally find the constructor-injection much easier to use and the code is much easier to read and understand.

Recently, I was building a Flex application and using the Model-View-Controller. Flex XML markup requires that components must have no argument constructors, therefore I was left with setter-injection as the only way to do dependency injection. After several views I was having hard time to keep all of the pieces wired together properly, I was constantly forgetting to wire things together. This made the debugging hard since the application appeared to be wired together (as there are reasonable defaults for your collaborators) but the collaborators were of wrong instances and therefor the application was not behaving just right. To solve the issue, I was forced to abandon the Flex XML as a way to instantiate the application so that I can start using the constructor-injection and these issues went away.
URL: http://googletesting.blogspot.com/2009/02/constructor-injection-vs-setter.html

[Gd] Faster screen orientation change

| More

Android Developers Blog: Faster screen orientation change

Android is a mobile operating system meant to be run on a wide array of devices, with very different hardware configurations. Some devices, like the T-Mobile G1, can change their hardware configuration at runtime. For instance, when you open the keyboard, the screen change from the portrait orientation to the landscape orientation. To make Android applications development easier, the OS automatically handles configuration changes and restart the current activity with the new configuration. This is the default behavior that lets you declare resources like layouts and drawables based on the orientation, screen size, locale, etc. If you are not familiar with the way Android handles resources, I highly suggest you to read the official documentation on resources.

While this behavior is really powerful, since your application adapts automatically to the device's configuration at runtime, it is sometimes confusing for new Android developers who wonder why their activity is destroyed and recreated. Facing this "issue," some developers choose to handle configuration changes themselves which is, in my opinion, a short-term solution that will complicate their life when other devices come out or when the application becomes more complex. The automatic resource handling is a very efficient and easy way to adapt your application's user interface to various devices and devices configurations. It sometimes comes at a price though.

When your application displays a lot of data, or data that is expensive to fetch, the automatic destruction/creation of the activities can be lead to a painful user experience. Take the example of Photostream, a simple Flickr browsing application I wrote for the release of Android 1.0. After you launch the application and choose a Flickr account, the application downloads a set of 6 photos (on a T-Mobile G1) from the Flickr servers and displays them on screen. To improve the user experience, I also use slightly different layouts and drawables in portrait and landscape, and this is what the result looks like:

Photostream lets Android take care of the configuration change when the screen is rotated. However, can you imagine how painful it would be for the user to see all the images being downloaded again? The obvious solution to this problem is to temporarily cache the images. They could be cached on the SD card (if there's one), in the Application object, in a static field, etc. None of these techniques is adapted to the current situation: why should we bother caching the images when the screen is not rotated? Fortunately for us, Android offers a great API exactly for that purpose.

The Activity class has a special method called onRetainNonConfigurationInstance(). This method can be used to pass an arbitrary object your future self and Android is smart enough to call this method only when needed. In the case of Photostream, I used this method to pass the downloaded images to the future activity on orientation change. The implementation can be summarized like so:

@Override
public Object onRetainNonConfigurationInstance() {
final LoadedPhoto[] list = new LoadedPhoto[numberOfPhotos];
keepPhotos(list);
return list;
}

In the new activity, in onCreate(), all you have to do to get your object back is to call getLastNonConfigurationInstance(). In Photostream, this method is invoked and if the returned value is not null, the grid is loaded with the list of photos from the previous activity:

private void loadPhotos() {
final Object data = getLastNonConfigurationInstance();

// The activity is starting for the first time, load the photos from Flickr
if (data == null) {
mTask = new GetPhotoListTask().execute(mCurrentPage);
} else {
// The activity was destroyed/created automatically, populate the grid
// of photos with the images loaded by the previous activity
final LoadedPhoto[] photos = (LoadedPhoto[]) data;
for (LoadedPhoto photo : photos) {
addPhoto(photo);
}
}
}

Be very careful with the object you pass through onRetainNonConfigurationChange() though. If the object you pass is for some reason tied to the Activity/Context, you will leak all the views and resources of the activity. This means you should never pass a View, a Drawable, an Adapter, etc. Photostream for instance extracts the bitmaps from the drawables and pass the bitmaps only, not the drawables. Finally, remember that onRetainNonConfigurationChange() should be used only to retain data that is expensive to load. Otherwise, keep it simple and let Android do everything.

URL: http://android-developers.blogspot.com/2009/02/faster-screen-orientation-change.html

[Gd] GWT Community Updates

| More

Google Web Toolkit Blog: GWT Community Updates

A couple of months ago, we put the spotlight on the GWT community to highlight some of the great things that have been going on. Since then, there has been a lot of new activity to talk about, so we'd like to share these announcements with you below:

Community announcements

GWT Server Library (GWT-SL) 0.1.5b Released: The GWT-SL library provides developers with a way to easily use GWT with the Spring framework. In this latest release, the library provides support for integration with Gilead (formerly known as hibernate4gwt) and has been updated to work with GWT 1.5.3, and also includes many other new features and improvements.

Gilead 1.2.1 Released: Gilead lets you export persistent entites from the JVM to the outside world. For GWT, it means easy integration with Hibernate. This maintenance releases includes support for Maven support and comet4gwt among other new enhancements. If you use Hibernate, or any other of the new technologies Gilead now supports, check out the library on their project page.

Dependency Injection in GWT: You may already be familiar with GIN (GWT INjection), a dependency injection library that integrates GWT with the Guice framework. However, in case you wanted to try a new flavor of guice (pun intended), you may want to take a look at the recently introduced suco library, which offers its own guice-style dependency injection technique.

emite 0.4.6 Released: emite is an open-source library that implements an XMPP communication protocol and provides hooks for GWT integration. This means you can now make your GWT applications more chatty using this library. If you want to have your users chatting over and about your GWT application, this library might be worth checking out.

More fun stuff

Google I/O: Google's developer conference is coming back again this year at the Moscone Center in San Francisco, California. If you attended last year, you'll know that lots of great talks and impromptu chats with Google engineers await. Like last year, the conference will feature a handful of awesome GWT related talks, not to mention members of the GWT team onsite to answer all your questions. Check out the registration page if you'd like to meet some of us in person.

URL: http://googlewebtoolkit.blogspot.com/2009/02/gwt-community-updates.html

Wednesday, February 18, 2009

[Gd] Dev Update: Bug Fixes

| More

Google Chrome Releases: Dev Update: Bug Fixes

Google Chrome's Dev channel has been updated to 2.0.164.0. This is a bug fix release. Find about the Dev channel and how to subscribe at http://dev.chromium.org/getting-involved/dev-channel.

You might notice 8 Indic languages are now available for the Google Chrome user interface: Bengali, Gujarati, Kannada, Malayalam, Marathi, Oriya*, Tamil, and Telugu. (*Note: Oriya does not work in Windows XP.) This is just the initial integration of support for these languages. The translations are not complete and haven't been finalized. Please don't file bugs for these languages, yet.

Changes
  • Fixed the problems with Facebook's sidebar layout.
  • Fixed last week's 'crash on some Hebrew and Arabic sites' known issue.
  • Fixed several problems with making Google Chrome the default browser on Windows Vista.
  • The complete list of changes is available in the release notes.
Known Issues
Just so you know (and don't have to spend your time filing a bug when you run into these):
  • After scrolling, input method editor (IME) windows appear far from the current text area. (Issue 7651)
  • The Web Inspector (right click > Inspect Element) does not work. (Issue 7800)
  • Issues with commands on pop-up windows: the context menu has most commands disabled, reload and view source do not work. (Issues 7615, 7634, 7804)
  • Saving web pages does not work. Save as.. (Ctrl+S) appears to save to your Downloads folder, but it creates a file in the Application\2.0.164.0 directory. (Issue 7616)
  • Some pop-ups and tabs load pages, but the title remains 'Untitled' and the address bar shows 'about:blank' as the URL. (Issue 7625)
Let us know about any issues you find by filing a bug.
--Mark Larson, Google Chrome Program Manager
URL: http://googlechromereleases.blogspot.com/2009/02/dev-update-bug-fixes_18.html

[Gd] Start the Downloads!

| More

Official Google Data APIs Blog: Start the Downloads!

Posted by Eric Bidelman, Google Documents List APIs Team

Many of you have been waiting patiently for the ability to download your Google Documents using the Documents List Data API. Today, I am very happy to announce the API's top feature request is finally live.

The undocumented (but widely used) RawDocContents url has been replaced by a more versatile Export servlet. Authenticated applications can now download documents in a number of different formats including pdf, doc, ppt, swf, xls, and more.

Exporting is available to all three authentication methods (ClientLogin, AuthSub, OAuth) and will work for developers using the DocList API with a Google Apps hosted domain.

Lastly, we've got samples!
For all the details on exporting your documents, see the documentation. As always, if you have questions, please visit us in the Documents List API forum.

This feature resolves the following issues: 70, 35, 542, 706, 810
URL: http://googledataapis.blogspot.com/2009/02/start-downloads.html

[Gd] State of the Index: my presentation from PubCon Vegas

| More

Official Google Webmaster Central Blog: State of the Index: my presentation from PubCon Vegas

It seems like people enjoyed when I recreated my Virtual Blight talk from the Web 2.0 Summit late last year, so we decided to post another video. This video recreates the "State of the Index" talk that I did at PubCon in Las Vegas late last year as well.

Here's the video of the presentation:



and if you'd like to follow along, here are the slides:



You can also access the presentation directly. Thanks again to Wysz for recording this video and splicing the slides into the video.

Posted by Matt Cutts, Search Quality Team
URL: http://googlewebmastercentral.blogspot.com/2009/02/state-of-index-my-presentation-from.html

[Gd] Now playing: developer-created videos

| More

Google Code Blog: Now playing: developer-created videos

By Christine Tsai, Google Developer Programs

In the last few months, we've posted videos of developers sharing how they built their applications with Google developer tools and technologies. These included developers building their AJAX front-ends with Google Web Toolkit, writing mobile apps for the Android platform, and scaling their web apps with App Engine. We really enjoyed working with these developers to produce these videos. However, we thought it would be great to allow any developer to create their own video talking about their application and help them share their video with other developers on code.google.com.

Today, we're happy to announce that we're now accepting developer-created videos through this video submission page. If you've got a great app built with Google developer products and want to be considered to be featured on code.google.com, all you need to do is:
  1. Check out these instructions and guidelines
  2. Create a short video (or videos) based on the above guidelines and upload it to your YouTube account.
  3. Submit your video details on the submission page.
  4. We'll be reviewing submissions regularly and selecting videos to feature on code.google.com and/or our developer blogs.
You don't need professional equipment or even a studio to produce a good video. Here are 2 examples of videos created by developers. Note that both were shot with hand-held video recording devices and basic video editing software. And as you can see, the "sets" used are just their own workspaces:

Jimmy Moore, developer of Mibbit:



Best Buy's Giftag.com, which was recently featured on this blog:



Ready to tell us your story? Visit the submission page to get started.
URL: http://google-code-updates.blogspot.com/2009/02/now-playing-developer-created-videos.html

Tuesday, February 17, 2009

[Gd] A completely new Gadget Designer

| More

Google Desktop APIs: A completely new Gadget Designer

A new and improved Google Desktop Gadget Designer is out, with a couple of major new features. The Designer editor now includes autocompletion support and function call tips for the Google Desktop Gadget API and the JavaScript language.

You can start autocompletion by typing the "." key or pressing Ctrl+Space. A list appears that displays objects, methods, properties, events, and constants to choose from, along with visual indicators to help you distinguish between them. Non-object related variables and functions are also dynamically recognized as you type them, and you'll see autocompletion suggestions based on your current scope. The following screenshot shows how Designer displays autocompletion suggestions for view object properties and methods that start with "s".



Call tips display function prototypes and short descriptions. They appear when you type an opening brace "(" or press Shift+Space. The following screenshot shows the call tip for the view.setInterval() method.



We sincerely hope that these new features will save you a lot of time while developing gadgets, making it that much more fun to bring your ideas to life. Please download the latest SDK and try out the new Gadget Designer.

Posted by Paneendra Ba, Software Engineer (Google Desktop Team)
URL: http://googledesktopapis.blogspot.com/2009/02/completely-new-gadget-designer.html

[Gd] AdWords API Developer Docs: Now in Chinese and Japanese!

| More

AdWords API Blog: AdWords API Developer Docs: Now in Chinese and Japanese!

It's easy to write code using the AdWords API in the programming language of your choice, thanks to all of our client libraries. But when it comes to written language, you're more constrained--our recent developer documentation has only been maintained in English.

We're happy to announce that this is no longer the case, and our Developer's Guide now features a Chinese and Japanese translation. If you're not automatically redirected to the appropriate language when you visit that page, use the popup menu in the upper right hand corner of the web page to switch to one of the supported languages.

Please note that only the v12 version of the Developer's Guide has been translated. We're working hard to get v13 translated as well, and hope that the v12 documentation proves useful for v13 developers--the majority of the documentation is the same between the two versions. We will be leaving the v12 documentation up on the site for an extended period of time.

We'll be releasing translations for additional languages in the future, so stay tuned for more updates!

--The AdWords API Team
URL: http://adwordsapi.blogspot.com/2009/02/adwords-api-developer-docs-now-in.html

[Gd] AdWords Downtime: February 21, 10am-2pm PST

| More

AdWords API Blog: AdWords Downtime: February 21, 10am-2pm PST

We'll be performing routine system maintenance on Saturday, February 21 from approximately 10:00am to 2:00pm PST. You won't be able to access AdWords or the API during this time frame, but your ads will continue to run as normal.

Cheers,
-Jeffrey Posnick, AdWords API Team
URL: http://adwordsapi.blogspot.com/2009/02/adwords-downtime-february-21-10am-2pm.html