Good morning, everyone, and welcome to day two of Google I.O. My name is Zach Cook, and I'm a product manager on the Chrome team leading our web payments effort. A special thank you for coming out and joining me at 8.30 AM, which is very early. And of course, a special thank you and welcome to everyone on the livestream, as well as anyone that's watching on YouTube later. I'm really happy to be up here today, talking to you all today about how we think about the future of web payments and how we're trying to really help users, both our users and your users, your customers, have pain-free checkout experiences on the web. But I thought I'd get started by giving a refresher on why we care about this space at all. I think it stems from the fact that the web is better than ever. You've probably heard it over and over again, from Rahul's keynote to all of our web track sessions, that the web is really amazing these days. You can build fast, rich, app-like experiences, and they're really compelling. And that line between what is web and what is app is more blurry than it's ever been. And we think this is an incredible opportunity. And things like WebGL and Polymer and Service Workers, these are all tools that can help you create these incredible experiences. I think, personally, my favorite example of how far the web has come is the fact that you can literally circumnavigate the entirety of the Earth's surface directly inside of a browser tab these days. So this is Google Earth running inside of Chrome. And to me, it just kind of blows my mind that you can do this on the web. If you don't recognize this, this is actually where we are right now at Shoreline Amphitheater, which is the beautiful white tent where all the keynotes are. And then, of course, we're in the back parking lot. But it's a very nice parking lot. So really incredible stuff. But when you look at all this amazing progress, there's one area that seems obviously behind. And that's the way we buy things online. Because despite all of this great progress, this is still what most checkout flows look like. It's the same questions, the same form fields, the same multi-step process. It's like, for all this great innovation, we're still stuck here. And I suspect this is very similar to the way checkout forms first worked when they launched. In preparation for this talk, I did a little bit of research. And I discovered that the first online transaction was made in 1984 in someone's home by a 72-year-old woman named Mrs. Snowflake, which I think is just an incredible piece of fairly worthless trivia. But I think that very little has changed in those years, even though it's 2017. And I think the stats reflect that we need some change here. Long checkouts continue to be one of the leading causes of card abandonment out there. And it makes sense. Here's a question for you. Has anyone in here on a mobile device ever abandoned a transaction because the process was too long or cumbersome? You can raise your hand. Oh my god, that's way higher than the stat, by the way. So that's amazing. And me too.  Maybe I do, maybe I don't. The point is that there's a lost opportunity to give users a really great experience here and to convert at that moment. So we're quit literally losing money. Despite these challenges, though, mobile commerce is huge. I mean, mobile commerce in the US alone this year is expected to exceed $150 billion. That's all the more impressive when you consider the fact that mobile websites still convert about a third lower than their desktop or laptop counterparts. So we have a lot of work to do and a huge opportunity here to really better the lives of our users. And so every good platform out there, whether it's apps or the web, needs a good payment solution to succeed. And so it became obvious to us that the web needs a better answer for payments. And that's what I'm here to talk to you today about today. And in that sense, I actually have really good news. It already exists. Last year at Google I.O., a couple of my colleagues were up on stage. And they announced that we were working on this new API called Payment Request. Well, I'm happy to report that not only did we say we were going to launch it, we actually launched Payment Request in September of last year. So what is Payment Request? It's an open, built into the web, designed to be fast and secure, ready to be used today API for transacting on the web platform. We're going to be talking about all of these different components throughout our talk today. And I'm really excited to just dive right into it. But first, I should clarify something. Payment Request is not a processor. We're not trying to make the browser a processor or a gateway or another new entity in the system to move money from point A to point B. We think the industry has already done a great job of actually filling this service. Great players like Stripe and Braintree and Vantive. And we love the work that they're doing. No, we're focused on users. We're focusing on taking that user experience that seems stuck in legacy mode and moving it out of that into a much more faster streamlined experience. So when we thought about designing the Payment Request API, we had two goals, I think, primarily in mind. The first is that transactions on the web should be seamless. And we have to start with the status quo. So we have to take the existing world, often times the world of credit cards, CVCs, billing addresses, all those complicated things from a UX perspective. And we have to make them better. The second thing is we have to think about security and how we can improve that. And I don't just mean things like HTTPS, because, of course, we should always have HTTPS everywhere. We're big advocates of that. But I mean, we should be forward looking and say, how can we bring more secure forms of payment, like tokenization, directly into the web platform? So how can we unlock opportunities for players like Android Pay and Samsung Pay and future tokenization technologies to have a home directly in the web platform? So high quality, secure payments become first class citizens of the web platform. Now, I could talk about this all day long, but I'm going to just go ahead and jump to a demo and show you what this all looks like. All right. So it's going to jump over to the Wolfvision here. All right. So as I mentioned, payment request is alive and ready today. So you don't have to wait to start implementing. And we actually have a number of really great merchants implementing, one of which is Kogan.com. It's a little blurry, but hopefully you guys can get the idea. Kogan is Australia's largest retail company. And they've implemented payment request. And it just so happens that Chrome also has an office in Sydney. Now, I've never been there, but I'm going to operate under the assumption that one day they will let me go to Sydney. And I'm going to give myself a gift on arrival that will be waiting at the Google Office for me. And so I'm going to buy something that everyone I think needs, of course, USBC adapters, super common. So I'm going to add this to my cart. And it's now added to my cart, as you can see. And I'm going to hit the Checkout button. And so you see here the sort of standard thing happens. I'm on Kogan.com. The shopping cart loads up. I've got my list of items I'm about to purchase. I have delivery estimates, and I hit the Checkout button. And here's payment request in action. So instead of going to the traditional checkout flow at this point, a payment request sheet slides up directly from the bottom. We've got the merchant name, their HTTPS URL with a lock icon. We've got the Chrome logo in the bottom left, so users are aware of where this data is coming from, as well as a bunch of other information, as you can see. So first, you see we have a total amount of money being requested. So you see right now it's Australian dollars for $5. And you see that I already have a Visa credit card default selected there. And the only thing I have to do is choose a shipping address. So this makes sense because, of course, it's a physical good, so we have to ship it somewhere. So I'm going to tap on and choose. And you see here that payment request already knows my most frequently used addresses. So you see the first one there, my number one, is my main office in our San Francisco headquarters. And then the second one actually is our Sydney office. What this tells you is this is not the first time I practiced this demo. So Chrome has stored and saved my address here. So I then tap on this address. And what's happening when I tap on that is we take that address and we send it behind the scenes to the merchant so they can use that address to dynamically populate the set of available shipping options. So you'll see they default selected free shipping for me. But if I tap on that, I can also select express shipping. Now in this case, I have no idea when I'm going to go to Sydney and pick up my little converter here, so I think standard shipping will be fine for me. And then I hit the pay button. And you'll see the only thing that I have to do is input a CVC. Now because this is a live transaction and something should be kept secret from the world, I am not going to show my CVC number to everyone. But you can trust that I just typed it in. And now the transaction is running behind the scenes. We've taken that data.  And we've sent it behind the scenes to Kogan. And as you can see, the transaction is successful. Yay, I love when demos go well. So that's amazing. What? Thanks. I think what's really cool about this is that I didn't have to type in anything except for my CVC. We had all my data stored. It was all ready to go. All I had to do was confirm it, off it, and get it over. So that's the kind of seamlessness that we're talking about bringing to the web. Now I know that we are really focused this year on the mobile web track. But the reality is that we need to ship back in a demo mode because we still have, there we go, perfect. Again, we've been on the mobile web track. And that's the big focus for us at I.O. But we all know that users still love buying things on their desktops and on their laptops. And we thought that we should bring the same great experience to these platforms. So here you see, I have a shop loaded up on my Mac and Windows, or sorry, Chrome running on my Mac. And I'm going to tap the Buy Now button. And as you can see, a new payment sheet optimized for the desktop experience comes down from the top. And what's great here is you'll see that my same information is available. So I choose an address. You'll see it's got my same addresses that you saw on my mobile device because I'm signed in. And all that data is sinking across all of my instances of Chrome. In this case, I'm just going to ship to our Spear Street office. You see that methods are still dynamically calculated. So we offer free shipping inside of California. But you can see, just as a demo, if I do decide to ship somewhere else, shipping dynamically changes to $10. And in this case, my 8.605 visa is also there present, the card I just used to make that last transaction. But in this case, since I can't hide the screen, I added a test card that I'm going to go ahead and use to facilitate payment. So I do the same thing, tap on Pay, insert my three-digit CBC, hit the Converm button, and the same thing happens. So your order has been successfully placed. So really great. And I'm really excited to say that we are bringing payment requests to all Chrome platforms very soon. So really nice. So we can pop back over to Slides. Can we pop back over to Slides? I feel like we'll get there. Excellent. OK. So now you've seen payment requests in action. I want to help you understand a little bit how it works. Now, I won't go into too much depth here because we already have a lot of great resources. But I want to give you the core idea of how this whole process works. A payment request is a JavaScript API, of course. It's built and baked into the web platform to create these experiences. This is what you saw there. All was natively Chrome-rendered UI. And the first thing you have to do when you want to create a payment request is you have to tell us how you can get paid. We call these supported methods. And there's two types of supported methods that exist inside a payment request. The first one are things that are baked into the standard. In this case, we have something called basic card. Basic card is a great fallback mechanism. And it's your way of telling the browser, hey, if it looks and feels and functions like a piece of plastic in someone's wallet, it probably maps to basic card. So it's your way of saying, I accept any of these forms of payment. I don't show it here, but there are ways to get more nuance than this as well. You can say, I only accept debit cards, or I only accept credit cards from these three networks. All that's totally possible. The second thing you can pass in are supported methods that we call proprietary methods. These are identified by URLs. And in this case, for example, if you wanted to leverage the great new stuff that the payments team announced yesterday around Google Payments, this is how you tell the browser that, hey, I support any of those Google Payment methods. And so there's a proprietary system built in here so that every entity in the payment space can actually participate freely in the payment request ecosystem. It's the job of the browser to look at the ways a merchant can get paid and the way that a user can pay you and match those automatically. And that's what allows us to offer that great rich experience where things are default selected. So all I have to do is confirm and pay. The second thing I have to pass in are details of the transaction itself. There's only two required things here. You have to pass in a label, like purchase amount, for example, and you have to pass in an amount of money that you're looking to get paid on. In that sense, there's a currency code. This could be US dollars, or as you saw in our demo, Australian dollars, and a value. And we use that to render the appropriate amount on the screen. You can also pass in an optional set of display items. These are things that show up that basically inform the user about how that total amount of money was reached. These are totally optional, but we really recommend them because it helps the user explain how that total amount of money was reached, things like subtotal, taxes, shipping costs, et cetera. And the final thing you can pass into payment request is your completely optional set of additional information you might need to complete your transaction. So when we saw the Kogan demo, you saw that what they had done was they requested shipping true. This basically tells the browser, hey, if you have addresses stored, leverage those so the user can select them.  So when I tap an address, we take that address, we bundle it, send it to the merchant so they can dynamically calculate shipping options, and there's a way in the API to then update us on the set of available options. So it makes a really robust, rich experience. You see, you can also request things like email, phone, and name. Email, for example, was also in the Kogan demo because that's utilized for a new customer like me who had never purchased to be able to send an email transaction receipt. Again, all of these are entirely optional. The only thing you have to have in a payment request is an amount of money and a way that you can get paid, at least one way to get paid. Something that we, oh, and now you have to put it all together, of course. So quite simple, you just construct a payment request so you pass in those three components we just talked about. And then whenever you're ready to actually show that payment sheet, you call .show. And .show is the function that says, hey, actually slide up that payment sheet and facilitate payment. At that point, that returns back a JavaScript promise, and you're just gonna wait. And at some point, you're gonna get back a payment response. And that payment response is just a JSON object that contains all of the data that you requested and that you need to facilitate the transaction. So if it's a credit card, you're gonna get things like card number, name, a billing address, even a CVC to run it through. If it's a proprietary form of payment, you'll get all of the data for that particular form of payment. So Android Pay is also supported on this. So if you got an Android Pay response, you would be able to parse that response and pull out that tokenized form of payment and send it off directly to your payment processor.  And that's your way of telling the browser, hey, I'm finished with this transaction, go ahead and close that payment sheet. That then also returns back a promise that will resolve when that payment sheet is completely closed down. And that way, if you have like great UI, BIPs that you wanna flip or whatever, you can do that all seamlessly without the closing of our animation. And that's it, as much as it takes to actually get that great experience we just showed on Kogan.com. Now there's one other API I want to mention, or one method, which is Can Make Payment. Can Make Payment is an API that allows you to ask payment requests if the user has a form of payment already active and ready to go before calling.show. So if the user doesn't have anything set up, you'll get back false. If they have something set up, you'll get true. We think that this API, along with that set of optional information at the end there, that third component, allow payment requests to be really flexible and they can work into all of your different flows. And so it's really nice to be able to, you can just use it as simply as a payment mechanism, just for a credit card, or it can facilitate the entire transaction flow, including shipping address and names and emails and phone numbers. And we have merchant shipping, all different variations of this. Now as I mentioned, one thing that we're really happy to announce today is that we are coming to every single Chrome platform. We announced Android last year and now we're happy to announce it's coming everywhere. That's Android, Linux, Windows, Chrome OS, Mac, as well as even Chrome for iOS. And so for users that are synced, all of that data is stored and synced across all your devices. So the minute I sign in from one to another, all that data is there and ready to go. There's a theme here with payment requests, which is let the browser help you. We've got this data stored. Our users trust us to store it. What we want to do is share it with you. All we need is user consent to do so. So in some sense, think of payment requests as a way for a user to grant consent to share this data with you seamlessly and easily. Now something else I'm excited to announce is that we also have support for all Google forms of payment built right in. So if you went to the keynote yesterday with Shridhar and Polly, you saw that we're building this great new payment experience where all of your forms of payment in Google are grouped under a single application. All this is gonna be built and seamlessly work inside of Chrome and with payment requests where most of the heavy lifting is actually done by us. So you'll pass in that google.com slash pay identifier and you're gonna get all the benefits of the Google payment ecosystem built right in and access to those hundreds of millions of fobs, which we think is really compelling. And as you can see, it's a really nice experience built directly into Chrome. Something else that I think is also incredible is the fact that payment requests now also work seamlessly with AMP. So if you're not familiar, AMP are accelerated mobile pages. They're basically incredibly fast loading pages that load virtually instantaneously. So in this GIF on the right hand side, you'll see a live example of this working on one of our partner sites, portero.com. You'll see that it all starts from a search. You search, you tap on a result and that page loads basically instantly. So user can very quickly go from searching to seeing the entire product information. They then tap that buy button directly on the product page and the payment request sheet slides up. All the information is there. You're ready to transact. So the entire experience from front to back can be done in less than a minute. It's really amazing. AMP has seen incredible success. And so if you haven't yet looked into AMP for your product pages, I would encourage you to check it out. And if you have AMPed your product pages, I would really encourage you to look into leveraging payment requests to just facilitate that transaction right there on the page. Now, I know I'm talking about a lot of Google here, Google Chrome, AMP, which is an open standard, Google Payments. But one thing that is really great today to be able to announce is that this API is a cross-browser API. We talked about openness, right? And openness means that it should work everywhere. And so this is really great. Edge has launched. Samsung Internet has launched. Chrome has launched. And Firefox is in development and launching soon. So we've seen a lot of movement in the industry, which we think is really incredible. Yeah. Thanks. I think this tells you that there's a commitment in the industry to solve this problem and to really make web payments compelling and to give users on every platform independent of their browser choice a great checkout experience. And so it's been great working with all these players inside of the W3C. And of course, as I mentioned, this is available now. This isn't just Vaporware. It's not something that we're launching soon. No, payment requests exist. And we already have a number of great merchants, literally around the globe, shipping integrations. So you've got Wego. You may have heard already. They're based in Southeast Asia. We've got Kogan in Australia. JD Sports, Nivea, players from Europe. We're really excited and thankful to all these early partners. And these are just some of the merchants that are shipping payment request integrations right now. We also recognize that we want to bring, well, not recognize, we want to bring the benefits of payment requests and seamless transactions, though, to all merchants independent of size. And one way to get that reach is to work with these great channel partners, people like WompMobile, who you saw in the AMP demo, WooCommerce, BigCommerce, Mobify, Weebly, Shopify. By working on these guys and building payment request integrations right in, we can bring these benefits directly to all merchants, even those in the long tail, because everyone should be able to give their users stellar experiences. And so we've been really happy to work with all these great guys. Now, I realize that this can be overwhelming, and that checkout flows are complicated. You're like, Zach, this all sounds great, but you have not seen my checkout flow. I've got guest checkout flows. I've got registration. I've got sign-in. I've got coupon codes. I've got all this stuff. And I realize that it's a big ask to go from not using this new thing to leveraging this new thing. So I want to throw out a potential place to consider getting started. And it starts with a challenge. And the question is to go back and ask yourself, what percentage of your transactions, especially on mobile, have only one item in the cart at checkout? So go back, run your numbers, and figure out what percent of transactions only on, have only one item in the cart at checkout. And again, focus on mobile. I think you'll be surprised at how high it is. We ask this question to our partners all the time, because we're curious. And it's always higher than what we expect. But we've been amazed to see that it's up to 80% sometimes of checkouts that only contain a single product. But if that's the case, why are we still stuck to a legacy system? It's like, the way we walk into a physical store is I grab my cart, I walk down the aisle, I add items into my cart, and then I go up to the front and I check it out and stuff like that. And that's the whole process. And then we brought e-commerce into the world. And we thought, eh, we'll stick with the same model. We're going to go ahead and have virtual aisles. And the user will have a virtual shopping cart. And they're going to walk the aisles and add items in. And then they're going to click on that shopping cart to review and check out. And then our form factor's got smaller. And we're like, ah, we'll keep the same model.  And so the flow ends up looking like for 80%, up to 80% sometimes of your users are on a product page. They're having to tap on the product, add it to cart, go find the cart, click on the cart button, review the cart, and hit the checkout process. And you just think, man, maybe we can optimize this. And so here is my recommendation or something you should consider to get started, which is consider payment request as a buy now button that you can add directly to your product pages. It's a way to pretty simply get started. You can leverage tools like canmakepayment and request shipping and request email address to facilitate that entire transaction right there on the product page. So just as an experiment and see how it performs, I think it's worth giving users, especially those that only want to make a single fast purchase, the option to do so. And again, with all the tools like canmakepayment, you can do so in a way where you can have full control over the system. So they don't have a seamless experience built in. That's fine. Skip it and go to your legacy flow. But we think there is a really great opportunity here to have an impact and drive up conversions. And then later, if this proves successful, you can consider how to leverage payment requests in your default checkout flow as well. Now, we've talked from the very beginning about openness. And when we first announced payment requests, we said that it was never about just making Google forms of payment easier, although, of course, we care about that. But it's recognizing that for true openness means that everyone should be able to participate in the ecosystem. And so one of the things that we're really, really happy to announce today that we've been working on for a long time is that we're officially opening up payment requests so that third-party payment application providers can participate directly in the ecosystem and show up in that exact payment request sheet. Because the reality is that the web is global and payments are global. And if we want to have global scope, we have to open it up so that everyone can participate freely. And we think this is really great. But to talk a little bit more about this, I want to invite up a couple of my colleagues from the W3C's Web Payments Working Group who we've been working on this with. From Alipay and Alibaba, let me welcome to the stage Max and Jaja to talk a little bit more about this. Yeah. Hello, everyone. I'm Max. And I lead the International Centers for Work for the Alibaba Group. Hello, everybody. I'm Jaja. I'm a senior engineer from Alipay, which is a company of EndFinishers Group. Before getting started, let me see a quick show of hands. How many of you have ever heard of Alipay? Whoa. OK. So how many of you have ever used Alipay to make a transaction? Oh, not bad. So mobile payments are very popular in China. For example, Alipay is used for online shopping, taking taxis at the supermarket, and lots more. And we can use fingerprint, face detection, and other biometric authentication methods. It's very secure and convenient. Alipay is not only popular in China, it's also a global brand. When we're considering to bring Alipay into the global market, we found that mobile web is the popular venue for people doing online shopping. We wanted to bring the good user experience of native Alipay directly into the web ecosystem. And we see that the payment request API standard is the best way to do this. We joined W3C and the Web Payment Working Group to work with Google to make sure that the payment request API standard can also support native payment app. So updating your native Android app to run instead of payment request API actually is quite simple. You just need to add in your Android manifest XML file to respond to the payment intent and add metadata which specifies your payment master's name. For example, for Alipay is alipay.com slash WebPay. Your payment app will then receive the payment request through this intent and should reply with the correct response for your particular application. But as you can imagine, in working native payment app from browsers has security challenges. For example, if there is a phishing attack and a fixed Alipay installed on user's phone, we don't want the browser to open up that fixed app. So how do we prevent this in the standard? So also, let's see a couple of manifest files located on the payment provider's website. This can contain a variety of useful information used to verify the authenticity of the payment app. The first is what we call the payment method manifest file. This is downloaded by the browser using the payment method identifier information, which for us is alipay.com slash WebPay. The browser does this by issuing an HTTP link header request, which points to the location of the payment method manifest file on alipay.com. Instead of this payment method manifest, we can then define the location of our second manifest, the WebApp manifest. This is where we define the information about our application itself, including the package name and the fingerprint information. What is important is that only alipay has control over this manifest file. And when the browser tries to invoke payment app, it will first download this manifest file and verify the signatures match. Let's look at the demo and see how this works. So all the demo is real. So in the first demo, the merchants support multiple payment methods. And when the user clicks buy button, alipay can show up as one available payment method. And if the user selects alipay, the native alipay app will be opened up, and the user can use their fingerprint to do the authentication. It's very convenient and secure. So in the next demo, the merchant only supports alipay. So the merchant can even show a pay with alipay button. And with just one click, and within several seconds, the payment could be finished. It's very convenient. And I think that will help you to spend your money more easier. Cool. So we are currently working hard with Chrome Team to bring this feature into production. So if you are a developer, you can use this feature in Chrome, in alipay, in UCWeb, and hopefully in more browsers in the near future. Alipay is the world-leading third-party payment platform. We have spotted more than 18 currencies, including USD, Hong Kong dollar, URL, Palm, Japanese yen, and so on. We are continually improving user experience and security, so technology, innovation, and implementing industrial standards. Welcome to the joint payment ecosystem. Thanks for being here. Thank you. Awesome. Thanks, Max. And thank you, Jiajia. I think it's really exciting to see an industry like this evolve, and we're really happy to be a part of it, and really pushing for openness on the web. As they mentioned, I'll quickly recap. There are just three actually steps to get started integrating your application today. One, you'll define your identifier. For Google.com slash pay, that's what it is. For alipay, it's alipay.com slash web pay. Secondly, you'll make a few updates to your manifest file in your Android app, as well as some functions to handle those things. And then finally, you'll set up some manifest on your web server, so you can be confident that Chrome is opening the right application. So really simple, really great, and I'm happy to announce that we're already working with some really great partners. So you'll expect to see Samsung Pay coming into Chrome, Alipay, as you saw just in the demo, as well as Square Cache, and a number of others. So I think you're going to see a lot of evolution in this space over the next three to six months. Now, I recognize there's a bit of irony here, which is that we are on the web track talking about how great the web is and how amazing it is. And then I'm up here saying, our first integration is with native Android apps. This is for a couple of reasons. One is because we do think that there are great experiences that can be built with native applications. You get access to things like fingerprints, so you can have biometric authentication, and it makes great experiences. The second thing is just a little bit easier to get started. But I have great news, which is that we are actively working on pure web app support. So you get all the benefits of the web, like no installation, immediate availability, and global reach. And so web apps can be full first-class citizens inside of the payment request system. We think this is actually really compelling. We recognize that users love to pay with certain brands, but don't necessarily have those apps installed. That's OK, and we're fully working and committed to bringing that support. And today, I'm excited to announce that we are working with PayPal to actually build out this experience and bring PayPal's web app directly into the payment request experience. So look forward to sharing more about that over the next few months. Now, again, we talked about a lot today. There's a lot of code samples, a lot of overviews. So we have a lot of great integration guides that are out there that you can reference. We've got payment request guides. We've got how you can get started integrating your Android payment application. And we also have a great code lab that you can run through, which helps you get familiar with the payment request system. So I encourage you to check those out. As well as after this, we do have a mobile web tent, which is just around the corner out this door to the left. So I would encourage you to stop by, say hello, see some of these things in action, and ask the hard questions. So thank you so much, everyone. It's been a pleasure to be up here today. Hope to talk to you afterwards. Hey, everyone, Sam here. In this web series, we'll solve common web problems with standards. These techniques are part of the web platform and work with any framework or library. OK, let's go. If you're animating some elements, whether you're using CSS, the web animations API, or libraries which just use request animation frame, make sure you help your browser stay speedy by letting it use your 3D graphics card. Sam, what are you talking about? When you look at a website, it's made up of layers stacked on top of each other. And your graphics card won't need to redraw for changes to only some certain CSS properties, specifically opacity and transform. These two properties let you move stuff around and change how visible it is. You can animate width, color, or other CSS properties, but do it sparingly and not in response to user action, where you want to be snappy. To keep things fast, if you have elements that move around a lot, you'll also want to set the will change transform or opacity CSS property. This is a hint to the browser. This element should be a layout all the time. Otherwise, when you upgrade or downgrade to a layer, you'll incur a cost. The browser has to redraw that specific part of the page. But if you give everything in your page a layer, this might bog down your browser as it struggles to compose them all together. This is a complicated topic, and you should check out more documentation to learn more about it. And most importantly, your site doesn't need to be perfect. It won't crush your user's experience to make a few mistakes here and there, but it's good to keep on top of it. Check Chrome's rendering section, Inside Developer Tools, once in a while, just to see what's happening and how your site's going. This was Layers the Standard Way. See you on the next tip. The only thing that evolves faster than technology is our expectations. We want everything better, easier, now. Suddenly downloading an app feels like it takes forever. And in many parts of the world, data is still at a premium, with one megabyte costing up to 5% of a monthly wage. Let's face it, though. Until now, the alternative to native apps hasn't been great. But that was then. Progressive web apps can now deliver mobile web experiences with a native-looking feel, offering features like real-time push notifications, adding a site to your home screen so you can easily jump back to it with a single tap, even when you're offline, plus the ability to make quick payments on the go. And all from your browser is the next generation of the mobile web. So what are we waiting for? Let's go and build something great. We tend to talk about the web, and today I think he's no different. Do you think you can beat Wikipedia at a server-side render, do you? I did. We face it to be two. The rules all change. One code base is not what you want, because then you end up with stagnation. I've got one function that actually produces the other function. It's almost become self-aware. The code is now writing itself. What time does the game start? LinkedIn is the premier social network for professionals. We are consistently one of the top apps on Google Play. My name is Pradeepra Dash. I'm the engineering manager for LinkedIn infrastructure team for the flagship apps. We have a million-plus reviews. We are consistently four-plus stars. Our users are really appreciative of how stable the app is, how it really helps them bring their professional profile forward. My name is Drew Hanny. I'm on the Android infrastructure team at LinkedIn. My team is responsible for the overall health of our Android application. We take care of releases to Google Play, our testing pipeline for the app, our build pipeline. One of the tools that my team has been excited about is the APK Analyzer tool, because we spend a lot of time paying attention to the size of our app, and it required some expertise to figure out what was causing your app to be a certain size. But now that we have the APK Analyzer tool, we've been able to expand that knowledge throughout the entire team. LinkedIn was an early adopter of Gradle, so adopting Gradle for Android was a pretty natural fit for us because we can share a lot of our custom plug-in logic that we've built, and we can also get consistent builds across developer machines and our build service. One thing that's really benefited us is the Lint system, which has a lot of built-in checks for common problems, and we've really appreciated being able to write our own custom Lint checks for LinkedIn-specific internal libraries. With so many developers checking into the code base, one thing that helps onboarding someone new is having a consistent code style throughout the code base. Android Studio lets us find a custom code style that each developer can add and automatically have their code formatted in the LinkedIn style. One of the things that we really appreciate is the open nature of the platform, where not only has the feedback that we have given back to the developer community in Accepted, but also being worked upon. In the last couple of years, my team has become way faster, much more agile, and being able to code easier and faster on the Android Studio. I also learned how to program computers, and then in 2001, we started the first video games company for mobile phones in Spain, called MicroJocs. In 2013, my studio was acquired by a big company. Some of the guys and myself, we decided that we should do something fresh, something new, and we found it on the run. Titan Roll is a real-time strategy game. It's considered it as a MOBA. It's a massive online battle arena, but especially designed for mobile devices. The game is today as it is, thanks to the Early Access program. We changed many things from the learnings, from the community. Since we launched the game on Early Access, we got more than 2 million installs on Android devices. We started in the Early Access program back at the very beginning of it. The difference between the Early Access program and traditional soft launch is that users are actively giving the team feedback. So you don't only check the metrics you have, but they also provide possible solutions. So you end up by doing the game players want to play. The thing about not having the ratings, but do having the constructed feedback was very good. The Early Access was a great opportunity for an indie developer, someone starting and very key for us in amnesia. When we started with the Early Access program, we approached it in different stages. So the idea was at the beginning to focus on the engagement of the games. Once we started that out, we focused on the retention of the game. And finally, we focused on monetization to do a valid product for the market. We managed with Early Access to improve our retention in a 41%. The engagement by a 50% and the monetization by a 20%. From the very beginning of the program till worldwide launch of the game. I feel very happy working on the video games industry because it has been my passion since I was a child. And it's really inspiring that through Omnibrand, we have a real chance to shake the new era of the video game. In response to popular demand, the Android framework team has written an opinionated guide to architecting Android apps. And they've developed a companion set of architecture components. Hi, my name's Lila, a developer advocate for Android. And I'm here to introduce you to these shiny new architecture components. These components persist data, manage life cycle, make your app modular, help you avoid memory leaks and prevent you from having to write boring boilerplate code. Your basic Android app needs a database connected to a robust UI. The new components, room, view model, live data and life cycle make that easy. They're also designed to fit together like building blocks. So let's see how. I'll tackle the database using room, which is a new SQLite object mapping library. To set up the tables using room, we can define a plain old Java object or pojo. We then mark this pojo with the at entity annotation and create an ID marked with the at primary key annotation. Now for each pojo, you need to define a DAO or database access object. The annotated methods represent the SQLite commands you need to interact with your pojos data. Now take a look at this insert method and this query method. Room has automatically converted your pojo objects into the corresponding database tables and back again. Room also verifies your SQLite at compile time. So if you spell something a little bit wrong or if you reference a column that's not actually in the database, it will throw a helpful error. Now that you have a room database, you can use another new architecture component called live data to monitor changes in the database. Live data is an observable data holder. That means it holds data and notifies you when the data changes so that you can update the UI. Live data is an abstract class that you can extend. Or for simple cases, you can use the mutable live data class. If you update the value of the mutable live data with a call to set value, it can then trigger an update in your UI. What's even more powerful though is that room is built to support live data. To use them together, you just modify your DAO to return objects that are wrapped with the live data class. Room will create a live data object observing the database. Then you can write code like this to update your UI. The end result is that if your room database updates, it changes the data in your live data object which automatically triggers UI updates. This brings me to another awesome feature of live data. Live data is a life cycle aware component. Now you might be thinking what exactly is a life cycle aware component? Well, I'm glad you asked. Through the magic of life cycle observation, live data knows when your activity is on screen, off screen or destroyed so that it doesn't send database updates to a non-active UI. There are two interfaces for this. Life cycle owner and life cycle observer. Life cycle owners are objects with life cycles like activities and fragments. Life cycle observers on the other hand, observe life cycle owners and are notified of life cycle changes. Here's a quick peek at the simplified code for live data which is also a life cycle observer. The methods annotated with at on life cycle event, take care of initialization and tear down when the associated life cycle owner starts and stops. This allows live data objects to take care of their own setup and tear down. So the UI components observe the live data and the live data components observe the life cycle owners. As a side note to all you Android library designers out there, you can use this exact same life cycle observation code to call setup and tear down functions automatically for your own libraries. Now you still have one more problem to solve. As your app is used, it will go through various configuration changes that destroy and rebuild the activity. We don't want to tie the initialization of live data to the activity life cycle because that causes a lot of needlessly re-executed code. An example of this is your database query which is executed every time you rotate the phone. So what do you do? Well, you put your live data and any other data associated with the UI in a view model instead. View models are objects that provide data for UI components and survive configuration changes. To create a view model object, you extend the view model class. You then put all of the necessary data for your activity UI into the view model. Since you've cached data for the UI inside of the view model, your app won't require the database if your activity is recreated due to a configuration change. Then when you're creating your activity or fragment, you can get a reference to the view model and use it. And that's it. The first time you get a view model, it's generated for your activity. When you request a view model again, your activity receives the original view model with the UI data cached. So there's no more useless database calls. To summarize all of this new architecture shininess, we've talked about room, which is an object mapping library for SQLite, LiveData, which notifies you when it's data changes so that you can update the UI. And importantly, it works well with room so that you can easily update the UI when the database values change. We've also talked about lifecycle observers and owners, which allow non-UI objects to observe lifecycle events. And finally, we've talked about view models, which provide you data objects that survive configuration changes. Altogether, they make up a set of architecture components for writing modular, testable, and robust Android apps. You can sensibly use them together or you can pick and choose what you need. But this is just the tip of the iceberg. In fact, a more fully fledged Android app might look like this. For an in-depth look at how everything works together and the reasoning behind these components, check out the links in the description below. To jump straight into code and get started working with these objects, you can check out the code labs and samples for lifecycle and persistence. Happy building, and as always, don't forget to subscribe. I'm Vojtek Karciński. This is Android Tooltime. And let's talk a bit about the Espresso test recorder and how it can help with adding UI tests to your app. Well, first, a short explanation for those unfamiliar with Espresso. Espresso is a testing framework designed to provide a fluent API for writing concise and reliable UI tests. However, it is often the case that developers are reluctant to add UI tests to their apps or simply don't have time to learn the framework. This is where the Espresso test recorder comes in. It lets you create and add UI tests to an existing app in an interactive way. You might have previously seen the beta version of this feature, but in Android Studio 2.3, we are promoting it to stable with a few enhancements. To get started with the test recorder, click on record Espresso test under the run menu. The device selection dialog pops up and after you make your choice, the test recorder runs your app in debug mode. Simply progress through your app's UI as a regular user would by clicking buttons, swiping and typing into input fields, and all those actions will appear in the test recorder window. You can also click here to add an assertion to your test at any time during recording, which will trigger the test recorder to dump the current view hierarchy. To select the view you want to assert on, click on the screenshot that appears in the recorder window and choose between the assertion type from view exists, doesn't exist, or check that it contains the specified text. When you've finished recording your test, the test recorder generates the equivalent test code to run your actions and assertions and puts it in a new file in your projects instrumentation test folder. It also checks if your build file contains the required Espresso dependencies and adds those if needed. When you look at the source file that Espresso test recorder created, you will see that it's perfectly normal human readable code. So if you need to further customize your tests or alter them when your app changes, you can simply open the file again and make the alterations you need. As you can see, the Espresso test recorder is very simple to use, but it does come with some limitations. As of Android Studio 2.3, only a few most common assertions are available through the recorder UI. So if you need anything more complicated than that, you will need to edit the generated code by hand. Also, at this stage, the test recorder cannot handle all situations where additional synchronization is needed to deal with delays and async operations in your apps. I highly recommend getting familiar with the Espresso idling resource API and using that in your tests to signal when a long running operation happens. For advanced users who want to tweak some aspects of test code generation, there's a settings page for the test recorder in Android Studio Preferences. Here you can change the maximum view hierarchy depth that will be used for view identification and if app data should be cleared every time you record a new test. The Espresso test recorder is a great way to start adding tests to your app, whether you want to learn Espresso by examining the generated code or simply to quickly build a test suite which you can customize later. We look forward to your feedback on our social channels and happy testing. There are approximately 285 million people with visual impairments around the world. Making your app accessible not just opens it up to these users but it has a potential to improve design for everyone. Most people are familiar with an accessibility service called TalkBack which is a screen reader utility for people who are blind and visually impaired. With TalkBack the user performs input via gestures such as swiping or dragging or an external keyboard. The output is usually spoken feedback. There are two gesture input modes. The first one is touch exploration where you drag your finger across the screen and the second one is linear navigation where you swipe left and right with your finger until you find the item of interest. Once you arrive to the item you're interested in you double tap on it to activate. The primary way in which you can attach alternative text description for your UI elements to be spoken by TalkBack is by using an Android attribute called content description. If you don't provide content description for an image button, for example, the experience for a TalkBack user can be jarring. Unlabeled button, double tap to activate. Unlabeled button, double tap to activate. For decorative elements such as spacers and dividers setting content description to null will tell TalkBack to ignore and not speak these elements. Make sure to not include control type or control state in your content description. Words like buttons, selected, checked, et cetera as Android natively does that for you. Android Lint automatically show you which UI controls lack content descriptions. To keep TalkBack spoken output tidy you can arrange related content into groups by using focusable containers. When TalkBack encounters such a container it will present the content as a single announcement. For more complex structure such as tables you can assign focus to a container holding one piece of the structure such as a single row. Grouping content both reduces the amount of swiping the user has to do while streamlining speech output. Here is an example of how ungrouped table content works. Song details, name, hey Jude, artists, the Beatles, cost $1.45. And here's the same content with grouping applied. Content grouping activity, song details, name, hey Jude, artists, the Beatles, cost $1.45. You should manually test your app with TalkBack and eyes closed to understand how a blind user may experience it. We also provide accessibility scanner as an app in Google Play. It suggests accessibility improvements automatically by looking at content labels, clickable items, contrast and more. Vision impairments doesn't just refer to blindness. 65% of our population is farsighted for example. With careful design you can make sure that many of your visually impaired users can have a positive experience without having to rely on TalkBack. Begin by making sure that UI of your apps works with other accessibility settings including increased font size and magnification. Keep your touch targets large, at least 48 by 48 DP. This makes them easier to distinguish and touch. Provide adequate color contrast. The World Wide Web Consortium created color contrast accessibility guidelines to help. And to assist users with color deficiencies, use cues other than color to distinguish UI elements. For example, more descriptive instructional text. If you're using custom views or drawing your app window using OpenGL, you need to manually define accessibility metadata so that accessibility services can interpret your app properly. The easiest way to achieve this goal is to rely on the Explore by Touch helper class. With just a few methods, you can build a hierarchy of virtual views that are accessible to TalkBack. Making your app accessible doesn't just need to new users. It helps to make the world a better place, one app at a time. To read more about developing and testing your apps for users with visual impairments, check out the links below. Also, check out the video on developing for users with motor impairments. Hey, good morning, everybody. Good to see you all here and on the live stream. Good morning around the world. If you're joining in, welcome. My name is Paul Bakos. I'm a developer advocate working on making the web faster and user-friendly and currently with my focus on Accelerated Mobile Pages, AMP. And I'm here to tell you about a combination made in Heaven, as I would call it. And what I'm talking about is the combination of AMP and Progressive Web Apps. Now, AMP makes the first hop blazing fast. If you've experienced it before, you know that it's usually the case. But in Progressive Web Apps, enable amazing reliability and engagement that you will only see from a native world. But that's just on the surface. So on the surface, that combination kind of makes sense. But then we have to start from the beginning because once out of time, the story starts with a modern-day web developer in 2017 with a growing imposter syndrome and the feeling of drowning. And so in 1999, if you created a web page, what you did is you created some HTML marker. You added some CSS. And then you hit the publish button. You had some really cheap server. There was no slash dot anything to have the slash dot effect. So it really was fairly good. And I felt like I could do anything. I felt like, oh, yeah, this is amazing. I'm connected to so many people around the world. And it's a free entry for everyone. But now let's look at 2017. So you create a marker. You add some CSS. Then someone tells you to definitely choose a build tool and make sure you choose the right one. You add Babel Webpack. And obviously React, because I heard millennials like React. And then so many other things that you have to do to actually be competitive in today's landscape. And then so yes, being a modern web developer is hard. But in fact, if you're looking at it from a company angle, what does your company, let's say you're a publisher, what is your company trying to accomplish and what do they need to do? Now you go one level up and you see it gets even worse because you have a number of different deploy targets, the mobile web, the desktop web, native Android, native iOS, instant articles, Apple News, and so on. So there's a number of growing ecosystems that you need to support. And now I'm here to tell you that you add two more to the roster.  So yes, I get it. I get it. But hear me out. So let's take a zoom out world view, a bird's eye view, onto what we're actually trying to do. Now if we look at an e-commerce case, what we're actually trying to do, regardless of technology, I'll take a guess. You want to sell stuff. You want to sell lots of stuff. To sell stuff, you need to bring your product landing pages to lots and lots of places where they're seen by millions of people. And landing on your browse and product pages should be effortless and instant. And finally, the payment process should be effortless and simple as well. The user should automatically be inclined to come back and buy more of a time through re-engagement. And that's the kind of experience I want. I want to start fast and then stay fast. So why does AMP solve part of this problem? Well, I'm just going to recap briefly why AMP matters here. So think about your apartment key. Would you give your apartment key to all of these people? Well, there's usually one or two that say, yes, sure, could turn into an epic house party. However, that's really optimistic. I think this scenario is way more likely. However, on the web, there's an ongoing challenge of having a lot of monetization and user acquisition methods in play versus the user experience. And this happened because we're giving the keys to everyone. We're giving the keys to everyone, for everyone, to our web pages. So as soon as we add a script from a third party to a web page, all bets are off. If you don't trust, if you can't trust that source, they could do whatever they want on your web page. It is really like giving a key to a stranger. And so what we get because of that are slow-learning pages, non-responsive content, content that's shifting around that is really, really not really great to experience. And we just had that. So I'm going to skip this. Now, the current situation is pretty bad. We have over 200 server requests per mobile web page on average. And 19 seconds is the average mobile launch page time over 3G. Now, out of those 19 seconds, 77% of all mobile sites take longer than 10 seconds to load. But don't worry, it gets worse. In fact, if you look at that 10-second number in particular, it's really important because at 100 milliseconds, an interaction, for instance, clicking on a button feels instant. One second, it still feels natural. You still have your context model. But then at 10 seconds, you lost the user's attention. And yes, that has been measured multiple times before. The fact that after 10 seconds, if you load a mobile page, almost all users drop off. Now, if you've been listening to the previous stat, yes. That means 77% of all pages have likely never seen a mobile. So that's why we created AMP to actually combat this problem, to bring back the beauty of the mobile web. So we have three components in AMP. The AMP HTML, which is a superset and a subset of HTML, that adds new components, but also restricts some of the things that you can do. And then we have AMP.js that powers those things. And then we have the AMP caches. Now, just two quick examples of what AMP does are a few of the things it does. For instance, it can prioritize content loading. So it knows exactly where everything is rendered on the page before all the external assets are loaded so that we can pre-render the above the fold and not render anything else below the fold. And the caches can then use that. The platform that uses the caches to deliver your AMP pages can use that to smartly pre-render quite a set of pages. So if you're arriving, for instance, on Google Search and you get the top stories carousel, which is powered by AMP, some of those things are often pre-rendered before you click on them, which is why they feel so instant. Now, if we go back one step and look at this comparison that I did before of 1999 versus 2017, how does this look like in AMP? Let's have a look. Yeah, I think it looks way better. In fact, that's what you do. You create HTML markup. Because we have high-level components like accordions and all sorts of things in the HTML markup, you never write JavaScript. So you create HTML markup. You add some CSS. Out of it, you get a fairly nice, responsive, interactive content page if you want to. And then you just hit Publish. And it can be on a really cheap server because the caching infrastructure on top automatically quals and caches all of your content to be displayed in the apps. So you get back to a really, really cheap deployment model. So why progressive web apps? Well, they're engaging. They give you push notifications and home screen stickiness. And they're also reliable. They give you offline access and a response of UI, and those are the things that you know usually from the native world of things. And that's a common reason why developers build native apps. But in fact, 80% of the time is spent in the top three native apps on a phone. And there's zero number of apps that get installed on average per month. So that means that it's very, very expensive, for instance, through advertising to acquire new users through the App Store model. And so what we want, essentially, is a combination of those things. We want the capabilities of the native app ecosystem, but we also want the reach of the mobile web. And we get that with progressive web apps because they have many of those features built in. And they're also basically a website. So it's a pretty good way to get both of those things. So why is the combination of those two a good idea? They seemingly seem to attack different spaces on a different level. Well, if you just build a progressive web app, then you have the challenge that your first load is still going to be so slow. And the reason is that progressive web apps are really dependent on a technology called service worker, a client-side proxy that accelerates and caches the delivery of your app shell, of articles, et cetera. But the service worker only kicks in after the second request. So on the first load, you don't get those performance benefits. And usually, it's the first impression that counts if you want to get a new user. But then on the AMP side of things, you get no user author JavaScript. So we don't allow you to write user author JavaScript, except in an iframe. There's no custom service worker, no push notifications, no web app manifest when served from the AMP cache. On your origin, that still works. But when served on the AMP cache, you don't get all of those benefits. And so that is in order to be predictably fast. So the difference, really, on the AMP side, you get reliable instant delivery and optimized discovery. But no JavaScript static content, mostly. But then on the progressive web app side, the first delivery is usually slower. It's not as easily embedded as AMP documents. I'll talk about this later. But you get access to the latest web APIs. You can do whatever you want. And it supports much more dynamic content, even. And to combine those two is what we call start fast, stay fast. And now, of course, you could forget all of that and simply focus on the fact that the combo makes first a mesmerizing led animations. And if you've been doing web animation, sorry, if you've been doing web development in the 90s and early 2000s, I think this one might work even better for you. Wait for it. Mm. Yeah, OK. OK, let's not go there. But how do you actually do it? How do you actually get there? Well, we have three application patterns that make it happen. First, I call AMP as progressive web app. Second, AMP to PWA. And the third, AMP in PWA. Now, if you've been listening and I've been comparing the two, you're like, wait, AMP as PWA? We have actually, for sites that have static content mostly and don't have a lot of interactivity, you can have an AMP that is both a progressive web app. In fact, MyNet, who is one of the leading publishers in Turkey, has done that with their pages. So what you see here is a fully compatible AMP page. All of this is AMP with a full navigation concept, back and forth, carousel, whatever. All of it is AMP. And it also has progressive web app features. So it can be installed on the home screen, has a web app manifest, and so on. And in fact, just by doing that, they saw tremendous uptick and quite a few numbers. They got over 25% higher revenue per article page view. That is really the important number, because that means the bottom line is better. And four times faster average page load speed, over 40% longer average time on site, over 30% more page views per session, and much lower bounce rates. So in the end, really something worthwhile to do. But you can actually go further than that with our pattern. You could actually, because you have the service worker in place on your origin, you can insert anything into the AMP page that you want, random stuff that AMP doesn't like, because you are in control as soon as the service worker is running. Now, I had some nostalgia, so I thought, why not insert some 90s DHML magic into the AMP website? And I found this amazing mouse cursor. And this is exactly what I did. So here we go. I'm going to enable the service worker. I'm going to reload. And yes, I have a fancy mouse cursor and an animated background, all the things that AMP doesn't like. And first of all, what have I done? So you shouldn't do exactly that, maybe. But this pattern still comes in useful if you want to insert ads that are, for instance, not supported in the ecosystem yet, or other things that you need on your origin to run. So next is AMP to Progressive Web App. Now, all of this is based on a technology, on a component that we call AMP install service worker. And the AMP install service worker, the way if you've used service worker before, you register it in JavaScript on your page. And because you don't have access to JavaScript, we have an equivalent that is AMP install service worker. But the cool thing is that this component also works when your page is loaded on the AMP cache, let's say, in the top stories carousel on Google. It can install the service worker from your site's origin from your own domain so that subsequent clicks are accelerated. And the way this looks is the pattern is always the same. The user discovers content. The service worker installs in the background while the user is consuming the content. And then the user is upgraded instantly to a PWA. Let's have a look at how this looks in real-world production examples. So first, let's look at crossing, which is a job search site similar to LinkedIn in all of Europe. And so if the user discovers content, they check out a job that they like, they click on it, and then the service worker installs in the background. And now, if they're actually interested in one of those jobs, they're instantly forwarded to the Progressive Web App that push notifications can remind them to come back if their job is not available anymore, et cetera. So the next click is going to be instant. Now, next example, with Goibibu, which is a leading travel search company in India, you get the same pattern in a completely different vertical. User discovers content. Second page, the service worker installs in the background.  But now there's a Get Availability button at the bottom. If you click that button, again, you're instantly redirected to the Progressive Web App that allows you to check the availability. We could have even checked in advance in the service worker if there's availability so that even the API call wouldn't be necessary anymore. And then Rakuten, a Japanese recipe website that I've created recently is called Rakuten Recipe. And in this case, same pattern. The user discovers the content, arrives on a recipe site. And so you browse through the recipe. You realize, OK, there's a couple of connected recipes that I'd like even more. Or I want to bookmark this. And then the user is instantly upgraded to a Progressive Web App. Now, with Rakuten in particular, I have some stats to share. In fact, if you look at the different combination of things they've done, it's quite impressive, in my opinion. So with AMP, they've seen over 50% more time spent per user over 3.6 times higher CTR within the AMP page compared to other Rakuten Recipe sites. And then with Add to Homescreen, with a Progressive Web App feature, they're seeing over 70% more visits per unique user and over three times more page views per unique user once they install to the home screen. And push notifications, same thing. A lot more re-engagement, three times more weekly sessions per user after the first week, four times after second week and five times after first month. And now this is really important. With push notifications, they get three fourths, so 75% lower bounces for those users coming in by push notifications than by installs to shares. So they're seeing much more re-engagement through that channel. OK, so this sounds hopefully pretty good, but there's still a problem. Now, if you copy the URL in the Progressive Web App, you share or send it to a friend, then that friend will not go through the AMP install service worker flow. So they will open the Progressive Web App without a warm cache. Now, what do we do with this? Well, usually you would have AMP pages deployed on one subdomain, and you have the Progressive Web App deployed on another subdomain, and a link from an AMP page leads to the Progressive Web App. Sounds pretty straightforward. However, you can change that and reuse the same domain, the same URL space for both of these. And you can do that because the service worker can intercept navigation requests. So if you click a link, the service worker can say, OK, no, I'm not going to give you the next AMP page. I'm just going to give you the Progressive Web App instead, even though you're on the same domain. And it's actually just a few lines of code to do that. So you check for a navigation request, respond with a Progressive Web App. Now, what happens if we do this? A couple of magical things, because without the service worker, we still just get AMP. So for browsers that don't support it, you always get a fast experience. And then with service worker, you get the combination of AMP in the background and the Progressive Web App because the service worker intercepts and delivers the Progressive Web App instead. And if you don't have a service worker and you still want people to lead to that richer experience, a Progressive Web App that might not work fully because there's no service worker in some browsers, you can still do that with a technology that we call shell or rewriting. That's part of AMP Install Service Worker. Basically what this does is it says, detect if service worker is available in this browser. If it's not, rewrite the URLs on this site to go to a fallback domain. Now, OK, we have this complete, but now we have another problem. We still have this problem with our deploy targets. We still have plenty of deployable targets. And in fact, in this case, we probably have two content back ends. We have AMP HTML on one side and then probably JSON or some other content back end for the Progressive Web App that powers the Progressive Web App. Now, that is where the final pattern comes in handy, AMP in Progressive Web App. And in fact, AMP pages aren't just web pages. They're ultra-portable, embeddable content units that can stand on their own. And you think about it this way. If you don't think about it just as a website, some magic things can happen because we can get from this step to this step where AMP HTML powers all of my experiences, in this case, the AMP experience and the Progressive Web App experience. Now, one way to do this is to build an application shell and then use an iframe. But iframes are slow. And what we do instead, because we trust the content, it's our own content, we use Shadow DOM. So how does this look like? Without Shadow DOM, you get one window for every iframe that I initialize, infinite number of AMP library instance, and then an infinite number of documents. So lots of overhead to initialize the AMP library over and over and over again for every iframe. But then with Shadow DOM, you just have one window, one library instance that we call Shadow AMP, in the top of the page. And it simply connects to lots of documents and renders them out. So that's a much cleaner flow. And in practice, the PWA hijacks navigation clicks, fetches the requested AMP page, puts the content into that shadow root, and then calls it to Shadow DOM. But this was a slide that showed it just very briefly. I actually want to show it a little bit more in detail because we have a little bit more time today. And in fact, I think you can do this in an hour. This flow of inserting content via the Shadow DOM, if you already have AMP pages, I think you can do an hour. Now, if you don't believe me, let's do it in five minutes. OK? All right. So the first thing that we want to do is, and this is a caveat, we want to have a content source somewhere that serves as the navigation. So in this case, we need to have an overview page from somewhere that has a bunch of links, a bunch of images maybe. In this case, I just used YQL to fetch an RSS feed from somewhere, which is a really nice hack to create a compelling demo, I would say. And this gives me a nice list of articles that I can use. And I used the Guardian as a back end. Thanks again for the Guardian for letting me use the RSS feeds. And so as you can see, this is what I have so far. So this is just using the RSS feeds through YQL. And so far, so good. And this again, this step is not so hard to do. So I shouldn't be saying this, but I started on Monday. And so next one, we add the AMP shadow library to the head of the page in our progressive web app. Now again, this is a special version of AMP. And then we wait until AMP is loaded, which is using this technique that you find a lot of frameworks nowadays. So this is just a wrapper that the code inside this wrapper runs as soon AMP is actually fully loaded. And then when you have that, you fetch the AMP doc via XML HTTP request. And now again, straightforward, you know the link from the previous navigation. You know the link to the full article. You fetch it via XML HTTP request. And then you return something that we call response XML. Now, response XML contains a ready to use document object. Not that well-known feature of XML HTTP request. And I'm not using fetch here because fetch doesn't support this yet. This is why I'm using old school XML HTTP request. So now we have our actual document, our AMP document. It's not rendered anywhere yet. But now at step five, we render it using shadow AMP. So what we do is we create a shadow root. What this means, it's just a fancy way of saying we create a diff, a container, and we give that diff to a shadow root. Now, the AMP doc does all the magic. The attach shadow doc function does all the magic. So we give it the container that we just created. Actually, this should say shadow root. So let's just back on the slide. Then we give it a doc that we just fetched via Ajax. And we give it the original URL. And then in this case, we can also have a function that notifies us a promise when the page is ready and rendered out. Now, that's a basic flow. But there's a few things that make it even better. For instance, if you don't need certain things in the AMP page, because the AMP page usually has its own sidebar, its own navigation, so it can stand alone. But if you don't need that stuff while in embedded mode, you can actually remove those things before you give it to the AMP shadow library. You just remove the header, remove the sidebar, et cetera. So this is actual code from the demo. But also cool, if you don't want to do something as complex, that's cool, too. Because there's a class that we add to the body of the embedded page, which means that you can, in your CSS of your AMP page, you can use the dot AMP shadow page to simply hide things that you don't want in embedded mode. So that works as well. And finally, if you don't want to remove things, but you want to insert things back into the AMP page, features, for instance, like JavaScript highlighting or something like that, into the embed, you can do that as well by using shadow slots. And they provide a path for progressive enhancement of AMP docs when shown in the publisher's own context. So how does this look like in action? Let's have a look. Here we go. So the content experience is now all powered by AMP. As soon as you click on one of those links in the overview, the AMP page renders and loads. And because it's everything in our control, we have the whole document available. We can do some really nifty transitions to animate between those two instead of a full page load. Thank you. Now finally, let's wrap things up. With a progressive web app, with a progressive web AMP, sometimes I also call it plump, because I like the sound of it. It's always fast, no matter what. There's great distribution built in. It's progressively enhanced. It's really just one backend to rule them all and there's less client complexity, fewer deploy targets. And to visualize this last point again, remember how we had this plenty of deploy targets before in our previous slide. Well, in fact, we're now down to just three if we want to. We have that PWA shell, the native shell, and native shell and iOS. And those are just thin layers that serve as the application shell that provide a navigation model and maybe some features on top. But then AMP is the backend that runs it all, the content source. All of those could use AMP as a content source. And so you support the web, you support Android and iOS at the same time with very thin layers of extra code. So finally, a word of caveat. When do you actually do this? Well, you do this when you have a site that has lots of static content, for instance. So you don't want to do it if you built an XGmail, because it's really more like a really dynamic app that doesn't have landing pages, what we call leaf pages that accessed via organic search or social discovery. So your site has to have lots of static content to make sense. And ideally, you already have a large corpus of AMP pages that already gets you through the first step. And it just works extremely handy if your engineering resources are constrained or to reduce infrastructure complexity. And finally, you need to test out, if you haven't done AMP before, you need to test out if your content monetizing works fine within the AMP ecosystem. So before I leave you, and I think I have some time to open the room for questions, I'm going to leave this up for a second so you can take some screenshots. So we have a React sample app as well. That's not the one that you saw today, but it uses React, so it's great for millennials. So use the React sample apps to see how you do it in React. It has similar nice transitions. We just launched the AMP channel.  And AMP project.org, we just published a big new guide about all of these patterns that I just talked about. If you want to recap all of those things and go through the tutorials, you can do that now on AMP project.org. With that, I'm going to open for questions. Thank you, everyone. And we'll see you next time. I'm Sarah from the Google Developer Certification Team. Last year, we launched the Associate Android Developer Certification at I.O. Now we're adding two certifications for mobile web developers. Why mobile? Mobile now accounts for over half of all web traffic. Users expect their small screen experiences to be as quick and intuitive as those on a desktop. But making the mobile web fast and easy takes some special skills. How can you prove you've learned them? We've created two new certifications to help developers get recognized for their knowledge and skill, introducing the mobile site certification and the mobile web specialist certification. One focuses on sites and the other on web apps. Let's talk about mobile sites. What happens to your beautiful site if it takes too long to load? 53% of mobile visitors will leave a page if it takes more than three seconds to load. But the average mobile page loads in 22 seconds. Making this even one second faster increases conversion rates up to 27%. Google believes in the mobile web. And so do our customers. That's why we've created the Google mobile site certification to help site owners find the best talent. Passing this exam demonstrates you have the knowledge for building high-performing mobile sites. It also highlights your understanding of best practices and current browser technologies. To pass, you'll need to be proficient across mobile site design, UX best practices, and site speed optimization. This certification is especially useful for developers working in-house for agencies or clients. To prepare, use the online study guide or eLearning course. Both are free. Once certified, you can promote your certificate on your Google partner's public profile and social media. What if you're developing mobile web apps? Developing applications requires even more specialized skills than sites, so we have a certification for that. The mobile web specialist certification shows you can build quality web apps, including progressive web apps. You take this exam by solving a series of coding problems. We'll test your skills in many in-demand areas, including responsive design, accessibility, and progressive web application development. This certification is especially useful for developers looking to move up in their careers. It will prepare you to tackle a wide range of challenges. We also provide a study guide and a range of courses to help you prepare. With multiple certifications, how do you know which one to take? Are you building mobile sites and need to demonstrate you have the knowledge to do it? Take the mobile site certification exam. Need to show that you have the skills to build a mobile web app? Take the mobile web specialist exam. Visit our certification page under the Google Developers website to learn more about our programs. Get the study guides, get ready, and let's go. We're bringing together a really talented group of designers and developers to collaborate and innovate and generate exciting ideas for what can be done on the Android platform. Within this context of a sprint, I really think that the distinction between designer and developer is blurred. It's all about problem solving and getting it done. You're not working with designers as an engineer making a mistake to begin with. I feel like every designer engineer brings a perspective to a project. And that's what's nice about working with a designer. You think like an engineer and designer comes and brings a perspective. In this group, I'm happy to work with super talented designers. It helps me understand Android better because I see how they're thinking about it. It kind of kills my prejudgements about the product and I start thinking about it from a fresh perspective. We focus in on generating a broad range of ideas that are really innovative and far reaching and then prototype and pull together concepts and prototypes to demonstrate and create a vision for what those concepts could be. I never was really familiar with the idea of using this type of process for ideation. And it's impressive to see the degree of precision that Kai specifically has introduced and in the way that she's run this process, it's been really enjoyable to see specifically how one exercise leads into the next and the next and the next and how that can actually effectively yield good ideas. We're a very small company so effectively we're doing similar things all the time but we often rush straight to the solution. It was nice to see some structure around, I guess, the process. So, you know, it starts here and you don't get to fix it straight away.  And that kind of structure, though it seems kind of burdensome, like it actually improved like the overall thing we came up with. When you're in a company, you tend to think about how the company kind of does something and how the things that you've learned in the past and then here is just kind of like a blank canvas again and you get to start new and then rediscover the things that kind of work in a workflow or in a much more creative space. I mean, here we try to build something in three days, which is insane. This is the first time we actually been in a sprint with just doing Android 2 and I would love to bring some more of the Android sprinting back to our company. I think design sprints facilitate interdisciplinarity, interoperability and all of the kind of amazing things that can happen from a good collaboration. One of the really exciting features of Android is that it's a very open platform. Anyone can come and write their own apps and create their own concepts. We want to bring that opportunity of openness to the design community and inspire designers to generate concepts and ideas and design really cool apps that leverage the openness of the platform. I was impressed with the openness of Android. It's definitely a unique thing that you might not find on iOS or other systems. In our app in particular, there's things that we definitely couldn't have done on iOS that are actually really useful and it is nice because the app can organically come with you into the rest of your life. I think for me, one of the big awesome parts of it was that I was able to begin to learn Android which is something that I've always wanted to do as a prototyper. I just would like to get to know Android better and this is like a really big jump start. One of the few constraints that they put on us here at the Design Sprint was like to sort of like come up with something that's like unique to the Android ecosystem. And as we were going through all of our crazy-ates and all of the myriad ideas that we had come up with, we actually abandoned some of them that were cool because they were kind of like something that could feasibly be built on any platform. And I think that giving us that constraint infused our other ideas with more creative solutions and I think what we came up with is like so simple and so delightful and only available on Android. Developing a successful app isn't easy. To reach a broad audience, you'll need to consider your iOS, Android and mobile web users. And to build for these platforms, you'll need a backend server to store data and support the apps. Of course, you want to get your users logged in, hopefully lots of users, which means your backend will have to scale. Then after you've solved your scaling problems, you'll have to find more ways to spread the word to get new users. But have you found a way to measure all this activity? And oh no, your app is crashing and causing servers to melt down and you haven't even made a dime yet. Don't you wish this could be easier? This is why we built Firebase. It has all the tools you need to build a successful app. It helps you reach new users, keep them engaged, scale up to meet that demand in addition to getting paid. From the beginning with Firebase, you'll have Test Lab and Crash Reporting to prevent and diagnose errors in your app. Your backend infrastructure problems are solved with our real-time database, file storage and hosting solutions. Acquiring new users is easy with invites, add words and dynamic links. And using the authentication component, you can get those users logged in with minimal friction. Once installed, you can keep your users engaged with notifications, cloud messaging and app enhancing. Then with Remote Config, you'll have the freedom to experiment with new features and optimize the user experience in real time. And of course, you can earn money with the same AdMob component that's been monetizing great apps for years. Last, but certainly not least, our all new analytics component designed uniquely for Firebase brings insight into how well these components are working for you and your users. With Firebase Analytics, you can measure and optimize your advertising campaigns, discover who are your most valuable users and understand exactly how they are using your app. Now, all these components work great on their own and provide a solid infrastructure to build out your app, but they work even better when combined in creative ways. So let Firebase handle the details of your app's backend infrastructure, user engagement and monetization, while you spend more time building the apps your users will love. To get started right now with Firebase on Android, iOS or the web, follow these links for more information. Then, to manage and monitor your apps connected to Firebase, there's a web console to view crashes, setup experiments, track analytics, and a whole lot more. And to learn more about Firebase and all of its components, you can read the documentation right here. We can't wait to see what you build. We have with us, Aparna Shridhar, who is a product manager at HackerRank. There are so many people who really look up to you. What really inspired you into technology? I started writing my first program when I was, say, in sixth standard. Just playing around with basic back in the days when we had dial-up connection and when I decided what to do for undergraduate studies. That's when I had the option to, again, pick computer science. And at that point in time, I dated back to this enjoyable experience I had as a child and thought maybe I would give that a try. Tell us about your experience as lead coach for the Udaa City Android Nano degree. Something that I would like to highlight about teaching is that it's been like the most fulfilling and gratifying experience. Can I help that one student who almost wants to give up on programming, who almost feels like this experience is too hard, if I can help that one person at a time progress? I feel like later in their life, sometimes they would look back to do it for somebody else again. What is your message to the women in tech out there? We undergo a lot of stereotypes. I cannot tell you the number of times I'm the only woman in the room and automatically the question is, are you in sales, are you in marketing? The more women can do to break that stereotype to embrace more of these roles, the more we can change this perspective that we do have in tech. Thank you so much, Aparna. Welcome. This is our first certification summit. You guys and ladies are among the first certified Android developers. The developer base growing very fast, going and becoming the largest developer base in the world. The interesting point is that India is a mobile first market, however the percentage of developers developing for mobile is relatively low. So we're trying to really supercharge that. India is one of the emerging markets. 80% of the smartphone growth rate is expected till 2019.  They are not trying to solve for the entire world. They're trying to solve for their own users. You are at the end of the day developing a product, not for yourself. You're developing for an consumer. I'm going to talk to you guys about what's new with Android O. Any of you guys use some of the Fireboy's 2.0 features? Yes, it's about recognition, it's about getting a job, it's about growing your career, but there are bigger forces at play. I feel that development, mobile development, Android can make a difference actually in the world, fixing problems in one's own community, whether it's water, education, environment. But we want to support you connecting to communities and trade change in the world. Firebase makes authentication easy for end users and developers. Most applications need to know the identity of the user so they can provide a customized experience and keep their data secure. Firebase supports lots of different ways for your users to authenticate. If your users want to authenticate with their email address, you can build that for them. Firebase Off has built-in functionality for third-party providers such as Facebook, Twitter, GitHub, and Google. It can also integrate with your existing account system if you have one. You're given the choice about how to present login to the user. You can build your own interface or you can take advantage of our open-source UI which is fully customizable and incorporates years of Google's experience in building simple sign-in UX. No matter which one you use, once a user authenticates, three things happen. Information about the user is returned to the device via callbacks. This allows you to personalize your app's user experience for that specific user. The user information contains a unique ID which is guaranteed to be distinct across all providers, never changing for a specific authenticated user. This unique ID is used to identify your user and what parts of your backend system they're authorized to access. Firebase will also manage your user's session so that users will remain logged in after the browser or application restarts. And of course, it works on Android, iOS, and the web. That's Firebase Off, allowing you to focus on your users and not the sign-in infrastructure to support them. Thank you for joining us for today. India is coming along the way as I just mentioned. Today, India is the second largest country in the world in terms of number of developers. Soon, it's going to be number one. What we want to invest in is actually training the faculty from your colleges. The potential is so great and what Google is doing to help catalyze that innovation is it's really an exciting time for these campuses. We are really trying to provide the best possible experience to teachers in these faculty hubs because the first step to training 2 million developers is to train the teachers that are going to teach those 2 million. Industry, as of now, demands a lot of updated curriculum, developing 2 million Android developers. Being working in a technical university, we can contribute hugely on developing those million app developers. So we're excited that all the raw materials are there to create an innovation revolution in India. I really think the students are going to make some great things and I can't wait to see what comes out. There's a lot of potential in India and we need to take it forward. With Google, we can provide rich opportunities to all. That is the essence of Google program, which I have seen. This is a good move and this program will definitely be useful to the students because app development is going to rule the world for the next few years, really. Just waiting for the shot to finish. Okay, there we are. So I'm here with Daniel in the Community Lounge where people from all over the world are gathering at Google I.O. Can you tell us a little bit about the activities going on here and what people are saying? Yeah, the lounge is pretty new on the I.O. Like we used to have community areas on the I.O. But nothing huge like this. I don't know if the camera can capture it but this is basically like the whole tent, like the front porch of it. And as you can see, it's crowded and people come here to chill, to play. They play pool. We have some wooden block building games. We've got some networking games, people chatting. You don't hear me saying we have any gadgets here. This is completely unplugged. And like people here maybe come to relax a little bit from all the technology which happens in the tents everywhere else. And they just sit back and relax and talk to other people. So we are the place sort of maybe to unplug from the technology for a little bit. We also have some local meetups. So I am with GDGs. I'm in the community team in Google. So we help communities around the world to do meetups. So we thought, why don't we do meetups here? So we have about 25 small meetups and it's anything for like people who did applications for social good. Or just now, I think there is a meetup of Russian speaking developers. So we have the hallways. They come here, they meet. It's very unprogrammed, very anarchistic in a way.  I love it. I hope we do it next year. And when you come next year, make sure you're to buy. Awesome. Well, let's check out some of the stuff. Awesome. Let's go. So this IO17 hello world hashtag. Hashtag IO17 hashtag hello world. You can actually check it right now if you are bored with my face. And what happens is that we are building a bridge here. But communities, they don't function with a boss or blueprint, et cetera. So this experiment is about what happens if we want to construct maybe the next golden gate without blueprints or managers. You see, it's pretty chaotic, yeah? Timothy, I know like we are not golden gate bridge quality yet, maybe we will not be ever. As I said, this is an experiment. We are on day one. So we'll see how it goes. We also ask people to, if there are developers, to write hello world in their first programming language. So I hit mine here, like 10 print hello world in basic. I was very tempted to say 20, go to 10, you know, and see the wooden blocks being covered everywhere here. So we can see if plenty of languages here. So yeah, let's see what happened. All right, so Timothy, I know I said the launch is unplugged, but this is a, I was cheating. This is an exception. Like as you can see, this is very much plugged in. But what we are playing here is something that I want to tell you informally. We are not publishing. This is a YouTube playlist of some of the greatest GDG trailers and videos from around the world. Google Developer Groups, they organize meetups, events, activities, and they sometimes put crazy videos online. So we made like a two hour playlist out of that. You can find this whole screen on your own screen if you enter the address bit.ly slash launch TV. I'm not saying don't say it to anyone because I just said it to you, but you can be here with us at least virtually through this playlist. So enjoy. Cool. So what is this? Yeah, you had seen the movie Inception, right? And in the keynote in the morning today, you were talking about the inception. So this is a device. I don't know what for, I don't know what it will do to you. I mean, if people want to see more videos of you, I don't know if you want to see the name, but. Let's try it. This is a core workout. It's kind of like planking, but better. You can get a hangover from this. All right. So let me introduce Nino. Nino is from Georgia and she's running one of the meetups I was talking about. And this meetup is, what is it about Nino? Who is it for? This meetup is for developers mostly and we cover the topics of how we can develop apps or use current apps for social good. So basically the social aspects that our apps can have because technologists have so many opportunities and it can really go beyond just consumerism, right? It can serve so much more purposes. So I'm going to be sharing my own experience, how my team at Elva Instructor are helping to help people in conflict and crisis situations to better monitor situations or how you are helping farmers with information and probably get some more ideas from others. So it is very informal, very improvised because everyone is in the line for ice cream. So I hope that someone joins and it's going to be just a friendly session and thanks to Dan for this opportunity. I think it's fun and cool. So do develop apps for social good. Awesome, thank you. So you're welcome to join. Hello, everyone. I welcome you all in the center of development fundamentals. An app is basically a solution or a medium by which you get a solution to a lot more users. You have to figure out what kind of benefit the person is going to get by using an app. I feel personally, the phone is not a phone. It is something that can change people's life. With Google, we can provide rich opportunities to all. That is the essence of Google program. There's a lot of potential in Google. There's a lot of potential in India. And we need to take it forward. To get everyone to start thinking about Android and developing for Android, we're at the Cusp of a Revolution. We encourage you to continue learning, continue developing, and now go build some great apps. You have the talent and that is the need. Bring it on. Now it's time to learn about all the new cool stuff with Google Play Console and I'm here with Matt to tell us all about it. Hey everybody, we're super excited to be here. I.O. is a big moment for us with the Play Console because we're all about developers. As you probably know, the Play Console is what developers use to publish their apps to Android devices through the Play Store. And what we've seen is over the years we've gone from a Play Console, which was simply about getting an app from A to B from the developer to the end consumer's phone. Now it's so much more. There's really a hugely diverse set of tools that enable developers to be more successful with their app. And what we've found is that the user base has diversified as well. In addition to our core audience of Android developers, we have product managers, marketing managers, many other users wearing different hats in the organization are starting to use the tool. At I.O. this year, we're announcing a whole new set of features as well as updates to some of our popular existing features. In some cases, these features are helping apps to be higher quality. And so we're launching Android Vitals, which is a whole new set of reporting about bad experiences on the Android device. So these are a user experience where your app may be crashing or your app may be rendering in a slow way or you may have excessive wake ups, stuck wake locks that are causing excessive drainage on batteries. So we're going to start revealing that reporting to developers that can help them to debug, understand more about optimizing their app for the variety of devices that are out there. And that's one of many different new features we're launching. Another one, actually you can see on the screen behind me, is the device catalog. So Android's diverse ecosystem has been a tremendous strength, the source of the scale of the two billion Android devices that are out there now. But that diverse ecosystem can also be hard to navigate and understand for developers until now because the device catalog is a much easier way to browse the more than a thousand different Android certified devices. You can search and explore these devices by spec like RAM, like System on Chip and you can then see a reporting information about the number of installs your app has on that particular device or on that group of devices, how much revenue you're getting, how your ratings compare, which can really help you to understand whether any of the bad behaviors, any of these problems that users may be having with your app are concentrated in a particular area which can be critical to optimizing and making your app super high quality. So we're finding even just in the initial testing which we've now completed, this feature is rolling out to all developers. We found out early testers have really embraced these tools, it's really helping them to be much more surgical in the way they think about targeting their app and making it a great experience for the end user. In addition to the features that help developers to build higher quality apps, we've also got a number of features which help to mitigate risk during the release process. And so when you're releasing a new version of your app, you may have an installed base of millions, potentially hundreds of millions of users. If you're pushing out a new version of your app, you can otherwise be a worrying time. You don't wanna know that bugs are causing uninstalls. You don't wanna know that information late. So we have a new release dashboard with very low latency reporting that helps you to have visibility of these metrics. On the hour, every hour as it's starting to roll out to potentially global audience of hundreds of millions of devices. And so this can help you to manage your release with a lot more confidence. A third area where we're launching new features right here at IO is in the business area. And so developers, in addition to building amazing experiences, they wanna make money, they wanna grow their business. We have a lot of new reporting, including for app developers that have a subscription based model. You can look at subscription by tenure, look at cohorts from when they've started, when they've installed the app, and how that life cycle trends over time. You can help to see how different inflection points are contributing to subscription renewals or people leaving a subscription. So it can really help you to manage your subscription business. And then in general, we have a lot of statistics that are available through the Play Console. In the past, they weren't always easily navigable. We have a new configurable page. App developers are much more easily able to slice and dice these metrics, much more easily able to create custom configurations, to compare different time periods against each other, to compare one metric against another, and to introduce benchmarks of whole classes of apps so they can see how some of them compares to peers who make similar apps. And so we think that features like this will really help developers to manage their apps as a business as well. Wow, that was a lot of stuff. Thank you so much, Matt. Thank you. Hello, thank you for coming. I'm Martin Wick. I'll speak about effective TensorFlow non-experts. I'll later introduce Francois who will take the second half of the talk. So, TensorFlow, why? So, I have a son. You'll see him later in the talk, actually. And when I used to explain to him how image search works, I would have to say something like, oh, he has a computer, it looks at the metadata, and it looks where the images are. And now, when I explain how this works, I can just say, well, the computer looks at the images. And if you search for, say, Cherry Blossom, it looks at the images, all of them, in the world. And whenever it sees one that has Cherry Blossom, then it returns it. It's a much better story. And you've seen a lot of this particular event. AI is now going to be everywhere. And machine learning is everywhere. And it generates these products that were impossible to imagine before. What makes these products work in reality is, for us at least, TensorFlow. And this enables us to make these apps and make these products that use machine learning. And once you've written one of these models, one of these machine learning systems in TensorFlow, you can deploy it anywhere, mobile. TensorFlow is truly what enables apps that tell hot dogs from not hot dogs. So why don't we see that more? Why is it why are hot dogs not hot apps so cutting edge? The main reason is complexity. And complexity is in various shapes. So first of all, complexity is computational complexity. Computational complexity used to be a big thing. And now with cloud and with all the availability of data centers that you can rent, that's really not much of an excuse anymore. So we've solved this problem, assuming your code can run in a data center. But you also have to contend with, you have to make your code, your models, your apps, work on all these different platforms. In order to train them in a data center, you work on CPUs and GPUs. You probably have heard by now we have this thing called a TPU. It should work there too, because that's going to be fast. And of course, if you want to deploy it, once you're done, it needs to work on a mobile device. If you're into IoT or embedded systems, it has to work there too, say on an Raspberry Pi or something like that. So making that happen is hard. And finally, machine learning itself is actually fairly complex. So that's why we have TensorFlow. And TensorFlow gives you distribution out of the box so that you can run it in the cloud if you need to do that. It works on all of the hardware you need to work on. And it's fast, and it's flexible. And what I'm going to tell you today is that it's also super easy to get started. And that's why we're here. So TensorFlow takes all the details of a distributed system in their various hardware and just hides them from you, takes care of them. You don't have to know about it necessarily. It's nice if you do, but if you don't, that's not a problem. What you mostly see is the front-end. And what I'm going to talk about today is the Python front-end. The generic thing that people used to say, oh, this is TensorFlow, it's pretty low level. So you're thinking about multiplying matrices, adding vectors together, that kind of thing. What we built on top of that is libraries that help you do more complex things easier. We built a library of layers that help you build models. And TensorFlow is going to talk more about that. We built training infrastructure that helps you actually train a model and evaluate a model and put it in production. And again, this can you can do with carers or you can do with estimators, and as well as going to talk about carers. And finally, we built models in a box. And those are really full, complete, machine learning algorithms that just run. And all you have to do is instantiate one and go. That's mostly what I'm going to talk about today. So usually when you talk about, oh, my first model in TensorFlow, it's usually something simple. Like, let's fit a line to a bunch of points or something like that. But nobody is actually interested in finding a line to a bunch of points distributed. Doesn't really happen all that much in reality. So when I'm going to do that, I'm going to show you instead how to handle a variety of features and then train and evaluate different types of models, possibly distributed. And we do that on a data set of cars because we have that. I have uploaded all the code I'm going to show you to this address, which has both an O and a 0, so be a little careful. And what I've done there, it'll work with TensorFlow 1.2. And I am not sure whether it's been announced previously, but there is now TensorFlow 1.2, the first release candidate. So my code will work with that and nothing earlier. So you have to watch out. All right, so the first model today will be about predicting the price of a car from a bunch of features about the car, information about the car. Right, so without anything more, let's just do code. Whereas the talk is going to be code mostly. This is it. This is my model definition in TensorFlow. I'm exaggerating only a little bit because this only takes into account three different things. So first here, we define the input. And I'm defining three different what we call feature columns. I'm telling the model that it should expect an input that is a categorical feature, a string that's called make in the input. And I'm going to transform this into something that's usable by my machine learning algorithm by hashing it. So I declare it this way, a declarative way of telling you what to do with the feature for the inputs. The next thing is I'm going to say, oh, there's something called horsepower, and that's just a number. So I call it numerical column. And then there is something called num of cylinders in the input. And that's also a string, but it has very few values. So I'm just going to give you all the values directly here in the code. So in this data set, it actually is the case that num of cylinders is encoded as the words 2, 3, 4, 6, and 8, I think. So that's it. So there's probably many more of these. But in principle, that's what you do. And you say, OK, this is what my input looks like. And then we specify what kind of machine learning algorithm we want to apply to this. And in my case here, I'm going to use first a linear aggressor, which is kind of the simplest way to learn something. And all I have to do is tell them, hey, look, you're going to use these input features that I've just declared. That's it. And I'm done. Now, I still have to give it some input data. Intensive flow has off-the-shelf input pipeline for most formats, or for many formats. In particular here, in this example, I'm using input from pandas. So I don't know who knows pandas. It's a Python library.  It's nice. So I'm going to read input from a pandas data frame. And really, what I'm telling it here is I want to use the batches of 64. So each iteration of the algorithm will use 64 input data pieces. I'm going to shuffle the input, which is always a good thing to do when you're training. Please always shuffle the input. And num epochs equals none means cycle through the data indefinitely. If you're done with the data, just do it again. And then I can say, OK, train me my thing for 10,000 steps, say. And what happens then is that TensorFlow goes off and trains my thing. This is what the logout looks like. Actually, any interesting information for it. What's more interesting is that TensorFlow will also integrate with other tools that we have. In particular, it'll integrate with something called TensorBoard. TensorBoard is this wonderful front end that the training system writes data for. And then you can visualize it, and you can look into it. And one of the things that you can see, what I show here, is what's called the loss curve. Loss curve is kind of the most important thing to look at if you're trying to train a model. And what you see here is that our loss, that is kind of the error that the model makes when looking at data, is decreasing over time. And that means it's learning something, plain and simple. So good. That's good. The model is learning something. Great. The next thing I can do with TensorBoard is I can actually look at the model that was created and look at the lower levels of the model, look at what we call the graph. TensorFlow works by generating a graph, and then this graph is shipped to all of the distributed workers that it has, and it's executed there. You don't have to worry about this too much, but it's awfully useful to be able to inspect this graph when you're doing debugging or something like that. So here is the graph that was generated by the model declaration that I showed earlier. And I've highlighted in red here the part that's the actual model. That's the actual linear model. I can look inside of it. And you can see that there are these slightly yellow boxes, and those are the input processing computations that happen in this model.  So what's going on? The linear aggressor I defined is what we call an estimator. We inherited that estimator word from scikit-learn, and it's kind of this very, very similar concept. It supports all the basic operations that you need for an ML model. You can train it. You can evaluate it, usually on separate data. If you take away anything from this talk, it's that you should always evaluate your models on separate data while you're training or during your training. You can query the model for predictions once you've trained it, and then this is fancy. You can export what we call a saved model and give it to TensorFlow Serving. There's a talk about TensorFlow Serving tomorrow in the amphitheater at 1.30, and you should all go to it. So these methods all hide a lot of tricky details that you don't have to worry about and that are just done. You can just call them, and you can be reasonably certain that it actually works. We also defined an input function earlier, and that basically reads from data files and feeds data in an appropriate format into the estimator itself. There's a trick here. The estimator actually saves its state to what's called a checkpoint. The checkpoint contains all of the variables that the model contains, and every time we call one of these functions, it'll synchronize with the checkpoint. And this is very important for the distributed setting, where you have several machines and they all do their own thing, but they have to synchronize and they synchronize when something restarts or when something breaks. They synchronize via a checkpoint. This is also, the checkpoint is also what we use to export the saved model. OK, so it's great. So I've shown you how to train a linear model with Panda's input, but what if you want something else? Just anything else, really. Well, so all of these components are obviously swappable. So for instance, the Panda's input function, you can swap for other input functions. We have several that are just there. It's also pretty easy to write your own, so you can read from NumPy. You can read from any Python generator. Anything you can put out, like anything you could spit out of a generator, you can use. So this makes it very, very flexible. And you can write your own input function, too. It's not that hard. Also, the models that we have are not limited to just linear models. So we have linear regressor classifier. We have a deep neural network, which is a basic straightforward neural network, basic feed forward neural network. And then we also have estimators that do random forest, k-means, support vector machines, you name it. So all of this is available directly for use, so you don't have to implement it yourself. Let's say we want to swap this out. So first of all, we have to obviously change the name of the class that we're using. And then we'll also have to adapt the inputs to something that this new model can use. So in this case, a DNN model can't use these categorical features directly. We have to do something to it. And the two things that you can do to a categorical feature, typically, to make it work with a deep neural network is you either embed it or you transform it to what's called a one-hot or an indicator. So we do this by simply saying, hey, make me out of the make, make me an embedding, and out of the cylinders, make it an indicator column, because there's not so many values there. Usually, this is fairly complicated stuff, and you have to write a lot of code, but this is it.  Then also, most of these more complicated models have hyperparameters. And in this case, the DNN, basically, we tell it, hey, make me a three-layer neural network with layer sizes 50, 30, and 10. And that's all really you need to this very high-level interface. So for other models that can be more complicated or less, depending. And if none of this works for you, you can still take advantage of the training loops and all of the infrastructure that is in the estimator itself, and you can completely swap out the model and write your own. And the way you do this is we have this estimator base class, and you can put in what's called a model function. And this allows you maximum flexibility. The model function takes the inputs, and it produces tensors that contain the thing that you have to do for training, the thing that they have to do for evaluation. It returns the predictions, and then it'll also produce a safe model if you need one. So you can write all of this yourself if you really want to if none of the preexisting models fit for your use case. And you can use any kind of, you can use regular TensorFlow to define this model function, or you can use Keras, and Francois will say a little bit about that. So the exciting thing about TensorFlow is actually the fact that it runs not only in a single machine, but distributed in a data center. So to make this work, we have a utility that uses several workers and basically trains the model on all of these workers at once. We call a distributed training run, like a single run of training a model, an experiment. And to make one of those, we first make an estimator, as you've seen before, and then we add the input function and the estimator together and make an experiment. The name experiment comes from hyperparameter tuning, and I don't know how many of you are familiar with hyperparameter tuning. It's a very important concept in machine learning. Basically, instead of just training a single model for your data, you train a whole class of models and you pick the best one. And it's very powerful. And I'm not going to go into details on this, but the infrastructure for it is all set up. So you can, in the experiment function that makes the experiment, you can pass in hyperparameters, and then you can use those hyperparameters to create your estimator, and then you return that estimator with the experiment, that way you can implement hyperparameter tuning. Well, finally, this experiment, this function that makes an experiment, we pass to what we call the learn runner, which just runs it. And if we can pass some user options in a run config, what the run config also does, it contains information about the cluster that we run it on. And so we can use that information, for instance, if we make the estimator want to tweak it, depending on how many machines we have available or something like that, we can do that. So it contains information, how many workers do we have, how many parameter servers do we have, and so on. But the run config also takes information from the environment, and so we don't have to pass it explicitly. So what do we have to do in order to declare to TensorFlow, hey, here's a cluster. Please use the whole cluster as we write what's called the cluster spec. And it is a very, very simple thing. It's just simply a map from names of different machine types that we'd want to do different things and then a list of all the machines that can do this thing. And usually, you have parameter servers or PS, and you have workers. And the parameter servers store the variables, the workers do the actual work. That's kind of traditional, and you just fill out these lists, and you're done. And you save that, you dump that into the second thing here, you dump that into an environment variable, and then everything else will work from there. OK, setting up a cluster depends on the environment, and I'm not going to talk in detail about it. But if you are interested, it's on GitHub in the ecosystem repo. There's a number of scripts and a number of examples that help you get started. So one thing I'd like to mention, and I don't know how many of you have seen the TPU talks, this is a part of TPUs. If you stick to these concepts, your code will basically work on a TPU without modifications. So you will be able to use this once you can use it. So what I've shown you is we have intensive flow implementations of complete machine learning models. You can get started on them extremely quickly. They come with all of the integrations with TensorBoard, visualization, for serving and production, for different hardware, different use cases. They obviously work in distributed settings. We use them in data centers. You can use them on your home computer network, if that's what you like. You can use them in flocks of mobile devices. Everything is possible. And they run on all kinds of different hardware. Particularly, they will run on TPU, which is nice. They also always run on TPU and CPU, obviously. OK, so before we move on, the full code, again, is at this URL. If you're interested in more, do check out the tutorials on TensorFlow.org, and particularly the estimator tutorial. I think that maybe the most interesting for people who want to do right their own estimators. And then do go to the talk tomorrow at 1.30 in the amphitheater for TensorFlow serving with Nola. And with that, thank you very much. And I'll hand over to François. I'll tell you more. Thank you. Thank you, Martin. So canned estimators are great for many use cases. But what if you need something that's not available as a canned estimator? What if you need to write your own custom model? That's where the Keras API comes in. The Keras API is this high-level API for building TensorFlow models. And you can use it together with the estimator class and the experiment class that Martin introduced. As you know, TensorFlow features this fairly low-level programming interface, where you spend most of your time multiplying matrices and vectors. And that's very powerful. But that's also not ideal for building very advanced complex models. So we really believe that in the future, deep learning will be part of the toolbox of every developer, not just machine learning experts. Because everyone needs intelligent applications. And to make this future possible, we need to make deep learning really easy to use. We need to make available tools that are accessible to anyone. Because you shouldn't need to be an expert in order to start leveraging deep learning to solve big problems. So if you could design a deep learning interface without any constraints, what would an ideal interface look like? I really think that the core building blocks of deep learning are all fairly well understood. And rather than letting the user implement everything themselves, instead, it should be really easy to just take existing building blocks and be able to quickly assemble them to build new deep learning data processing pipelines. It should be basically like playing like it works. And I think actually, if you think about LEGO bricks, it's the ideal metaphor. LEGO bricks are very intuitive to use. They're very easy to use. They provide this very flexible, expressive framework in which you can build almost anything. They allow you to try different things very quickly and immediately get visual tactile feedback about what works and what doesn't work. And of course, LEGO bricks are very accessible. They're accessible to any human being, as is found above. And that's really the idea, the ideal, I would say, that we had in mind when we designed the Keras API. We wanted to be the LEGO for deep learning. So let's take a look at what Keras can do. So first of all, I think it's better to think about Keras not as a code base, an API framework or a library. It's just a high level API specification. And it's a spec that has several different implementations. The main one, of course, is a TensorFlow implementation. But there's also an implementation for Tiano. There's one for MXNet. There's one for Java. And there are more coming. And what makes Keras different from every other deep learning interface that's available is its deep focus on user experience. Keras is all about making your life easier, simplifying your workflow, especially in terms of providing easy to use, building blocks, intuitive affordan