Friday, January 21, 2011

[Gd] Processing Ordered Broadcasts

| More

Android Developers Blog: Processing Ordered Broadcasts

[This post is by Bruno Albuquerque, an engineer who works in Google’s office in Belo Horizonte, Brazil. —Tim Bray]

One of the things that I find most interesting and powerful about Android is the concept of broadcasts and their use through the BroadcastReceiver class (from now on, we will call implementations of this class “receivers”). As this document is about a very specific usage scenario for broadcasts, I will not go into detail about how they work in general, so I recommend reading the documentation about them in the Android developer site. For the purpose of this document, it is enough to know that broadcasts are generated whenever something interesting happens in the system (connectivity changes, for example) and you can register to be notified whenever one (or more) of those broadcasts are generated.

While developing Right Number, I noticed that some developers who create receivers for ordered broadcasts do not seem to be fully aware of what is the correct way to do it. This suggests that the documentation could be improved; in any case, things often still work(although it is mostly by chance than anything else).

Non-ordered vs. Ordered Broadcasts

In non-ordered mode, broadcasts are sent to all interested receivers “at the same time”. This basically means that one receiver can not interfere in any way with what other receivers will do neither can it prevent other receivers from being executed. One example of such broadcast is the ACTION_BATTERY_LOW one.

In ordered mode, broadcasts are sent to each receiver in order (controlled by the android:priority attribute for the intent-filter element in the manifest file that is related to your receiver) and one receiver is able to abort the broadcast so that receivers with a lower priority would not receive it (thus never execute). An example of this type of broadcast (and one that will be discussing in this document) is the ACTION_NEW_OUTGOING_CALL one.

Ordered Broadcast Usage

As mentioned earlier in this document, the ACTION_NEW_OUTGOING_CALL broadcast is an ordered one. This broadcast is sent whenever the user tries to initiate a phone call. There are several reasons that one would want to be notified about this, but we will focus on only 2:

  • To be able to reject an outgoing call;

  • To be able to rewrite the number before it is dialed.

In the first case, an app may want to control what numbers can be dialed or what time of the day numbers can be dialed. Right Number does what is described in the second case so it can be sure that a number is always dialed correctly no matter where in the world you are.

A naive BroadcastReceiver implementation would be something like this (note that you should associate this receiver with the ACTION_NEW_OUTGOING_CALL broadcast in the manifest file for your application):

public class CallReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// Original phone number is in the EXTRA_PHONE_NUMBER Intent extra.
String phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);

if (shouldCancel(phoneNumber)) {
// Cancel our call.
setResultData(null);
} else {
// Use rewritten number as the result data.
setResultData(reformatNumber(phoneNumber));
}
}

The receiver either cancels the broadcast (and the call) or reformats the number to be dialed. If this is the only receiver that is active for the ACTION_NEW_OUTGOING_CALL broadcast, this will work exactly as expected. The problem arrises when you have, for example, a receiver that runs before the one above (has a higher priority) and that also changes the number as instead of looking at previous results of other receivers, we are just using the original (unmodified) number!

Doing It Right

With the above in mind, here is how the code should have been written in the first place:

public class CallReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// Try to read the phone number from previous receivers.
String phoneNumber = getResultData();

if (phoneNumber == null) {
// We could not find any previous data. Use the original phone number in this case.
phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
}

if (shouldCancel(phoneNumber)) {
// Cancel our call.
setResultData(null);
} else {
// Use rewritten number as the result data.
setResultData(reformatNumber(phoneNumber));
}
}

We first check if we have any previous result data (which would be generated by a receiver with a higher priority) and only if we can not find it we use the phone number in the EXTRA_PHONE_NUMBER intent extra.

How Big Is The Problem?

We have actually observed phones with a priority 0 receiver for the NEW_OUTGOING_CALL intent installed out of the box (this will be the last one that is called after all others) that completely ignores previous result data which means that, in effect, they disable any useful processing of ACTION_NEW_OUTGOING_CALL (other than canceling the call, which would still work). The only workaround for this is to also run your receiver at priority 0, which works due to particularities of running 2 receivers at the same priority but, by doing that, you break one of the few explicit rules for processing outgoing calls:

“For consistency, any receiver whose purpose is to prohibit phone calls should have a priority of 0, to ensure it will see the final phone number to be dialed. Any receiver whose purpose is to rewrite phone numbers to be called should have a positive priority. Negative priorities are reserved for the system for this broadcast; using them may cause problems.”

Conclusion

There are programs out there that do not play well with others. Urge any developers of such programs to read this post and fix their code. This will make Android better for both developers and users.

Notes About Priorities

  • For the NEW_OUTGOING_CALL intent, priority 0 should only be used by receivers that want to reject calls. This is so it can see changes from other receivers before deciding to reject the call or not.

  • Receivers that have the same priority will also be executed in order, but the order in this case is undefined.

  • Use non-negative priorities only. Negative ones are valid but will result in weird behavior most of the time.

URL: http://android-developers.blogspot.com/2011/01/processing-ordered-broadcasts.html

[Gd] A Property By Any Other Name, Part 2

| More

Closure Tools Blog: A Property By Any Other Name, Part 2

This is the second in a series of blog posts on how Closure Compiler decides what properties to rename with the --compilation_level=ADVANCED_OPTIMIZATIONS flag. Part 1 talks about the current algorithm. This blog post will focus on property renaming policies that we tried that didn't work so well.

In the beginning, we tried to use coding conventions to decide when to rename things. Uppercase property names (foo.MyMethod) were renamed, and lowercase property names were not renamed. This didn't work well. One man's internal code is another man's external library. Sometimes you really didn't want uppercase property names to be renamed. Changing your code to use this convention meant breaking your API.

Later, we tried to move towards "smarter" algorithms, ones that did not require the programmer to be aware of renaming policies. These were called the "heuristic" property renaming policies. These algorithms looked at the entire input to the compiler, and tried to find all writes and reads to a specific property. If it saw at least one write to the property, and was reasonably sure that all the reads of that property came from those writes, then it renamed them all.

In small apps, heuristic renaming policies worked well. They were not very powerful, but they were easy to migrate to. Even when you didn't declare all the properties on external objects in the externs file, you'd usually still be ok. There would be no property writes to that property name, so the compiler wouldn't try to rename it.

But for medium to large apps, these advantages were a curse. Consider the following code:

/** @param {Object} json Some external JSON.
function f(json) {
return json.estate;
}
window['__receive_json'] = f;

// ...

// in some other code base
Foo.prototype.estate = 3;
f(new Foo());


If these were the only two appearances of the property estate in your binary, the compiler would rename it. The compiler can't tell that you're calling f from external code, and that you expect estate to be preserved.

You could have this piece of code that worked for years and years. Then, somebody who you never met could add Foo.prototype.estate in a different part of the codebase. It would break your code for no obvious reason, and the breaking change would be difficult to track down. When we have common JavaScript libraries, this becomes orders of magnitude more problematic. Adding Foo.prototype.estate could break any of the 25 products that depend on your library in subtle and difficult-to-debug ways.

Even if you did find the problem, how would you work around it? If this is shared code, then changing json.estate to something like json['estate'] might break other projects that depend on it, because their binaries do expect estate to get renamed.

Because of these problems, most projects that use Closure Compiler do not use heuristic renaming algorithms. But heuristic renaming wasn't a total failure. We learned some useful lessons:

  • If the compiler looks at your whole program to determine whether a property should be renamed, then that means a change in one part of the program can change property renaming in an unrelated part of the program.
  • If your code is shared across projects, then you probably want the property to be renamed in all projects or none of them.
  • When renaming properties, it's better to be transparent and 90% accurate than to be cryptic and 99% accurate.


Could we use these lessons to develop a better renaming algorithm? We'll talk about this more in Part 3.

Posted by Nick Santos, Software Engineer
URL: http://closuretools.blogspot.com/2011/01/property-by-any-other-name-part-2.html

[Gd] Google Innovation and The Pretotyping Manifesto

| More

Google Testing Blog: Google Innovation and The Pretotyping Manifesto

I'll be speaking very soon about innovation and The Pretotyping Manifesto (note: not prototyping). It's a concept that works well for any type of engineering, testing, or idea. Here's a brief preview...

The talk starts off by discussing the odds against innovators and how the deck is stacked against you from the start. Most engineers begin with trying to come up with THE killer idea. But you quickly realize that ideas are cheap. We all believe that our own ideas are good. As a matter of fact, most of us LOVE our own ideas to the point where it clouds our judgement. In parallel, there is a strong desire to jump in and build something after a great idea has been identified. Sometimes swarms of well intentioned people join in and "help." Quickly innovators can find themselves in the weeds or feeling disconnected from their original dream. So, what can be done? The idea is to use pretotyping and to focus on techniques that allow you to: Build the right it vs. Build it right.

Last time I did this talk, it was called: "the best keynote of any tech conference ever!"

I'm looking forward to seeing some of you the week of March7th when I'll be in London. In addition to dropping into the Google office, I'll be speaking at QCon London. If you want to attend (at a cheaper rate than normal) here are the details:

  • London event March 7-11, 2011.
  • My personal "promotion code" will save you £100 if they enter this code during registration.
  • Promotion code is: COPE100
Hope to see you in London,
Patrick Copeland
Senior Engineering Director, Google
URL: http://googletesting.blogspot.com/2011/01/google-innovation-and-pretotyping.html

Thursday, January 20, 2011

[Gd] [Libraries][Update] jQueryUI 1.8.9

| More

Google AJAX API Alerts: [Libraries][Update] jQueryUI 1.8.9

jQueryUI has been updated to 1.8.9
URL: http://ajax-api-alerts.blogspot.com/2011/01/librariesupdate-jqueryui-189.html

[Gd] Marketing Test Kitchen - customer stories

| More

Google Apps Developer Blog: Marketing Test Kitchen - customer stories

Despite a delay due to the holidays, we are excited to announce the stand out of the customer story marketing test kitchen, submitted by Smartsheet about their collaboration with Timeraiser. Smartsheet will be featured in the rotation of the featured & notables section on the Marketplace front page and a story in the Google Enterprise Blog.

Smartsheet tells a joint story of committing to the cloud and using strong examples and visuals to fully depict their message. Not only did they tell the story of Timeraiser’s use of Smartsheet, they vividly depicted an organization that has committed to cloud computing and has benefited greatly from it.

Read Smartsheet’s blog post and watch the video to see Timeraiser’s web strategy.



Other great stories were submitted by Mavenlink, Aprigo, Outright, and Manymoon.
  • Mavenlink used a unique question and answer format to tell the story of Mending Limbs and how they use multiple cloud apps
  • Aprigo shot a video and wrote a strong story to highlight the story of Google Apps user Bay Cove
  • Outright pushed out multiple stories to tell the story of why everyone loves Google Apps and their accounting app.
  • Manymoon used visuals and a straightforward story telling method to tell the story of Collaborative Project Consulting
Write your own case study and get it featured on the Google Apps Marketplace frontpage through the Marketplace Success Blog.

Stay tuned for more from the Marketing Test Kitchen by following the blog and submit your ideas to marketing-test-kitchen@google.com

Posted by Harrison Shih, Google Apps Marketplace Team

Want to weigh in on this topic? Discuss on Buzz

URL: http://googleappsdeveloper.blogspot.com/2011/01/despite-delay-due-to-holidays-we-are.html

Wednesday, January 19, 2011

[Gd] Beta Channel Update

| More

Google Chrome Releases: Beta Channel Update

The Beta channel has been updated to 9.0.597.67 for Windows, Mac, Linux, and Chrome Frame.

Due to stability issues Flash Player sandboxing has been put behind a flag for 9.0.  Accelerated composting and WebGL will remain on.  The remaining set of changes for this release constituted bug and stability fixes.

If you find new issues, please let us know by filing a bug at 
http://code.google.com/p/chromium/issues/entry

Anthony Laforge
Google Chrome
URL: http://googlechromereleases.blogspot.com/2011/01/beta-channel-update_18.html

Tuesday, January 18, 2011

[Gd] Make quick fixes quicker on Google Project Hosting

| More

Google Code Blog: Make quick fixes quicker on Google Project Hosting

Have you ever noticed a bug or typo in your code but not been in a position to fix it? Perhaps you were browsing the code online from your Cr-48, or perhaps you just didn’t have Subversion or Mercurial handy. Today the Google Project Hosting team is announcing a new feature for you: the ability to edit your source code files directly in the browser, in our online editor powered by CodeMirror. Just look for the “edit file” link on files in the online source browser:As you edit, you can preview the diff of your changes so you know exactly what you are committing:

And if you don’t have commit privileges to the project? No problem. Instead of committing your changes, you can file your changes as a patch in the project’s issue tracker.

By lowering the barrier to entry for everyone — project members and users alike — we hope to make it easier for projects to grow and improve. Enjoy!

By Jacob Lee, Google Project Hosting Team
URL: http://googlecode.blogspot.com/2011/01/make-quick-fixes-quicker-on-google.html

[Gd] A Property By Any Other Name, Part 1

| More

Closure Tools Blog: A Property By Any Other Name, Part 1

When you use Closure Compiler's --compilation_level=ADVANCED_OPTIMIZATIONS flag, the compiler will try to rename properties on your objects. For example, it may rename x.longPropertyName to x.a.

Because property renaming is a complex topic, we're going to split this discussion up into three blog posts. Part 1 is about the property renaming that you get with ADVANCED_OPTIMIZATIONS. Part 2 will be about other property renaming algorithms we've tried that didn't work so well. Part 3 will be about property renaming algorithms that we're currently experimenting on and are available from the Java API.

If you're using Closure Compiler's Java API, you have more fine-grained control over what renaming the compiler does. The API treats variable renaming (foo.bar -> a.bar) and property renaming (foo.bar -> foo.a) as completely independent optimizations. You can choose a variable renaming policy and a property renaming policy. The best property renaming policy, "All Unquoted," is what you get when you use ADVANCED_OPTIMIZATIONS. Most large Google projects use it. It significantly changes how we write JavaScript.

In the general case, a compiler can't rename properties at compile-time. You simply don't have enough information to try. There will always be objects that come from external sources that the compiler can't see (like JSON responses from the server), and property names that are undecidable. (Consider the expression foo[undecidableFunction()] = function(){};.) So property renaming can never be perfect. There will always be rules and gotchas.

Before we talk about the best property renamer, "All Unquoted," we have to define what we mean by "best." Usually, we use three criteria.

  1. Power: How much smaller does it make your code?

  2. Failure Cases: If it renames properties incorrectly, how easy is it to figure out what went wrong? How easy is it to fix the issue? If you make a change, how confident can you be that it won't break renaming?

  3. Migration: How easy is it to update a legacy codebase so that it can take advantage of property renaming?


"All Unquoted" renaming was designed to optimize for #2: making the failure cases easy to debug and correct. By design, the algorithm is transparent and simple.

  1. If a property is in the externs file, don't rename it.

  2. If the property appears in quotes, don't rename it.

  3. Otherwise, rename it.


For example, if you write the code:

var obj = {
alice: true,
'bob': true
};
obj.claire = true;
obj.document = true;
window['obj'] = obj;


then you will get something that looks like this:

var a = {
a: true, // alice was not in quotes or in the externs file
bob: true // bob was in quotes
};
a.b = true; // claire was not in quotes or in the externs file
a.document = true; // document was in the externs file
window.obj = a; // obj was in quotes


If you use the --debug flag, the same properties still get renamed, but now it will be much easier to see what the original names were:

var $obj$$ = {
$alice$: true,
'bob': true
};
$obj$$.$claire$ = true;
$obj$$.document = true;
window['obj'] = $obj$$;


This has some nice features that help debugging and development. It's straightforward for the average programmer to look at the compiled output and figure out why the compiler is renaming something, and what the name should be. If we decide that we don't want the property "claire" to be renamed, then we can change obj.claire to obj['claire'].

Furthermore, this convention makes it easier to read and refactor code written by a large team of JavaScript developers. If Bob is using "All Unquoted," and he has a method defined as Foo.prototype.methodA = fn, then Alice can easily search for all calls to methodA in the codebase. She doesn't have to worry about opaque accesses to the method, like obj['method' + 'A'], because she knows that the compiler will break those accesses anyway.

Another way to look at it is that we use the dotted access (obj.alice) for compile-time property lookups, and array access (obj['alice']) for run-time property lookups.

But there are some big downsides to "All Unquoted." As you saw above, any property in the externs file cannot be renamed anywhere in the program. When your methods have the same names as native browser methods, they won't be renamed. It's not as powerful as it could be.

Even worse, it is difficult to safely convert a legacy codebase to use this renaming policy. Because you never had to declare your "external" properties, you probably didn't, and it's a bear to find them all.

Could we do better? Maybe there's additional information we could leverage to get fewer false positives and false negatives? Perhaps we could look at the type annotations, or at other property assignments in the program? We'll get to those questions in the next two posts.

Posted by Nick Santos, Software Engineer
URL: http://closuretools.blogspot.com/2011/01/property-by-any-other-name-part-1.html