The RHoK community

Two years ago representatives from Google, Microsoft, Yahoo!, Hewlett-Packard, NASA and the World Bank came together to form the Random Hacks of Kindness (RHoK) program. The idea was simple: technology can and should be used for good. RHoK brings together subject matter experts, volunteer software developers and designers to create open source and technology agnostic software solutions that address challenges facing humanity. On June 4-5, 2011 we’ll hold the third Random Hacks of Kindness global event at five U.S. locations and 13 international sites, giving local developer communities the opportunity to collaborate on problems in person.

The RHoK community has already developed some applications focused on crisis response such as I’mOK, a mobile messaging application for disaster response that was used on the ground in Haiti and Chile; and CHASM, a visual tool to map landslide risk currently being piloted by the World Bank in landslide affected areas in the Caribbean. Person Finder, a tool created by Google’s crisis response team to help people find friends and loved ones after a natural disaster, was also refined at RHoK events and effectively deployed in Haiti, Chile and Japan.


We’re inviting all developers, designers and anyone else who wants to help “hack for humanity,” to attend one of the local events on June 4-5. There, you’ll meet other open source developers, work with experts in disaster and climate issues and contribute code to exciting projects that make a difference. If you’re in Northern California, come join us at the Silicon Valley RHoK event at Google headquarters.

And if you’re part of an organization that works in the fields of crisis response or climate change, you can submit a problem definition online, so that developers and volunteers can work on developing technology to address the challenge.

Visit http://www.rhok.org/ for more information and to sign up for your local event, and get set to put your hacking skills to good use.

Android: Identifying App Installations

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

Tracking Installations

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

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

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

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

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

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

Identifying Devices

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

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

However, there are problems with this approach:

Non-phones: Wifi-only devices or music players that don’t have telephony hardware just don’t have this kind of unique identifier.
Persistence: On devices which do have this, it persists across device data wipes and factory resets. It’s not clear at all if, in this situation, your app should regard this as the same device.
Privilege:It requires READ_PHONE_STATE permission, which is irritating if you don’t otherwise use or need telephony.
Bugs: We have seen a few instances of production phones for which the implementation is buggy and returns garbage, for example zeros or asterisks.
Mac Address

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

Serial Number

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

ANDROID_ID

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

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

Conclusion

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

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

Notes from the 2010 LLVM Developers’ Meeting

My name is Lang Hames, and I am a PhD student at the University of Sydney where I research aggressive register allocation techniques. Last year I completed a six month internship with the LLVM team improving their register allocation infrastructure, and last month Google sponsored my attendance at the 2010 LLVM Developers’ Meeting.

I had a fantastic time at the meeting. Californian hospitality always makes me feel right at home, and it was great to see all my friends from previous Dev Meetings and my internship with the LLVM team.

The meeting was huge this year, with over 190 attendees and such a abundance of talks it was impossible to make it around to everything on the day. It’s a good thing the entire proceedings are up on the web. The talks this year were impressive and diverse, including introductions to major new LLVM-family projects, new applications leveraging LLVM technology, and targets ranging from GPUs to FPGAs.

A few of my favourite talks:

Doug Gregor, a member of the Clang team at Apple and code owner of the Clang libraries, gave a great talk on “libclang: Thinking Beyond the Compiler.” (PDF) libclang is the Clang compiler’s functionality packaged as a library. It lets you parse source, access diagnostics, examine ASTs and even find code completion targets. This raises the really exciting prospect of building new development tools on top of a feature complete front-end. Imagine having syntax highlighting, code-completion and cross-reference all handled by the same parser that’s in the compiler. It’s difficult to over-state how cool this is, and I say that as an optimization guy (I thought the front end was just there to feed me CFGs). I’d highly recommend checking out a copy of Clang and playing with it. Doug’s talk included plenty of code snippets, and I’ve found reading through them to be a great way to get started.

Craig Silverstein of Google gave a talk on “Implementing Include-what-you-use Using Clang” (PDF). Include-what-you-use is the principle that C/C++ source files should directly #include header files that provide declarations/definitions that they use, rather than relying on transitive #includes. Building on Clang, Craig has developed a tool to analyse C++ code to detect and correct violations of this principle. This looks like a really handy and great example of what you can build on top of libclang.

Howard Hinnant of Apple introduced us to libc++ (PDF), a new C++ standard library built from the ground up with C++0x in mind. It has a lot of cool features, including fast default constructors, minimal memory footprints for default constructed objects, and fast move constructors. Dependence on libstdc++ is no barrier to trying it out: you can happily link your project against both libraries (libc++ uses inline namespaces to avoid confusion over ABI incompatible objects). One feature I thought was particularly neat was the adaptive sort: the sorting algorithms in libc++ automatically recognize partially sorted ranges and optimize their behavior to exploit the partial sorting for better performance. Howard’s test cases showed impressive speedups (over 2x in a lot of cases). I’m really looking forward to trying this out in some of my code.

Greg Clayton, also of Apple, introduced LLDB (PDF), a debugger built on Clang and LLVM libraries. This looks incredible and deserves a blog post of its own, but I’ll mention a few of my favorite features here. By building on libclang, LLDB is able to parse complex C++ expressions, up to and including multi-line expressions with local variables and control flow. It has been built from scratch to support a multicore, multithreaded world, with per-thread state and runtime control. Symbolic breakpoints allow you to set breakpoints with everything from File and Line to regular expressions (great for breaking on getters, setters, handlers, etc). Finally, following LLVM’s design philosophy all this functionality will be available via a C-API, with python bindings provided too. Looks like another excellent base for new developer tools, and I can’t wait to see what people do with it.

Other talks I particularly enjoyed included Nadav Rotem’s talk (PDF) on using LLVM for C-to-Verilog synthesis (aka building circuits out of C-code). Nadav ran us though some of the optimizations necessary to prepare LLVM IR for efficient hardware synthesis. Xuejun Yang’s talk, “Hardening LLVM with Random Testing” (PDF), was also fantastic. Xuejun’s team have developed a system for generating expressive, unambiguous C programs with defined meanings which can be used to test compiler correctness. Since March, 2008 they’ve helped find and fix over 170 bugs in LLVM.

Slides and videos of the talks I mentioned, and many others, are available on the LLVM Dev Meeting 2010 website. I highly encourage you to check them out.

The Dev Meeting doesn’t stop at the talks of course. It’s an invaluable opportunity to meet and swap ideas with other LLVM developers. I got a chance to meet Jakob Olesen and Andy Trick, who have been doing great things with LLVM’s register allocation framework (my PhD research area). I also chatted with some of the Google devs who are using Clang to tackle issues such as include-what-you-use in the Google codebase. Finally I attended “Birds of a Feather” meetings on LLVM optimizations, and on the progress that’s been made (and plans for the future) in building Linux with Clang.

Many thanks to Google, Apple, Qualcomm, and the Qualcomm Innovation Center for making such an amazing event possible. I’d also like to add very special thank you to Google for sponsoring me to attend this event. At the end of the day I walked out amazed at what has been achieved in the last year, and how active the LLVM community has been. I look forward to trying out all these new tools for myself, and I can’t wait for next year!

By Lang Hames, LLVM Developer