 We've talked about how to confront uncertainty, to confront uncertainty in order to monitor parking lots, to confront uncertainty in order to validate wireless protocols. In the last part of the talk, I want to talk about some early stage work that my group has been doing on actually harnessing uncertainty. So can we turn uncertainty into something positive rather than trying to deal with it or make it go away? And the work has come out of our thinking about how to build more adaptive systems. So why do I need to do this? Well, mobile devices, of which we spend a lot of time thinking about, go through lots of changes at runtime that are caused by mobility. So for example, this device starts off inside where it has an inaccurate location, a good Wi-Fi connection, and it's in a fairly warm environment, which affects energy efficiency and heat generation and other things. And then suddenly you put it in your pocket, you wander outside, and then now the device has a more accurate location because maybe it's using GPS. It's in a colder environment, which can be better for energy efficiency sometimes. And it has a weak link to some sort of LT or 3G base station. And so these changes are happening all the time. And this is because of well understood effects of mobility, the way mobility affects network quality, sensor accuracy, and in certain cases, temperature and energy efficiency. And my group is working on several projects that are related to specific effects of mobility. But there are other sources of diversity that we want to think about, or we need to think about as well when we're developing software for the modern world. If you write a successful app, that app is going to run all over the world. And there are big categorical networking differences between, for example, a phone that's located somewhere in Africa and a phone that's located somewhere in Asia with a really high speed network. Users are another source of variation. Users are different. They may use the phone differently. They may have different patterns of usage. They may install different apps. They may interact with your app in ways that you don't anticipate. I've got a plethora of wireless devices. The smartphone, there's a great graphic, or I think they used to be maintaining this, where they look at Android fragmentation. So how many different Android devices are out there? And there's tens of thousands of different Android devices. And at any given point in time, there are three, four, maybe five versions of Android that are out there in the wild on different devices supported by different vendors. And then, of course, I have energy as well as a potential thing I might want to adapt to because the type of things I might want to do when the battery is full might be different than the type of things I want to do when the battery is empty. And so when you're writing software and thinking about how to deploy it into this big world, this can be very challenging. And it's made more complicated by the fact that now we see a lot of the same software libraries being used in lots of different contexts. So my group has also been doing some work on databases for mobile systems. And here's an example where you have something SQL Lite that was never designed to run on smartphones. And it's running on all these smartphone apps because it's a common database that's used by Android apps. And the access patterns and the ways that apps are using this database are quite different potentially than an app that you would write that would run on a larger computer or run for a different purpose. So that's pretty interesting. So a developer that's sort of thinking about this entire world can find it very difficult to make simple decisions about what their app should do or how it should behave. So here's an example. I have a timer and I'm trying to set the rate at which that timer should fire. And so if the device is really beefy and has a lot of battery, maybe that timer goes fast. But maybe if I'm in a place in the world where the networking conditions are very good, I don't want to fire this timer very often because it's going to cause some sort of networking activity to happen. And so there's all these different considerations that I can take into account. Unfortunately today, if I want to think about what to do about how to set this timer, I don't have very many good options. Option one is I could basically try to set one value and hope it works everywhere. But of course, if you were uncertain about what value to choose, if you had some legitimate reasons to wonder whether or not this single value would be right, it probably won't work well everywhere. It may work, but it may not work well. The other thing you can try is you can try to write adaptive code. And when we look to the Android code base as part of this project, we didn't see a lot of this. But this is certainly an option. So I could do something like if the battery is low, then slow down the timer, otherwise run it at a faster rate. But this type of adaptation that's done at development time is also very challenging because, for example, what threshold are you going to choose and is one threshold appropriate for all devices? How much of an effect on energy does this timer firing even have? That may have a big effect if I'm on a slow network connection and a very small effect if I'm on a very fast connection, or may respond to some other difference in the environment. And then if the branches are even different, how much of a difference is there? And again, that difference may vary over time. And so doing this sort of development time adaptation is very challenging.