Tuesday, July 28, 2009

Google Apps + OpenID = identity hub for SaaS

We're happy to announce that the Google OpenID Federated Login API has been extended to Google Apps accounts used by businesses, schools, and other organizations. Individuals in these organizations can now sign in to third party websites using their Google Apps account, without sharing their credentials with third parties.

In addition, Google Apps can now become an identity hub for multiple SaaS providers, simplifying identity management for organizations. For example, when integrated with partner solutions such as PingConnect from Ping Identity, the Google Open ID Federated Login API enables a single Google Apps login to help provide secure access to services like Salesforce.com, SuccessFactors, and WebEX — as well as B2B partners, internal applications, and of course consumer web sites. See Ping Identity's post to learn more about their implementation and view the demo.


Another early adopter is Manymoon.com, a SaaS project management vendor that implemented the Google Open ID Federated Login API directly to make it easier for any organization using Google Apps to sign up for and deploy Manymoon to their users:

In the Manymoon Login page, the user chooses to log in using a Google Apps account

The user types in his Google Apps email address. The user never gives away his Google Apps Account password to Manymoon.

The user is redirected to the Google Apps domain to approve sharing information with Manymoon.

Once approved, the user is redirected to Manymoon and is signed in and ready to work with selected accounts.

If you prefer an out-of-the-box solution, we have been working with JanRain, a provider of OpenID solutions that already supports the new API as part of their RPX product.


Supporting the API for Google Apps accounts is exciting news for the OpenID community, as it adds numerous new Identity Provider (IDP) domains and increases the OpenID end user base by millions. In order to allow websites to easily become Relying Parties for these many new IDPs and users, we defined a new discovery protocol. The protocol is designed to allow Relying Parties to identify that a given domain is hosted on Google Apps and to help provide secure access its OpenID Provider End Point. The current proposal is an interim solution, and we are participating in several standardization organizations, such as OASIS and the OpenID Foundation, to generate a next-generation standard. Since the current protocol proposal is not supported by the standard OpenID libraries, we provided an implementation of the Relying Party pieces at the Open Source project, step2.googlecode.com. Google is also offering a set of resources addressing the issues of designing a scalable Federated Login User Interface. You are welcome to visit the User Experience summary for Federated Login Google Sites page, where you can find links to demos, mocks, and usability research data.

You can find more details in our API and Discovery documentation, or join the discussions in the Google Federated Login API Group, where you can ask any question and get answers from other Identity Providers, Relying Parties and Google engineers.

The OpenID Federated Login Service is available for all Google Apps editions. However, it is disabled by default for the Premier and Education editions, and it requires the domain administrator to manually enable it from the Control Panel. We've enabled the service for our employees here at Google, and domain administrators — you can also enable it for your domain.

Thursday, July 23, 2009

Presentations from Google Developer Days in Asia are now live

Videos, presentations, and photos from our Google Developer Days in China and Japan are now live. China's event kicked off our 2009 GDDs in Beijing on June 5 and Japan's GDD was a few days later on June 9.
At each event, attendees had the opportunity to learn about products such as Android, Chrome, OpenSocial, and App Engine and interacted with Google developers during office hours. Developers even got a sneak peak of Google Wave!

Tuesday, July 21, 2009

Above and Beyond the Call of Duty, with Permission

Project Hosting on Google Code is a beehive of activity, with many large and active projects and even more that aspire to that level. Now it will be a little easier for project members to sort out who should be doing what by documenting each member's duties in plain language on the new People sub-tab. Here's an example from the zscreen project:


Duties describe what each member is expected to be doing. Project owners can grant permissions that control what each member is allowed to do. While permissions can be fairly fine-grained, it's usually best to grant broad permissions, and then trust your project members to do their duties or go above and beyond them when the situation calls for it.

In open source software development, anyone can access the source code of the project, and it's important to allow anyone to access issues and project documentation. But in some projects, there is a need to restrict some information to a subset of project members for a limited time. For example, you might want to quickly patch a security hole before publicizing the details of how to exploit it. Project members can now place restrictions on individual issues to control who can view, update, or comment on them.
Here's some of what our new permission system allows project owners to do when they need to:
  • Acknowledge the role of a contributing user without giving them any additional permissions
  • Trust a contributor to update issues or wiki pages without letting them modify source code
  • Restrict access to specific issues to just committers, or to a specific subset of members
  • Restrict comments on specific issues or wiki pages when another feedback channel should be used instead
  • Automatically set access restrictions based on issue labels
Getting started is easy, just click the People sub-tab and start to document what you and your project team are supposed to be doing. If you need to mess with permissions, see our permission system documentation for all the details.

If you'd like to meet some of the people behind Google Code, please drop by the Google booth at OSCON 2009 this week.

Gmail for Mobile HTML5 Series: Autogrowing Textareas

On April 7th, Google launched a new version of Gmail for mobile for iPhone and Android-powered devices. We shared the behind-the-scenes story through this blog and decided to share more of what we've learned in a brief series of follow-up blog posts. This week I'll talk about autogrowing textareas for entering large amounts of text.

When composing a long message in a web app, regardless of whether it's on a desktop or a mobile device, you really want to see as much of your draft as possible and make use of all the available screen space.
One of my biggest gripes are fixed-size textareas that restrict me to only a couple lines of visible text when my screen is actually many times larger than the size of the textarea.

In today's blog post, I'll share a JavaScript solution for textareas that automatically grow (vertically) to the size of the content. They make composing long messages much easier and, for all those iPhone users out there, takes away the need to scroll with the dreaded magnifying glass! We're working on getting this into Gmail for mobile but here it is now as a teaser of things to come.





Measuring the height of the content

The first step is to detect when the content has changed. Some solutions on the net recommend using a timer (see our previous post to find out more about timers) to check if content has changed. However, that approach is not ideal on a mobile device, where both battery life and processor power are limited.

Instead, we will listen for key-up events from the browser. This guarantees that we only measure the textarea when the content has actually changed.

<textarea id="growingTextarea" onkeyup="grow();"></textarea>

The second step is to actually measure the height of the content. There are solutions on the net that recommend keeping a copy of the content in a div and measuring the div to get the height; however, due to memory and processor limitations on a mobile device, those solutions don't scale well when the content gets large (and it's also hard to replicate textarea line wrapping behavior exactly in a div).

Therefore we will make use of the scrollHeight and clientHeight properties. For our purposes, scrollHeight is the height of all the content while clientHeight is the height of the content that's visible in the textarea (for more precise definitions, see scrollHeight and clientHeight)
function grow() {
var textarea = document.getElementById('growingTextarea');
var newHeight = textarea.scrollHeight;
var currentHeight = textarea.clientHeight;

}
One limitation of using scrollHeight and clientHeight is that we aren't able to shrink the textarea when content is deleted. When all the content of a textarea is visible, the scrollHeight is equal to the clientHeight. Therefore we aren't able to detect that our textarea is actually larger than the minimum size required to fit all the content (please do leave a comment if you think of a solution that doesn't require re-rendering the page).

Growing the textarea

To grow the text area, we modify the height CSS property:
if (newHeight > currentHeight) {
textarea.style.height = newHeight + 5 * TEXTAREA_LINE_HEIGHT + 'px';
}
Notice how we only change the height if newHeight > currentHeight. Depending on the browser, changing the height (even if it's to the same value) will cause the page to re-render. On a mobile device, we want to try our best to minimize the number of operations.

Also, we grow the textarea by five lines every time we grow. From a UI perspective, this reduces the amount of jitter when composing a message but, from a performance perspective, this reduces the number of times we need to re-render the page.

(Quick note for developers implementing this for a browser with scrollbars: you might want to modify the CSS overflow property to preventing the scrollbar from appearing and disappearing as you grow your textarea)

The complete solution

Growing textareas are easy to implement and they make composing long messages infinitely more usable. So go out there add it to all your web apps!
<script>
// Value of the line-height CSS property for the textarea.
var TEXTAREA_LINE_HEIGHT = 13;

function grow() {
var textarea = document.getElementById('growingTextarea');
var newHeight = textarea.scrollHeight;
var currentHeight = textarea.clientHeight;

if (newHeight > currentHeight) {
textarea.style.height = newHeight + 5 * TEXTAREA_LINE_HEIGHT + 'px';
}
}
</script>
<textarea id="growingTextarea"
onkeyup="grow();">
</textarea>

Previous posts from Gmail for Mobile HTML5 Series
Using timers effectively

Monday, July 20, 2009

Apollo 11 mission's 40th Anniversary: One large step for open source code...



On this day 40 years ago, Neil Armstrong and Buzz Aldrin became the first humans to walk on the Moon. This was quite an achievement for mankind and a key milestone in world history.

To commemorate this event the Command Module code (Comanche054) and Lunar Module code (Luminary099) have been transcribed from scanned images to run on yaAGC (an open source AGC emulator) by the Virtual AGC and AGS project.

For more information on this project, I recommend looking at the website and the open source project.

Here are a few links to the source code:
As the project evolves, look for syntax highlighting done with a special extension for google-code-prettify.

Image - NASA/courtesy of nasaimages.org

Friday, July 17, 2009

Breaking the Persian language barrier with the AJAX APIs

There are several barriers to the free flow of information, but the language barrier is one that we can reduce with a little help from the developer community.

To encourage the sharing of ideas and information across the web, early last year we announced the AJAX Language API. Then, a few weeks ago we announced the Virtual Key board API.


In the span of a few months, developers have already started to integrate these APIs in very innovative ways: Vast Rank, Mibbit.com, and Jeevansathi.

Today, I'm happy to announce that we are supporting Persian in the Language API. This comes on the heels of our announcement that we support Persian on Google Translate.

With this launch, the documentation for the AJAX Language API has been translated into Persian (the first right-to-left language supported on Google Code) and both the AJAX Language API and Virtual Keyboard API now support Persian.

I encourage you to use this API and to make this world a smaller place. Thanks!

API زبان AJAX فارسی را پشتیبانی میکند.

موانع متعددی بر سر راه جریان آزاد اطلاعات وجود دارد. اما ما می توانیم موانع ترجمه را با کمی کمک از طرف برنامه نویسان کاهش دهیم.

برای تشویق به اشتراک گذاشتن ایده ها و اطلاعات در سراسر وب ، در اوایل سال گذشته ما AJAX زبان API و سپس ، چند هفته پیش صفحه کلید مجازی API را راه اندازی کردیم.

پس از تنها چند ماه برنامه نویسان به طرق بسيار خلاقانه ای شروع به استفاده از این API ها کرده اند:
Vast Rank
Mibbit.com
Jeevansathi

امروز، من با خوشحالی اعلام می کنم که ما شروع به پشتیبانی از فارسی در API زبان کرده ایم. این اقدام پس از اعلان پشتیبانی ما از ترجمه فارسی در گوگل می آید .

با این پرتاب ،اسناد AJAX زبان API به فارسی ترجمه شده است (که اولین اقدام به پشتیبانی از یک زبان سمت راست به چپ در کد گوگل می باشد) و هر دوی AJAX زبان API و API صفحه مجازی کلید در حال حاضر فارسی را پشتیبانی می کنند.

من شما را به استفاده از این API تشویق می کنم با این امید که این جهان را به یک محل در دسترس بدل کنیم. با تشکر!


Tuesday, July 14, 2009

Sidebar Gadgets: Coming soon to a Calendar near you

We've always believed users should have open and unencumbered access to their data, and Google Calendar is no exception. Whether through iCalendar, CalDAV, or the Calendar Data API, there are a multitude of options to access Calendar from other applications. However, developers have been asking for a way to extend the Google Calendar interface itself, and we've been listening.

Today, as part of Google Calendar Labs, we're opening up Google Calendar as a gadget container.

Gadget developers will already be familiar with most of this environment, complete with features such as OpenSocial for social networking and OAuth for working with third-party services. However, for the first time we're also providing an API to control and interact with the Calendar user interface. This means that even though your gadgets are running inside a sandbox, they are first-class elements of the Calendar user experience. In fact, many of the experiments we've made available through Calendar Labs were written using the publicly available gadget API.

We hope you'll share our excitement in opening up the Google Calendar interface. To get you started, take a look at the Sidebar Gadget documentation and sample code. If you have any questions or ideas for improvement, feel free to visit the Calendar API help group and let us know!

Wednesday, July 08, 2009

My Location on Google Maps

We've blogged before about how much we like location-based services and at Google we want all developers to be able to build these cool applications. That's why we're so excited about the W3C Geolocation API, a browser API that provides a really easy way for web applications to get the user's location.

Today we're announcing the launch of My Location on Google Maps, the first major Google web application to make use of the Geolocation API. My Location on Google Maps offers the same functionality you're probably familiar with from Google Maps for Mobile - simply click a button and your location is shown on the map with a blue dot.

Until recently, providing this kind of functionality usually meant writing a native application, which is hard work if you want to deploy on lots of different platforms. What's great about the Geolocation API is that it can be used by any web application, in any web browser that supports it, in a totally cross-platform way. Both Google Chrome and Firefox 3.5 already provide geolocation in the browser, Opera 10 will soon add support and we're looking forward to other major browsers adding support soon. As an interim solution, Gears also provides an equivalent Geolocation API and can be installed on other browsers such as Internet Explorer.

We look forward to seeing lots more cool web applications make use of the Geolocation API!

Tuesday, July 07, 2009

Native Client Security Contest: The results are in!

A few months ago, we challenged you to discover exploits in the Native Client system and more than 600 of you decided to take us up on our invitation. We're very pleased with the results: participants found bugs that enabled some really clever exploits, but nothing that pointed to a fundamental flaw in the design of Native Client. Our judges reviewed all entries very carefully and have selected five teams as the winners of the Native Client Security Contest.

The big winner of the contest was the team "Beached As", consisting of IBM researcher Mark Dowd and independent researcher Ben Hawkes. "Beached As" reported 12 valid issues, including vulnerabilities in the validator and multiple type-confusion attacks. The team "CJETM" (Chris Rohlf, Jason Carpenter, Eric Monti — all security professionals with Matasano Security) came in second by reporting three issues with a common theme of memory related defects, including an uninitialized vtable entry, an exception condition during new(), and a double delete bug. Gabriel Campana from Sogeti ESEC R&D Labs was selected as the third place, while for the fourth and fifth place we had a tie between independent researcher Daiki Fukumori and Rensselaer Polytechnic Institute student Alex Radocea. You can find a listing of all the issues the teams submitted at the Native Client Security Contest site.


The winners of the Native Client Security Contest, Team "Beached As"
Mark Dowd (left) and Ben Hawkes (right)

Winning teams were attracted to the contest by the potential of the Native Client technology. Mark Dowd, member of the winning team "Beached As", commented, "When I saw the press release announcing the product, I was intrigued by some of the ideas mentioned in the article. After reviewing the architecture a little, I thought the project adopted a novel approach to solving the problem of running native code securely, and was keen to take a closer look." Curiosity about what the technology could achieve also motivated the CJETM team, according to Chris Rohlf.

The real-world relevance of Native Client made this contest more interesting and challenging for participants. Contestant Alex Radocea stated, "Unlike most security challenges out there, the set of problems were not crafted. The tasks at hand were real and complex, as the real world is. I have no doubt that many unknown people eyed the code or attacked the applications and, frustratingly, found absolutely nothing wrong." Mark Dowd agreed: "Our goal was to create a convincing lead, to try and take the victory, and I think we did that. Having said that, the field was not soft. There were some tough contestants who were able to uncover a variety of interesting vulnerabilities."

We would like to thank all the contestants, the jury chair Ed Felten and all the security experts that judged the contest for helping us improve the security of our system. This contest helped us discover implementation errors in Native Client and some areas of our codebase we need to spend more time reviewing. More importantly, that no major architectural flaws were found provides evidence that Native Client can be made safe enough for widespread use. Toward that end, we're implementing additional security measures, such as an outer sandbox, but you can help by continuing to file bugs in Native Client. Community support and scrutiny has helped and will continue to help make Native Client more useful and more secure.

Monday, July 06, 2009

Google I/O Scavenger Hunt Winners

The astute conference attendee would have noticed hidden QR codes around the conference, as well as the scannable QR codes on everyone's badge. We wanted to find a fun way for people to bond with their new phones, as well as network with other attendees, so we set about creating a scavenger hunt game using Google App Engine & Friend Connect. The app handled game logistics (a leaderboard, URL endpoints), and we printed up a bunch of custom QR code stickers that pointed to game URLs.

App Engine made writing the scavenger hunt app much easier than it otherwise would have been. The initial version of the app took one developer less than a day to turn out, and we continued to add functionality and tweak it as I/O approached and we tested it in real-world situations. The versioning deployment made it very easy to test and push out new versions without disrupting existing users.

The overall structure of the app was very straightforward: every QR-code had a unique URL, which was embedded into the generated QR code. A URL was associated with a number of points to be awarded and a destination URL (such as the user's profile information, in the case of a user's badge QR code). Users were signed in using Friend Connect, which allowed us to avoid concerns of authenticating users and managing sessions.

When a user visited a URL for the first time, we recorded that fact so they couldn't try and get extra points with repeat visits, then sent them to the destination URL. We also kept a running count of the user's score against the User entity, so as to not have to count up their points on every request. Generating the leaderboard was a simple matter of querying for the users with the most points and displaying them.

QR codes were generated using the Chart API, which simply takes a string of text and a few other parameters, and returns a fully formed QR code.

The three resourceful and persistent folks below beat out the competition to rise to the top of the scavenger hunt ranks - going to great lengths, including swag bribery, to gain points. A hearty (if belated) congratulations to the winners of the Google I/O mobile scavenger hunt!



1st Place - Abraham Williams
2nd Place - Waylon Flinn
3rd Place - Pete Richards


We hope everyone that participated learned how to use their Android phones a little better, met people they otherwise wouldn't have, and had some fun :)











Thursday, July 02, 2009

Gmail for Mobile HTML5 Series: Using Timers Effectively

On April 7th, Google launched a new version of Gmail for mobile for iPhone and Android-powered devices. We shared the behind-the-scenes story through this blog and decided to share more of what we've learned in a brief series of follow-up blog posts. This week, I'll talk about two kinds of timers Javascript provides and how you can put them to good use in your own web applications.

Javascript Timer API

Timers provide a way to schedule a function to run at some later point in time. The two functions used to create timers are:
  • var id = setTimeout(fn, delay) creates a timer which calls the specified function once after the given delay.
  • var id = setInterval(fn, delay) is similar, but the function is called continually until the timer is canceled.
Each type of timer has a corresponding clear method (e.g., clearTimeout(id)) that stops a timer while it is running.

There are many great resources online already that document the nitty-gritty details of this API. That's not our focus here. Instead, I want to talk about specific ways in which you can put these timers to work for you in your web application.

Let's Do the Time Warp Again

It's important to keep in mind that just because you ask for a timer with a certain delay doesn't mean it will fire precisely that many milliseconds later. On current browsers, all Javascript code executes within a single thread. This means all your timers have to contend for execution time not only with each other, but also with all the other Javascript code in your application. If another block of code is in the middle of executing when a timer should fire, the timer will be delayed until that block of code is done. (Help is on the way: HTML5's Web Workers will allow web applications to spawn workers that run scripts in parallel.)

Let's look at a concrete example of what this means in practice. I added a timer to Gmail for mobile that is supposed to fire every 200 ms. Each time it fires, it records the time between consecutive timer ticks. Here are the results after 100 ticks:


The dashed blue line represents the requested timer interval, 200 ms. Notice that the median was almost 50% higher than requested, at 276 ms; the time between ticks varied from 98 ms to almost 4 seconds, with an average delay of 493 ms.

This highlights the fact that the interval at which your timer actually fires may differ greatly from the requested delay. In fact, the time between ticks is typically highly variable. It will fluctuate based on what else is happening in your application and on the device. Don't rely on your timer being precise!

Buy One Timer, Get One Free?

When I first started working on the new version of Gmail for mobile, the application used only a couple of timers. As we continued adding more and more features, the number of timers grew. We were curious about the performance implications: would 10 concurrent timers make the app feel slow? How about 100? How would the performance of many low-frequency timers compare to a single high-frequency timer?

To answer these questions, we conducted a few experiments. We injected some extra code into a development build of Gmail that created a lot of different timers, each of which just performed some simple calculations. Then we fired up the app on an iPhone 3G and Android G1 (both running the latest version of their respective firmware) and observed the performance. Note that although we could have just created a separate test page for this, we chose to inject the code right into our app so we could see how fast it would be to read and process mail with all those timers running.

Here's what we learned. With low-frequency timers — timers with a delay of one second or more — we could create many timers without significantly degrading performance on either device. Even with 100 timers scheduled, our app was not noticeably less responsive. With high-frequency timers, however, the story was exactly the opposite. A few timers firing every 100-200 ms was sufficient to make our UI feel sluggish.

This led us to take a mixed approach with the timers we use in our application. For timers that have a reasonably long delay, we just freely create new timers wherever they are needed. However, for timers that need to execute many times each second, we consolidate all of the work into a single global high-frequency timer.

One High-Frequency Timer to Rule Them All

A global high-frequency timer strikes a balance between needing several different functions to execute frequently and application performance. The idea is simple: create a single timer in a central class that calls as many functions as required. Ours looks something like this:


var highFrequencyTimerId_ = window.setInterval(globalTimerCallback, 100);

globalTimerCallback = function() {
navigationManager.checkHash();
spinnerManager.spin();
detectWakeFromSleep_();
};

Why did we choose to hardcode the various function calls in globalTimerCallback() rather than implementing a more generic callback registration interface? Keep in mind that this code is going to execute many times every second. Looping over an array of registered callbacks might be slightly "cleaner" code, but it's critical that this function execute as quickly as possible. Hardcoding the function calls also makes it really easy to keep track of all the work that is being done within the timer.

To Die, To Sleep; To Sleep, Perchance to Tick

One neat application of a high-frequency timer is to detect when the device has been woken from sleep. When your application is put to sleep — either because the device is put into sleep mode or because the user has navigated away from the browser to another application — time, as perceived by your app, pauses. No timers fire until the user navigates back to your app and it wakes up. By keeping a close eye on the actual time that elapses between high-frequency timer ticks, you can detect when the app wakes from sleep.

First, create a high-frequency timer, as described above. In your timer, call a function that keeps track of the time between ticks:


// The time, in ms, that must be "missed" before we
// assume the app was put to sleep.
var THRESHOLD = 10000;

var lastTick_;
detectWakeFromSleep_ = function() {
var now = new Date().getTime();
var delta = now - this.lastTick_;
if (delta > THRESHOLD) {
// The app probably just woke up after being asleep.
fetchUpdatedData();
}
lastTick_ = now;
};

Now your users will always have the latest data available when they return to your app without having to manually perform a refresh!

I hope this helps you make the most of timers in your web application. Stay tuned for the next post, where we'll discuss some cool tricks to spice up the text areas on your forms.

Wednesday, July 01, 2009

Enabling Public Service: All for Good and Google App Engine



You may have seen the post on the Google Blog about All for Good, the new site that makes it easy to find and share volunteer activities within the United States. The site was built collaboratively by Google and several partners. We're especially proud that it was built using 100% open source Python code. All for Good's first release includes both gadgets and a free API, making it even easier for casual developers to build applications and embed All for Good listings in their own apps and sites.

If you're interested in seeing your software talents dedicated to community service, check out the API documentation, our Getting Started Guide and the complete source code for the core engine. We're especially looking forward to see what applications the developer community will create for mobile platforms and for Facebook. Happy Hacking!

by Guido van Rossum, Software Engineering Team

Follow us on @GoogleCode

Google Code now has a home on Twitter - introducing @GoogleCode! Expect our tweets to be a nice mix of developer product announcements, Code Blog coverage, coding tips and tricks, interesting tech news and commentary, developer events, and more.

If you have any suggestions for what you want to see, feel free to send an @reply. We can't guarantee to respond to everyone, but we'd like to hear your feedback and suggestions for @GoogleCode or our developer products.

Christine Tsai