If you’re a Chrome extensions power user, you may be familiar with a task manager that looks like this:
That’s a lot of extensions running! Most of the time, they’re probably just sitting idle, waiting for the user to interact with them. Do they really need to be running and using your memory all the time?
Over the last several months, we've been working on a new feature for the extension system called Event Pages that we think will help reduce the memory used by these idle extensions.
How They Work
Event pages are an evolution of background pages, with one major improvement: rather than running in the background all the time, an event page only runs when it is handling events. Once an event page becomes idle, it is unloaded, freeing memory until the next time it’s needed. Learn more from the event page documentation.
To help event pages support some important use cases, we’re also developing a few new APIs.
- The alarms API allows an extension to wake itself up at set times, to support features like periodically syncing data to the cloud.
- Some new events let extensions know when they have been installed, or when their event page is being unloaded.
- A declarative version of the webRequest API lets extensions do network interception without the need for a background page at all.
Try it Out
We plan to release event pages to Chrome’s beta and stable channels late this summer, but you can start experimenting with them on the developer channel today. Try converting your overweight extension to event pages, and let us know how it works.
As Chrome Web Store apps and extensions have become more popular, users have been generating a large amount of reviews and feedback for developers. Until now, there was no way to separate a user’s review of an app’s features and quality from developer-focused feedback, such as the reporting of bugs, feature requests, and general questions.
To improve the feedback loop between developers and users, we’ve added a new way to get feedback directly from your users:
This feature provides a clean separation between reporting bugs and compatibility issues to developers and the rating / comments users can leave in the store relating to the functionality and usefulness of a given app. The contents of the feedback forum are publicly visible to everyone, which helps to cut down on duplicate issue reporting.
Turning the Feedback Feature On
In order to enable this feature for your store items, go to your developer dashboard and click on the “Edit your User Feedback preferences” option (highlighted below):
Engaging With Your Users
You should encourage your app’s users to engage with you via the new feedback feature by placing links to your app’s feedback page directly on your site after you’ve activated it. To do so, use the url format “https://chrome.google.com/webstore/support/yourappid
We hope that this new feature will give users a better experience in reporting issues, requesting new features, and asking questions. Similarly, developers will now have a much easier forum to use to have an ongoing social conversation about their products.
Cross-posted from the Google Developers Blog
Would you like to use your coding skills to significantly improve the world, and have the chance to win tickets to Google I/O 2013 for your efforts? Google.org has joined forces with the I/O Extended team to bring you the "Develop for Good" Hackathon. We’re looking for hackers to tackle issues around repressive regimes, engaging citizens in politics and enabling us all to be greener!
Almost anyone can participate in the hackathon from just about anywhere in the world. Many of the Extended events are already hosting hackathons, so we encourage you to find an event near you or start your own. If you’re in the San Francisco Bay Area, Google.org will be hosting a ‘Develop for Good’ hackathon at the San Francisco I/O Extended event.
Here are the three challenges developed by the Google teams:
- Google Ideas: Conflict reporting for blackout situations in repressive regimes.
- Google Politics & Elections: Citizen Engagement for Politics & Elections.
- Google Green: Help us all be a little bit greener!
Developers can start preparing, and even coding, right away and then bring their ideas to the Extended event Hackathons during I/O (though we welcome you to participate even if you’re unable to attend an event). Pencils down on Friday night—hacks must be submitted by 11:59 p.m. (PDT) on June 29, 2012 via this form.
After June 29th a team of Googlers will judge the submissions for each challenge. We will announce the winning hacks for each challenge by about August 1st, 2012. There will be one winning hack selected from each challenge area, and each will receive up to 5 tickets to I/O 2013, along with the honorary title of "Google Developer for Good, 2012". In addition, we’ll award one of the latest Chromebooks to each member of the team producing the best web app across all three challenges.
If you are interested in getting involved, we recommend signing up for an I/O Extended event near you and then checking with the organizer to see whether a hackathon is part of the agenda -- or hosting your own Extended event and hackathon!
Cross-posted from the Google Developers Blog.
A year ago, we released a preview of the PageSpeed Insights Chrome Developer Tools extension, which analyzes the performance of web pages and provides suggestions to make them faster. Today, we’re releasing version 2.0 of the PageSpeed Insights extension, available in the Chrome Web Store.
PageSpeed Insights for Chrome is a Chrome Developer Tools extension that analyzes all aspects of the page load, including resources, network, DOM, and the timeline. If you're already familiar with Chrome Developer Tools, you'll find that PageSpeed Insights integrates with a toolset you're already using.
We hope you’ll give PageSpeed Insights for Chrome a try and start optimizing your web pages today. We’d love to hear from you, as always. Please try PageSpeed Insights for Chrome, and give us feedback on our mailing list with questions, comments, and new features you’d like to see.
During these last few weeks, the Chrome Web Store team has been focused on launching the store in more countries and building some new features for developers that can help them reach and engage with more users.
We recently launched the Chrome Web Store in six additional countries: Turkey, Ukraine, Egypt, Saudi Arabia, Morocco and the United Arab Emirates. This means that developers can now distribute and sell their apps to millions of additional potential users.
To be successful in these new markets, we highly recommend localizing your apps in as many languages as possible. This will make them more accessible to users around the world, and more likely to be promoted in the 42 countries the store is available in.
New Offline Apps Collection
To recognize developers who have made their apps work offline - and help users find them - we created a special collection just to highlight them in the store.
If you are a developer, getting your app listed in this collection is as simple as adding the offline_enabled flag to your app’s manifest file (note: to avoid negative user feedback, please ensure that your app does indeed work well offline before you do this).
Better Information in the Developer Dashboard
One of the common requests we’ve received from developers, is that they’d like better insight into how well their apps are doing in the store. Many of you would especially like to know how many times your apps and extensions are being viewed vs. how many installations are occurring.
To help you with your data needs, we’ve created a new graph view to help you understand the performance of your apps. To make this data more accessible, you can easily download it as a CSV file. Currently, we provide 90 days of history information.
In the near future, we plan to further refine this feature - for example, we may increase the historical period for which data is available and add other features to help you understand how your apps are being adopted.
When we wrapped up our recent Pwnium event, we praised the creativity of the submissions and resolved to provide write-ups on how the two exploits worked. We already covered Pinkie Pie’s submission in a recent post, and this post will summarize the other winning Pwnium submission: an amazing multi-step exploit from frequent Chromium Security Reward winner Sergey Glazunov.
From the start, one thing that impressed us about this exploit was that it involved no memory corruption at all. It was based on a so-called “Universal Cross-Site Scripting” (or UXSS) bug. The UXSS bug in question (117226) was complicated and actually involved two distinct bugs: a state corruption and an inappropriate firing of events. Individually there was a possible use-after-free condition, but the exploit -- perhaps because of various memory corruption mitigations present in Chromium -- took the route of combining the two bugs to form a “High” severity UXSS bug. However, a Pwnium prize requires demonstrating something “Critical”: a persistent attack against the local user’s account. A UXSS bug alone cannot achieve that.
The exploit still had a long way to go, though, as there are plenty of additional barriers:
- chrome://chromewebdata does not have any sensitive APIs associated with it.
- chrome://a is not same-origin with chrome://b.
- chrome://* origins only have privileges when the backing process is tagged as privileged by the browser process, and this tagging only happens as a result of a top-level navigation to a chrome:// URL.
- The sensitive chrome://* pages generally have CSPs applied that prevent the UXSS bug in question.
The exploit became extremely creative at this point. To get around the defenses, the compromised chrome://chromewebdata origin opened a window to chrome://net-internals, which had an iframe in its structure. Another WebKit bug -- the ability to replace a cross-origin iframe (117583) -- was used to run script that navigated the popped-up window, simply “back” to chrome://net-internals (117417). This caused the browser to reassess the chrome://net-internals URL as a top-level navigation -- granting limited WebUI permissions to the backing process as a side-effect (117418).
As you can imagine, it took us some time to dissect all of this. Distilling the details into a blog post was a further challenge; we’ve glossed over the use of the UXSS bug to bypass pop-up window restrictions. The UXSS bug was actually used three separate times in the exploit. We also omitted details of various other lockdowns we applied in response to the exploit chain.
What’s clear is that Sergey certainly earned his $60k Pwnium reward. He chained together a whopping 14[*] bugs, quirks and missed hardening opportunities. Looking beyond the monetary prize, Sergey has helped make Chromium significantly safer. Besides fixing the array of bugs, we’ve landed hardening measures that will make it much tougher to abuse chrome:// WebUI pages in the future.
Back in March, we began work on a Metro-style enabled desktop browser, a version of Chrome that will run in both the Metro and desktop environments of Windows 8 on x86. (Chrome won’t run in WinRT, i.e. Windows 8 on ARM processors, as Microsoft is not allowing browsers other than Internet Explorer on the platform.) If you’re running the Release Preview of Windows 8, you’ll be able to try Chrome in Metro mode in the next Chrome Dev channel release by setting it as your default browser.
The initial releases of Chrome in Metro mode will include integration with the basic Windows 8 system functionality, such as charms and snap view. Over the next few months, we’ll be smoothing out the UI on Metro and improving touch support, so please feel free to file bugs. We’re committed to bringing the speed, simplicity, and security of Chrome into Windows 8, and we look forward to working with you on it.
CSS filters are a powerful, easy-to-use visual effects tool for web developers. Filters can manipulate the appearance of any HTML element and can be stacked together to create unique effects -- all with a single line of CSS. Chromium GPU accelerates these filters to make them super fast. CSS filters are new in Chromium 19.
The current set of supported filters in Chromium include many that are familiar to web developers with image processing experience, such as sepia, saturation, opacity, and blurs. If you’re a web designer looking to add dynamic visuals to your next page layout, a developer building a photo editing app, or a game developer looking for an easy way to add effects to your next title, CSS filters can help you get there easily.
GPU acceleration of these filters brings their performance to the point where they can be used for animating elements in conjunction with CSS animations powered by -webkit-transition or even HTML5 video tags.
To get a sense of how much you can do with CSS filters, check out this interactive abstract painting app.
For more info on CSS filters, including a full list of those available in Chromium and how to use them, check out the new CSS Filter tutorial on HTML5Rocks.
In theory there’s no difference between theory and practice. In practice, there is. That’s why we prefer to try new ideas out in the real world and see which features actually helped users get where they want to go. In Chrome we call these tests Field Trials, and they’ve been part of every install steadily making Chrome better since day one. For example, Field Trials helped us improve our Omnibox pre-rendering by about 70 percent - making about 1 in 3 Omnibox navigations faster by a second or more.
If you’re contributing to Chrome, you should consider using Field Trials to help tune your features. Recently we’ve added infrastructure to help make designing and deploying these tests easier than ever. Field Trials will now have a regular update cycle similar to the one that delivers the newest version of Chrome to users, making it easier to rapidly release and retire new variations. We’ve also centralized the logic of which variations are active so that its easy for developers on M21 or higher to reset their variation state, using the --reset-variation-state command line flag. To learn more about variations of Chrome, check out Field Trials at the Chromium project.
Just over two months ago, Chrome sponsored the Pwnium browser hacking competition. We had two fantastic submissions, and successfully blocked both exploits within 24 hours of their unveiling. Today, we’d like to offer an inside look into the exploit submitted by Pinkie Pie.
So, how does one get full remote code execution in Chrome? In the case of Pinkie Pie’s exploit, it took a chain of six different bugs in order to successfully break out of the Chrome sandbox.
Pinkie’s first bug (117620) used Chrome’s prerendering feature to load a Native Client module on a web page. Prerendering is a performance optimization that lets a site provide hints for Chrome to fetch and render a page before the user navigates to it, making page loads seem instantaneous. To avoid sound and other nuisances from preloaded pages, the prerenderer blocks plug-ins from running until the user chooses to navigate to the page. Pinkie discovered that navigating to a pre-rendered page would inadvertently run all plug-ins—even Native Client plug-ins, which are otherwise permitted only for installed extensions and apps.
Of course, getting a Native Client plug-in to execute doesn’t buy much, because the Native Client process’ sandbox is even more restrictive than Chrome’s sandbox for HTML content. What Native Client does provide, however, is a low-level interface to the GPU command buffers, which are used to communicate accelerated graphics operations to the GPU process. This allowed Pinkie to craft a special command buffer to exploit the following integer underflow bug (117656) in the GPU command decoding:
The issue here is that if size_of_buffer is smaller than sizeof(uint32), the result would be a huge value, which was then used as input to the following function:
This calculation then overflowed and made the result of this function zero, instead of a value at least equal to sizeof(uint32). Using this, Pinkie was able to write eight bytes of his choice past the end of his buffer. The buffer in this case is one of the GPU transfer buffers, which are mapped in both processes’ address spaces and used to transfer data between the Native Client and GPU processes. The Windows allocator places the buffers at relatively predictable locations; and the Native Client process can directly control their size as well as certain object allocation ordering. So, this afforded quite a bit of control over exactly where an overwrite would occur in the GPU process.
The next thing Pinkie needed was a target that met two criteria: it had to be positioned within range of his overwrite, and the first eight bytes needed to be something worth changing. For this, he used the GPU buckets, which are another IPC primitive exposed from the GPU process to the Native Client process. The buckets are implemented as a tree structure, with the first eight bytes containing pointers to other nodes in the tree. By overwriting the first eight bytes of a bucket, Pinkie was able to point it to a fake tree structure he created in one of his transfer buffers. Using that fake tree, Pinkie could read and write arbitrary addresses in the GPU process. Combined with some predictable addresses in Windows, this allowed him to build a ROP chain and execute arbitrary code inside the GPU process.
The GPU process is still sandboxed well below a normal user, but it’s not as strongly sandboxed as the Native Client process or the HTML renderer. It has some rights, such as the ability to enumerate and connect to the named pipes used by Chrome’s IPC layer. Normally this wouldn’t be an issue, but Pinkie found that there’s a brief window after Chrome spawns a new renderer where the GPU process could see the renderer’s IPC channel and connect to it first, allowing the GPU process to impersonate the renderer (bug 117627).
Even though Chrome’s renderers execute inside a stricter sandbox than the GPU process, there is a special class of renderers that have IPC interfaces with elevated permissions. These renderers are not supposed to be navigable by web content, and are used for things like extensions and settings pages. However, Pinkie found another bug (117417) that allowed an unprivileged renderer to trigger a navigation to one of these privileged renderers, and used it to launch the extension manager. So, all he had to do was jump on the extension manager’s IPC channel before it had a chance to connect.
Once he was impersonating the extensions manager, Pinkie used two more bugs to finally break out of the sandbox. The first bug (117715) allowed him to specify a load path for an extension from the extension manager’s renderer, something only the browser should be allowed to do. The second bug (117736) was a failure to prompt for confirmation prior to installing an unpacked NPAPI plug-in extension. With these two bugs Pinkie was able to install and run his own NPAPI plug-in that executed outside the sandbox at full user privilege.
So, that’s the long and impressive path Pinkie Pie took to crack Chrome. All the referenced bugs were fixed some time ago, but some are still restricted to ensure our users and Chromium embedders have a chance to update. However, we’ve included links so when we do make the bugs public, anyone can investigate in more detail.
In an upcoming post, we’ll explain the details of Sergey Glazunov’s exploit, which relied on roughly 10 distinct bugs. While these issues are already fixed in Chrome, some of them impact a much broader array of products from a range of companies. So, we won’t be posting that part until we’re comfortable that all affected products have had an adequate time to push fixes to their users.
Last year we proposed the Web Intents API to help web applications integrate with one another with minimal effort. We've now enabled an experimental version of the API in the most recent stable version of Chrome, to gather feedback from the web community and shape the future of the Web Intents API.
This prototype version of Web Intents makes it easier for developers to try out the API and experience its benefits first hand:
- Developers who build client apps will be able to easily include functionality from other web services (e.g., photo editing).
- Developers creating those services will no longer need to invest time and resources to negotiate and build hardcoded integrations - they can just focus on offering a great quality product with the integration facilitated by the API.
In addition, this implementation of Web Intents can help the design discussions in the W3C web intents open standards list. After all, it's impossible to build a complex API—especially one that requires an ecosystem of apps—without feedback from web developers using it in the wild.
We expect that Web Intents will evolve significantly, potentially in backwards-incompatible ways, as feedback from real world usage trickles in. Because of its experimental status, the current live version is prefixed and only allows applications to register as services in their Chrome Web Store app manifest.
Once the API is stable, we plan to remove this restriction.
To learn more on how to use the experimental Web Intents API check out the Web Developers' Guide to Web Intents in Chrome. If you choose to experiment with Web Intents, be sure to follow our discussion group, where we'll announce any impending breaking changes in Chrome's implementation.
The Dev channel has been updated to 20.0.1132.7 for Chromebooks (Acer AC700 , Samsung Series 5, and Cr-48)
The Dev channel has been updated to 20.0.1132.7 (Platform versions: 2268.9.0) for Chromebooks (Acer AC700 , Samsung Series 5, and Cr-48).
This build contains a number of new features, as well as security & stability improvements. Some highlights of these changes are:
Like with other multithreaded applications, debugging Web Workers may be a tricky task and having good instruments makes this process much easier. Chrome Developer Tools provides full debugging support for scripts running in both dedicated and shared workers.
You can now use the powerful Scripts, Timeline, Profiles and Console panels to develop Web Workers:
All dedicated workers running in the inspected page are listed in the Scripts panel, under the Workers section. Clicking on a worker URL will open a new Developer Tools window attached to the worker. If you need to debug a dedicated worker’s initialization, there is also an option to pause workers on start. This will suspend the execution in all starting dedicated workers at the very first statement.
Shared workers are more independent than dedicated ones as they can be used concurrently by several pages. All running shared workers can be discovered through the chrome://inspect page. Each shared worker listed there has inspect and terminate links next to its URL. These links allow you to launch a Developer Tools window attached to that worker or terminate the worker respectively.
When you need to debug a shared worker initialization, it is enough to terminate the current instance of the worker leaving the Developer Tools window open and reload one of the worker clients. The worker will restart and Developer Tools window will automatically re-attach to the new instance.
Web browsers are big, complicated pieces of software that are extremely difficult to secure. In the case of Chrome, it’s an even more interesting challenge as we contend with a codebase that evolves at a blisteringly fast pace. All of this means that we need to move very quickly to keep up, and one of the ways we do so is with a scaled out fuzzing infrastructure.
Chrome’s fuzzing infrastructure (affectionately named "ClusterFuzz") is built on top of a cluster of several hundred virtual machines running approximately six-thousand simultaneous Chrome instances. ClusterFuzz automatically grabs the most current Chrome LKGR (Last Known Good Revision), and hammers away at it to the tune of around fifty-million test cases a day. That capacity has roughly quadrupled since the system’s inception, and we plan to quadruple it again over the next few weeks.
With that kind of volume, we’d be overloaded if we just automated the test case generation and crash detection. That’s why we’ve automated the entire fuzzing pipeline, including the following processes:
- Managing test cases and infrastructure - To run at maximum capacity we need to generate a constant stream of test cases, distribute them across thousands of Chrome instances running on hundreds of virtual machines, and track the results.
- Analyzing crashes - The only crashes we care about for security purposes are the exploitable ones. So we use Address Sanitizer to instrument our Chrome binaries and provide detailed reports on potentially exploitable crashes.
- Minimizing test cases - Fuzzer test cases are often very large files—usually as much as several hundred kilobytes each. So we take the generated test cases and distill them down to the few, essential pieces that actually trigger the crash.
- Identifying regressions - The first step in getting a crash fixed is figuring out where it is and who should fix it. So this phase tracks the crash down to the range of changes that introduced it.
- Verifying fixes - In order to verify when a crash is actually fixed, which we run the open crash cases against each new LKGR build.
In addition to manageability, this level of scale and automation provides a very important additional benefit. By aggressively tracking the Chrome LKGR builds, ClusterFuzz is evolving into a real-time security regression detection capability. To appreciate just what that means, consider that ClusterFuzz has detected 95 unique vulnerabilities since we brought it fully online at the end of last year. In that time, 44 of those vulnerabilities were identified and fixed before they ever had a chance to make it out to a stable release. As we further refine our process and increase our scale, we expect potential security regressions in stable releases to become increasingly less common.
Just like Chrome itself, our fuzzing work is constantly evolving and pushing the state of the art in both scale and techniques. In keeping with Chrome’s security principles, we’re helping to make the web safer by upstreaming the security fixes into projects we rely upon, like WebKit and FFmpeg. As we expand and improve ClusterFuzz, users of those upstream projects will continue to benefit.
The Dart team invites you to the first global Dart hackathon, a collaboration between the Dart team and the developer community. Sign up and have fun hacking on Dart to build modern client and server side web apps and libraries. Current hackathon locations include:
- North America:
- Silicon Valley, California, USA
- South America:
- São Paulo, Brazil
- Europe and Middle East:
- London, England
- Prague, Czech Republic
- Tel Aviv, Israel
- Bacolod City, Philippines
- Chandigarh, India
- Goa, India
- Karnataka, India
- Manipal, India
- New Delhi, India
- Seoul, Korea
- Tokyo, Japan
Hackathon dates vary by location. Check out the full list for the schedule.The Dart project is still in technology preview, which means you’ll be hacking on early access code, but that’s all part of the fun. We’re eager to see what you build, and we hope you can make it. Register today!
Last January, Chrome was the first major browser to preview WebRTC, HTML5's new real time audio and video stack. Since then, we've been hard at work keeping up with the evolving specification, fixing bugs and listening to the web community’s feedback.
The main parts of the WebRTC specification are now stable and are coming soon to all 200M+ Chrome users. With this blog post, we want to help developers plan for what will be introduced in this first stable release later this year.
Our implementation will support multiple independent PeerConnections, each capable of sending and receiving multiple independent media sources.
ICE / STUN / TURN
ICE and STUN are standardized methods for establishing a peer-to-peer connection on the Internet, even if the two end points are behind private network addresses (NAT). Chrome’s current stack deviates from the official current standards. We are working to fix this.
We will also support TURN servers to allow connections through tougher firewalls, where relaying and encapsulation are needed. Exactly what type of TURN will be supported is TBD.
Encryption will be mandatory for all usage of WebRTC in Chrome. For our first stable release, we will implement DTLS-SRTP.
VP8, iSAC, iLBC, G.711
The video codec support by Chrome will be VP8. We've made several major improvements inside and around VP8 to ensure it can deliver a great real time experience. On the audio side, we will initially support iSAC, iLBC, G.711, and DTMF, with iSAC being the default. It is a royalty free wideband codec optimized for speech, open sourced at webrtc.org.
More functionality and features will appear in future versions of Chrome. We’ll work on prioritizing them once we get the basics right:
- Data API. Implementation will start once the network stack is ready.
- Screen sharing.
- PeerConnection proxying. The ability to relay a stream to a third party will not make our first version.
- Recording. MediaRecorder specification work has not been completed yet.
We’ve enabled GPU-accelerated Canvas2D on capable Windows and Mac computers, which should make web applications like games perform even better than a pure software implementation. GPU-accelerated Canvas2D has previously been enabled in the Beta channel for quite some time, so hopefully developers have had a chance to try it out. We’re continuing to make improvements and tweaks to our Canvas2D implementation, so please file a bug in our public issue tracker if you encounter problems.
Over the past several months, the number of daily app and extensions downloads from the Chrome Web Store has more than doubled. We are now seeing millions of downloads per day. Some apps and extensions have grown even faster thanks to inline installation, a feature we launched a few months ago.
With inline installation, you can allow Chrome users who visit your web site to install your apps and extensions directly without requiring them to visit the Chrome Web Store. This creates a smoother experience for your users as it eliminates an extra step where potential users could drop off.
Here are a few examples of the impact of inline installation:
- Chrome extensions Evernote Clearly and Evernote Web Clipper derive 15% and 25% of their Chrome installations (respectively) from their inline installation implementation
- Rovio implemented inline installation for their Angry Birds Chrome game and saw their install rate jump by almost 10%)
- Equire, a CRM extension that integrates with Gmail, saw a 66% increase in Chrome user retention after they implemented inline installation.
Implementing inline installation is very easy:
- Provide a link to your Chrome Web Store item.
- Write some script to check for whatever client-side capabilities your app requires (support for WebGL, the Web Audio API, etc). Modernizr is a great library to use for this.
The user sees the same Add To Chrome dialog prompt that they would on the store, confirm the install, and they're done – all without leaving your site.
Last week, the Chrome team participated in the Game Developers Conference in San Francisco. We all enjoyed talking to attendees about how game developers can benefit from the latest browser technologies such as Native Client and HTML5.
For those of you who were not able to attend, we recorded videos of our talks. Check them out and let us know what you think.
During GDC, several developers presented some new and upcoming games for the Chrome Web Store. From AirMech to the highly anticipated From Dust, these games provided a sneak peek to the future of browser-based games.
Besides being able to use the latest technology the web has to offer, creating a game for Chrome means you can distribute and monetize your game successfully. This is evidenced by our 4 brand new case studies with Kabam, Hlafbrick, Game Salad, and Limex Games.
To learn how you too can develop games for Chrome, start by visiting our game developer site.