Develop Chrome Apps on desktop/mobile, distribute and profit – Chrome Dev Summit 2013 (Joe Marini)

MALE SPEAKER: OK. So I was going on about the
offline first stuff earlier. But there’s somewhere
where this has been happening for
years in Chrome apps. They’ve been providing
privileged APIs and sort of showing the open web and
what it could be in the future. And to talk about that, a
warm welcome to Joe Marini. [APPLAUSE] JOE MARINI: All right. Hi, everybody. All right. Mic on? You guys can hear me OK? Yeah? All right. How’s everyone feeling? AUDIENCE: Woo! JOE MARINI: Good? I know. It’s 5 o’clock. I know. You can see I’ve used my extreme
clout as a Google speaker to secure the highly
sought after 5PM slot. I appreciate you guys
sticking around, though. Yeah. I’m going to be talking
about Chrome apps today. A couple things. First of all, I’m going
to try to speak slowly. I am a New Yorker. That does not come easy to
me, but I’ll give it a shot. Second thing, please
keep your arms and legs next to your seat at all
times until the presentation’s come to a full
and complete stop. And then we’ll go
into– we’ll do PNaCl, and then we’ll have some beers. Just before I get
started, how many people have heard of Chrome
packaged apps before today? Wow, everybody. That’s fantastic. All right. How many people have gone
to the Chrome Web Store to get content,
extensions, apps, whatever? All right. Just about everybody. That’s awesome. How about you guys
in the live stream? Yeah? I’m imagining hands going up. I’m imagining it’s a good thing. Awesome, great. OK, that’s good. This is me. I’m Developer Relations
here at Chrome on the Chrome team for Chrome
apps, extensions, Chrome Web Store. That’s my contact info. Please feel free to
reach out and say hi. I am friendly. I will respond usually nicely. Please feel free
to ask questions. I love getting questions. So before I would begin,
I figured three slides in, it’s always useful to do demos,
because I think demos really resonate more than just
pictures on a slide. So let me just quickly
show you a couple demos. We’ve been at Chrome
Apps for a while now. This is “The Economist” app. You may have seen this. So you can go to the Chrome
Web Store and get this today. It’s basically an app. You notice right away
there’s no URL bar, there’s no Back button, right? On the Mac here, there’s
an actual real Menu bar. I can choose a story, I
can keyboard through it. It’s got some nice
performance there. What else? Let me show you something else. Here is an Internet
Relay Chat client that we built using Chrome apps. Again, all HTML5,
all JavaScript. You guys are probably wondering
what this red light down here is. I was going to show this
later, but I might as well show it now. So Chrome apps have the ability
to work with the hardware platform. So what I’m going
to do is I’m going to jump over to this little
sub-network I have set up. And I’m going to come
over to this demo. Philips makes these light
bulbs that you can actually attach to the
internet in your house and just control them with
your smartphone and stuff. So you can see that as I’m
changing the dials here on my Chrome app, I’m
actually changing the color. I know, ooh, ah. [APPLAUSE] JOE MARINI: Isn’t that cool? Native apps, my friends,
in HTML5 and JavaScript. But I think probably
one of the best demos of all– how many
people use Sublime? Sublime Text users? Awesome. Yes. Watch. This is really cool. So I’m going to fire
up Sublime Text. All right. And here’ my Sublime editor. I’m going to size
it down a little bit if I can use my mouse. There we go. So there’s Sublime right there. Just make it a
little bit smaller. All right. And I’m going to go over here. Whoops. And I’m going to
launch this– whoops. I’m going to launch
this other app called Caret, which is a Chrome app. It was built by a guy
in his spare time, and it’s available on the
Chrome Web Store today. And I’ve got the two windows. All right. And I’m going to go ahead
and add a directory. Why not? Sure, that one. That looks great. OK. Which one’s the Chrome app? Which one’s the native app? Right? Pretty good, huh? I mean, this is
HTML5 and JavaScript. It’s just fantastic stuff. All right. I’m not good enough
with the mouse to do the three-card monte. Otherwise, I’d spin
them around and ask you to pick which one was
which, but I’m actually not going to do that. All right. Let’s go back to
the– all right. Of course, the question–
that all looks great, and it performs well. You could see that
we can do cool stuff. But still, you might
have this question, like, why would I
build a Chrome app? Why would I build a native
app when the web is so great? And the web is great. We don’t disagree. We’re Google. We love the web. Web apps are fantastic. There’s lots of great
web apps out there today, and they’ve been
around for a long time. The problem is that there
comes a time when web apps just really aren’t all that great. There comes a time when
web apps are decidedly not quite so awesome. Offline is one of them. We’ve all seen this, right? You’re trying to
use the browser, and you lose the internet
connection for some reason, and you get this
nice, white screen. Native apps don’t do this. The internet may come
and go, but they’re not doing this white
error screens for you. Games, right? We all play games. Well, not everybody. But I play games on the web. Web games are great. You got this full keyboard,
this accurate pointing device. But there are times when
games are just not as great. Wouldn’t it be awesome if
you could give your users the ability to use real hardware
controllers and game sticks and so on to play games with? This is really hard
to do on the Open web. There’s some APIs that you
can use for accessing the game controller API, but not
everybody supports it. And not all of them
work, and so on. So there are definitely
some problems among others. See, these are two of
the more important ones. So Chrome apps are intended
to help solve this problem. They run offline by default. They’re basically
designed by default to run when there is
no internet connection. Because all the resources
are packaged locally like a regular native app. So offline is a very big
pillar of how Chrome apps work. They also run across all
the popular platforms. Out of the box, by default,
it’s HTML5 and JavaScript. You get Mac, Windows,
Linux, Chrome OS, which is kind of like
Linux, iOS, and Android. Just out of the box–
HTML5 and JavaScript. And I’ll get into that later. I just showed a
couple of minutes ago that you have access
to the native hardware platform and the native OS. So you can do things
like access the USB port, Bluetooth, the network. So they give you these
really great capabilities that the native web does not
yet have, or if it does have, it’s kind of spotty. They give you a rich, immersive,
engaging user experience. Who would have thought
that someday you’d be able to build
something like Sublime Text as a native app out
of HTML5 and JavaScript? I put the two side by side,
they look really great next to each other. One’s native, one’s HTML5
native, but a great experience. Whoops. And finally, one of the
great things about the web is that you get this
distribution model where you update your
code on the server, and then people just
get the updated app. And that’s all great. So the way that we address
this in Chrome apps is the Chrome Web Store
handles distribution, it handles updates. So you write your app,
you put it in the store, people download it,
they’re using it, they’re all loving life,
you ship an update. And then we use the
same update mechanism that the Google servers
and Chrome uses. So every, whatever,
four or five hours, the runtime is
pinging the server, saying, hey, is there a
new version, hey, is there a new version? If there is, the user
gets the updated version, everything’s great. These are the kinds of
issues that Chrome apps are intended to address. All right. Now, I’m assuming
that many of you probably have existing web apps. And there are some
differences when you’re building native Chrome
apps using web technologies that you need to be aware of. And I’ll cover some of that. So let me just begin. First, let’s talk a
little bit about offline. I’m going to go through
each one of these in a little bit more depth. So let’s talk about for a
second what offline really means, because offline
means different things. Yes, there’s I
have no connection. The network cord was
ripped out, or I’m in some place like the desert
or an airplane or whatever, and I just don’t have
an internet connection. That’s one form of offline. But there’s another
form of offline which is crappy offline. Maybe you’re in a cafe, and
you forgot to tip the barista, and now the Wi-Fi is
mysteriously not working. Maybe you work with Jake
in the UK Google office, and you go to the bathroom,
and there’s no internet. Maybe you’re in a
super-oversubscribed awesome conference, and the Wi-Fi
is really busy in the room. So these are all kinds of
situations and edge cases where offline really matters. And again, think back
to using Sublime. You’re sitting, typing
along, the internet goes out. Sublime doesn’t care. It’s not like it’s getting
its UI from the internet and updating it in real time. You just keep right on working. That’s because all those
resources are stored locally. They’re packaged up
in a package that you don’t have to generate
UI on the fly. You don’t have some PHP
script writing out HTML. So native apps had this
really great advantage in that regard where they just
recover from this natively. So in Chrome apps,
all your resources are packaged up
locally, and your app can be launched any time. Now, what this means
is you have to plan for having a great
offline experience. Not everybody thinks
about this stuff. The question, of
course, comes up, well, what about Service
Worker, what about app cache? Yes, Service Worker, I agree, it
solves a lot of these problems. There are things where
Service Worker is great for. But think, it’s not just
a technology problem. It’s a user behavior problem. We’ve spent the last
20 years teaching users that browsers don’t work
when they’re offline. So even if we had perfect
app cache and Service Worker tomorrow, you’d still have to
overcome this user inertia of I don’t open my browser,
because why would I. So there’s all these issues. So to plan for a great
offline experience, there’s certain
things you have to do. First, you’re going to have
to factor your app in order to work offline. So take the HTML, separate it
from the JavaScript, and so on. It’s always a good idea
to abstract the app a little bit so that it’s
talking to a data layer. Think about how
Sublime is working. You’re working on
your code, it’s simply working on the data,
and then the data layer is handling the part
of talking to the cloud or talking to
or whatever it is. So if you can make
that abstraction, things get a lot easier. You have to think a
little bit about what your app’s offline
features are going to be. And yes, some
applications just don’t work very well when
they’re offline, but that doesn’t
mean they’re useless. Think about an app like Skype. Skype– 95% of
the value of Skype is only there when
I have a connection. But when I don’t
have a connection, I shouldn’t be hosed. I should at least be able
to manage my contact list, I should at least be able
to see my call history. So there’s still
some value there. So these are the kinds of things
you’ll have to think about. Like, what kinds
of features does it makes sense for my app to
have when it’s offline? Since it’s Chrome
and since it’s HTML5, you do have access
to things like the navigator.onLine property. I agree with Jake,
it’s not perfect, it’s better than nothing. The good news is that most users
don’t plug their network cables into soil. I’ve only done it twice,
and once was by accident. Most people don’t do that. They actually do plug it into
the wall, they use the Wi-Fi. So it’s better than nothing. And we give you lots
of ways to store data. Now, there’s a couple
things that we don’t do. We don’t give you
window.localStorage, because it’s synchronous and
that blocks the UX thread. So we can’t have the user
sitting there twiddling their thumbs while you’re
moving megabytes of data back and forth. So we try to fix
that by giving you asynchronous versions
of synchronous APIs that would ordinarily
be in the web. So for example, we don’t
support synchronous XHR. Who does these days? Why would you do that? So we give you
asynchronous versions. And
is our asynchronous version of window.localStorage. But you can use IndexedDB, you
can use the HTML5 file system API. There’s lots of different
ways to store data. And the reason why this
works is because if you look at the way Chrome
apps are structured, you basically build them the
way that you would normally build your web app. You have your HTML, you’ve
got your JavaScript, you’ve got the other assets
that make up your application. And then all we ask you to do
is put a little infrastructure around that. There’s a manifest
file that you write that defines what the app is
and does– what its name is, what its description is,
what permissions it has, where the entry points
are, that kind of stuff. Then there’s a file
that you get to define. I’ve called it main.js. You can call it
whatever you want. You specify this
in the manifest. And that’s the file that
takes care of the entry points into your app. So there’s an event. For example, hey,
map got launched, hey, map got restarted,
a cloud message came in, an alarm went off. So this is where you handle
those kinds of events. That’s what is all wrapped
up into a zip file. So all of that gets
packaged up into a zip. That goes up to the
Chrome Web Store. And then you’re in business. We spend an hour
scanning your zip file, making sure you’re not trying
to, like, I don’t know, steal people’s email
addresses or whatever. We do a whole bunch
of security scans, and then you’re published. We don’t review
your app, we don’t do any of that in-depth stuff. You’re good to go. So to take an example, here’s
the Chrome Storage API. So you could see that
normally, if I had a form and I wanted to save
some data in the form, I would just get the value
out of some text area. And then the
API version of this function simply takes an object
with properties in it. And it’s asynchronous,
so there’s a callback function
for when it completes. If you care about it, great. If not, it goes
on its merry way. And your app is good to go. OK. So very heavy emphasis
on asynchronous stuff. In addition to being
offline by default, we are cross-platform
by default. And I talked about
this a few seconds ago. If you think back
to what you used to have to do to build native
apps, like a long time ago. If you wanted to build a rich
native experience– and I’m talking about a long time ago. I know many of you
were not born when I’m talking about
this time period. But there was a time
when all you did was target, basically, Windows. You built a native
app for Windows. If you really cared
about the 10% of people that didn’t have Windows,
you built a Mac version. And that was native
apps like some time ago. Now, contrast that with today. Today you’ve still
got Windows, but you have multiple
versions of Windows. You still get the
Mac, but there’s multiple versions of the Mac. Then there’s iOS,
and there’s Android. Now we’ve got all these
great mobile platforms that are coming up. Linux is in the mix. What does Ubuntu have? 20, 25 million users. There’s a lot of people
out there who use this. And then, of course,
there’s Chromebooks. Four out of the top five
selling laptops on Amazon right now are Chromebooks. Hard to believe, but it’s true. So you’ve got all
these rich platforms that you would have to deliver
a native experience for. And there’s costs involved here. Just on this screen
alone, there’s what? There’s Objective C, C#, Java,
C++, all kinds of native APIs. They’re different
for each platform. And then there’s
all the hidden costs that developers never think
about like building installers, building updaters. A long time ago, I worked at
Macromedia on Dreamweaver, and I was tagged as
the installer guy. You don’t ever want to be
tagged as the installer guy. You will never get away from
being the installer guy. Every question comes to
you about the installer. But these are the
kinds of things that Chrome apps
get you away from. We handle the installation,
we handle the updating, we handle the
cross-platform stuff. It’s another great
advantage of Chrome apps. In addition to being
offline and cross-platform, we have a very heavy emphasis on
being cloud-enabled by default. And that’s because users
increasingly expect this. They expect that their data’s
going to be in the cloud. They expect it’s
going to be synced. And we give you a
bunch of features that let you
leverage this stuff. So I talked a little
bit earlier about the API. There’s also a sync version. You guys notice that
when you’re using Chrome, you have all these
bookmarks, and you’ve got different versions
of your– you know, you’ve got different
computers, and they all sync across
all your Chromes. We just give that to you. We give you an infrastructure. So all you got to do is call
a few lines of JavaScript, and your data and
preferences and properties get synced across
your application. No special work you have to do. That’s for smaller data sets. For larger data sets,
there’s a sync version of the HTML5 file system. So you could store megabytes of
data, and it’s backed by Drive. Now, today it’s backed by Drive. It’s extensible. So if somebody else wants to
build a syncing architecture, they can do it. But out of the box,
it’s backed by Drive. There’s a Cloud Push Messaging
API built into Chrome apps. This is one of the cool
things about Chrome apps. Let’s suppose your app
isn’t even running. The user’s got their laptop
open, they’re doing something, but they haven’t
launched your app yet. The Chrome runtime is running,
though, and it’s listening. So you could actually
send a cloud message through our servers
to the Chrome runtime. Chrome will wake
your app up, tell it that it got a message,
which is really cool. You can’t do that on
the Open Web today. There’s no way for a web app
to wake the browser up and be like, hey, go to this URL. That would be scary. But Chrome apps can do that. Chrome apps can listen
to cloud messages. There’s an Identity API. Who loves writing OAuth code? Loves it? Yeah, I don’t either. We’ve got an API
that handles this. So doing things like
authenticating users is easy in Chrome apps. We have one API function that’s
specific to Google services. And because you’re signed in
when you’re using Chrome apps, basically, what happens is you
call this function, you say, I want to see who the user is. You get the token back,
and then off you go. There’s also a function that you
call for third-party services. So if you want to
authenticate using, I don’t know,
Twitter or whatever, there’s a way to do that. So just to give you an idea
of what this looks like, for the syncFilesystem,
the first example shows how to use the
synchronized file system to sync data. The first line basically says,
Set the conflict resolution policy. These are things you have to
think about, data conflicts. And have a choice. You can say, you know what,
I want the last write to win. Or you can say, you know
what, I’ll just handle it, don’t worry about it. But then once you
have that, you just simply call Request file
system like you ordinarily would on any other
HTML5 file system API. You get an FS object back. And then you’re working
with the file system. So it’s like any
other file system, only this one is
synced just for you. Just taken care of. For Identity, the
two APIs I talked about, the first one,
getAuthToken, that’s for the Google services. So if I’m signed in
with my Gmail account, whatever, I just
call this function, and I can specify whether I want
it to be interactive or not. And then there’s a
callback function. There’s that
asynchronicity again. The second version,
the launchWebAuthFlow, that’s the third-party version. And so because what happens
in OAuth normally is you have this redirect URL where the
third-party service calls back to. This is an app, so there’s
no web page to do this. We have this
function right here. There’s a callback function
that takes the redirect URL. So when that gets called,
all you do is get the token, and you’re off and running. You’re signed in. Pretty straightforward. All right. How am I doing on time? Good. All right. So I talked a little bit about
immersive user experience. Chrome apps obviously
live outside the browser. They can have richer
interfaces, experiences. This, of course,
means that your app is going to be
responsible for things that it was not responsible
for in the past. And it’s important to
remember that users, they just have
different expectations of apps versus websites. They expect deeper
platform integration, they expect better
performance from a native app. Even though users want great
performance from web apps– I don’t want Cole to come
running up here and smack me in the head– but yeah. They expect great
performance from web apps, but users basically
understand, I click a button, it’s got to go to the server,
get the content, and come back. Native apps, they don’t
have that expectation. No one expects, like, a text
editor to go off to the web and get content and come back. They want responsiveness. So they expect that,
because users just aren’t in a browser frame of
mind when they’re using an app. They’re just not
thinking in that mindset. They’re using an
app, and they expect it to work flawlessly
and quickly. So we give you some APIs to
help out with this a lot. So first, we give you
a full windowing API to manage your app’s windows. So you can do things like
see how big the screen is, see how many screens there are. You can do things
like figure out where to put initial windows. You need to remember–
this is an important thing. This is an example of
something that’s subtle, but users expect this. In the past, the
browser basically said, here’s your window
and here’s where you are, and here’s how big it is. And your web app
was like, oh, OK, I guess this is
where my window is. Well, apps don’t work like that. Imagine how frustrating it
would be if every time you open Sublime, you get it right
where it is, you get the window size, you close it, it
comes back up again, and it’s this big. That would drive you
nuts, wouldn’t it? Well, it’s going to drive
Chrome app users nuts, too. So you have to remember
things like remembering window location, remembering size. Now, the good news is we’ll
do that automatically for you if you give your windows IDs. So there’s not a whole lot
of work involved on your end. But examples of things
that people expect. You can control whether
the OS title bar is shown. You don’t like the title
bar, don’t show it. Make your own. It’s HTML. And then what we
do is we give you this little
-webkit-app-region, whatever. You specify that the drag
property on whatever you want to be the dragger,
and then that’s it. That’s your title bar, or
whatever, other drag regions. So full control. We give you a contextMenus API. Users have this annoying
habit–they right-click, they want something to happen. And so we give you this
native API to do this. What’s cool about this, though,
is that the contextMenus API works outside the app. So you can specify that
if somebody right-clicks on your app icon
in the launcher, you can specify the
content that goes in there, so it’s pretty cool. Nice native integration. There’s an Alarms API. There’s an API for getting
the media galleries on the user’s computer. Now all of this is obviously
behind permissions. But you can do things like get
photos, get movies, get music. There’s just built-in
ways to do this. You get a file system
just like you’d expect any other file system. So the user says, yup, you
can have access to my photos, there you go. There’s a URL Handlers API. So you can specify
that your app, as long as you own the URL, you
can specify that your app is the handler for a
specific URL scheme. Now, you have to own the URL. Your app can’t say, oh
yes, I handle Gmail URLs. No, you’ve got to
prove ownership of the URL or the
pattern at least. And you do that in the
Google Webmaster Tools, and then your app is able to
respond intent-like to users clicking on URLs in
emails, for example. So we give you really great
ways of making an immersive user experience. All right. Let’s talk a little bit about
integrating with the OS. I showed this a
little bit earlier. So Chrome apps have access to
the native hardware platform. You get access to the USB
port, Bluetooth, the network. You can go out and
discover devices. Obviously, this has privacy
and security issues. It sure would be crazy if I was
able to control this lightbulb from my friend’s
house or whatever. So again, this is paramount. Once you start accessing
things on the user’s hardware and so on, privacy and
security become really, really important. So it’s important to be clear
to the user about when you’re using resources on their system. Now, in some cases, you
don’t have a choice. But if you turn on the camera
and the little light comes on, you don’t have any
control over that. But in other cases where
you’re using the files or storing large
amounts of data, just be clear to the user
about what you’re doing. It’s really important. And of course, when you’re done,
you got to release this stuff, because it’s shared
by the system. Share. Got to share. All right. How am I doing on time? Five minutes. OK. Let’s talk a little bit about
application security and CSP. Who’s heard of CSP? Everyone’s heard of it. That’s great. I won’t go deep into it. I included the link
in the presentation, so you can read more about it. Basically, there are certain
content security policy defaults that apps set and
that you can’t override. So for example, you
can’t use things like eval in your Chrome apps. You can’t use things
like new Function. All your JavaScript code has
to be in separate .js files. And the reason is because
if somebody puts a script tag in the head of
your page and we have no idea how it got
there– did you put it there, did they put it there? We don’t know. So it’s got to be
in a separate file. You can’t do things like
inline event handlers. You’ve got to do things the new
school addEventListener way. iframes, you can use iframes. But they’re sandboxed into
their own origin in the page. So you can postMessage
into and out of an iframe, but the iframe can’t
get into the parent page and start calling Chrome APIs. Again, that would be bad. And you’ve got to declare
where your content comes from if it’s not local. So if you think back
to that Economist app, it was showing all those images. One of the things you
can’t do in a Chrome app is just simply say,
image tag, path to random image on
web, because you have to declare local content. Now, that’s a pretty
common pattern. So we’ve actually
written a library that handles this for you. It’ll go out to the web
XHR stuff down locally. And then you use
blob URLs or object URLs to refer to
them in the app. Paul Lewis actually wrote that. It’s a really great library. Of course, you might really
want to do that stuff. But wait a second, I really
want to do that stuff, I really want to use eval. I’ve got a templating library. We do provide ways to get
around some of these limitations or security measures
that we’ve put in. So first, we have
a webview component that you can embed
inside your apps. It’s the rendering
engine of Chrome. It’s not Chrome itself. There’s no extensions
that come in. But it’s the actual
rendering surface of Chrome. So what you’re
basically doing is embedding Chrome
inside of Chrome. And it gets a little
“Inception”-like at that point, but it actually works. It’s really cool. You can do things like
embed web content. And again, you can
do the postMessaging. They can communicate with
each other, which is great. You can execute script in
the web view, which is great. For accessing remote
resources, I talked about this, it’s that XHR library
that Paul wrote. For templating
libraries, this is where things get a
little interesting, because if they’re using
eval and new Function, there’s a couple
things you can do here. One, you can pre-compile
your templates. Handlebars does
this, for example. Or there’s a way for
getting around this stuff. You can declare a page
in your application, and it doesn’t have to be
visible, as a sandboxed page. And then what happens is all
that bad stuff is now OK again. You can do things like
eval and new Function. But that page is kept separate. It doesn’t have access
to the Chrome APIs. It can’t do things
like call the Chrome stuff in your application. And you could use
postMessages back and forth. So you could put the template
library in that page, send a message, have
it do all of its stuff, it sends the
results back to you. And so then everything’s all
nice and safe and isolated. All right. Mobile. Let’s talk about
mobile really quick. I’ve got a couple minutes left. So we are working
to bring Chrome apps to mobile devices via
the Cordova project. Who’s heard of Cordova? All right. That’s about everybody. OK. So Apache Cordorva basically
is the open source version of PhoneGap. When we Adobe acquired PhoneGap,
they open sourced the code. Kind of like we have
Chromium to Chrome, they’ve got Cordova to
PhoneGap, basically. That’s basically what it is. So we’re working to
bring a set of key APIs over from the Chrome API set
to mobile where it makes sense. We’ve got about six or seven
that we’ve worked out so far. We think probably
by early January, we’ll have a beta-ish version
for you guys to work with. And it’ll be great. You guys will be able
to write one code base, you’ll get mobile
apps and local apps. The workflow is pretty
straightforward. You install the tool set. You can import in
[INAUDIBLE] Chrome app or start from scratch. It’s up to you. You iterate over
your code, you debug. And then when you’re
ready to ship, it goes into the
native app store, because these are native apps. They don’t go in the
Chrome Web Store. So for iOS, it goes
to the App Store; for Android, it goes to Play. The Chrome Web Store’s only
for the desktop version. So that’s a key difference. So these are the APIs that we’re
going to support initially. A lot of these are pretty
well-baked already on Android. We’re working to bring
some of them to iOS. Actually, this may be
a little bit outdated. I think we might actually
have notifications now. But this is the initial
APIs that we’re working on. It’s a thing of beauty. Let me show you. Remember that Internet
Relay Chat client I showed you a few minutes ago? Let me just do this. I’m going to bring
this up right here. I’m going to tab over. OK. So there it is. That’s the IRC client. Let me bring up the
other one so you guys can see it side by side. There’s that one. There’s the UI. There’s the mobile version
running on my Android device. Same code base. HTML5, JavaScript, [INAUDIBLE]
running both my Android and my desktop. Oh my god, same code base? Yes, female audience
member, same code base. Same stuff. All right. So if that’s got you
interested, if this is exciting, if you think that Chrome
apps might be something you might want to
work on, these are the URLs you need to look for. We’ve got our GitHub repo,
the Chrome app samples. All the APIs that
are in the platform have a corresponding sample. is
where you go to learn about all this stuff. We document all the APIs there. And it looks like I’m
about seven seconds early, so thank you very much. [APPLAUSE]


Add a Comment

Your email address will not be published. Required fields are marked *