Back in 2000, sheets worked well because the smallest unit of user interaction with an application was a window. Soon after, though, things started to change. Web browsers in particular were among the first to start using tabs to put more than one document in a window. This caused a snag. A web page can require modal interaction from the user: picking a file, or supplying a username and password. Yet we don't want to prevent the user from switching to a different tab and continuing to interact with other websites. If the finest-grained modality control we have is per-window, how can we achieve that outcome?
Chromium's current answer comes from combining Cocoa's child window support with sheets to get tab-modal sheets:
While this looks like a normal sheet, you can switch between open tabs while the password request is up. You can't, however, interact with the web page.
The implementation, like all of the code used in Chromium, is open source, and can be found in the Google Toolbox for Mac, a collection of reusable components from the Mac developers at Google. The technical details of the GTMWindowSheetController can be found on the Google Mac blog. The other thing to note is that right now tab-modal sheets are only used for website authentication. The other sheets we use (for file selection, etc) are currently window-modal; we hope to convert them over soon.
The fate of tab modal sheets, however, isn't certain. A way to enforce tab-modal interaction is certainly needed. But is attaching sheets to the tabs the right way to achieve that goal? At the last WWDC, I talked to some graphic designers who were opposed to the idea. "Reusing sheets in a context that isn't window modality will only confuse the user!" On the other hand, my position is that the concept of modality is the same, and the context is similar enough that users will find that sheets help them understand the modality in which they must interact.
So the story isn't over. Tab-modal sheets are our contribution to the ongoing discussion, an experiment to see what works and what doesn't. Together we can work out the best way to help users interact with their computers.
A malicious extension is an extension written by an ill-intentioned developer. For example, a malicious extension might record your passwords and send them to back to a central server. The tricky part about defending against malicious extensions is that there are well-intentioned extensions that do exactly the same thing. Our defenses against malicious extensions focus on helping the user avoid installing malicious extensions in the first place:
We expect most users to install extensions from the gallery, where each extension has a reputation. We expect malicious extensions will have a low reputation and will have difficulty attracting many users. If a malicious extension is discovered in the gallery, we will remove it from the gallery.
When installing extensions outside the gallery, the user experience for installing an extension is very similar to the experience for running a native executable. If an attacker can trick the user into installing a malicious extension, the attacker might as well trick the user into running a malicious executable. In this way, the extension system avoids increasing the attack surface.
To help protect against vulnerabilities in benign-but-buggy extensions, we employ the time-tested principles of least privilege and privilege separation. Each extension declares the privileges it needs in its manifest. If the extension is later compromised, the attacker will be limited to those privileges. For example, the Gmail Checker extension declares that it wishes to interact with Gmail. If the extension is somehow compromised, the attacker will not be granted the privilege to access your bank.
To achieve privilege separation, each extension is divided into two pieces, a background page and content scripts. The background page has the lion's share of the extensions privileges but is isolated from direct contact with web pages. Content scripts can interact directly with web pages but are granted few additional privileges. Of course, the two can communicate, but dividing extensions into these components means a vulnerability in a content script does not necessarily leak all the extension's privileges to the attacker.
Finally, we utilize our multi-process architecture and sandboxing technology to provide strong isolation between web content, extensions, and the browser. Extensions run in a separate operating system process from the browser kernel and from web content, helping prevent malicious web sites from compromising extensions and malicious extensions from compromising the browser kernel. To facilitate rich interaction, content scripts run in-process with web content, but we run content scripts in an "isolated world" where they are protected from the page's JavaScript.
Of course, attackers will write malicious extensions and well-intentioned developers will write buggy extensions. The extension system improves security by making it easier for developers to write secure extensions. If you would like to learn more about the security of the extension system, you can watch our video or read our academic paper describing all the details.
We've done tech talks before, but this time we asked Chromium developers what they'd most like to hear about. Once we knew what was most in demand, we found experts on each subject and asked them to make a presentation. The talks were given before a live studio audience of Googlers last Friday with extra attention paid to creating high quality recordings. Now we're excited to make these widely available to all Chromium contributors!
The WebKit API
with Darin Fisher
Darin Fisher talks about the recently upstreamed Chromium WebKit API. The API is a critical step in our path to becoming completely integrated into the WebKit project. Like the other WebKit APIs, ours is a veneer which shields developers (including many of our own) from the internal details of WebKit (named WebCore). Darin talks at a high level about the API, dives into some code examples, and talks about the history and future of the API.
Layout Tests
with Pam Greene
Layout Tests are the tests we inherit from the WebKit project and are a very important part of the Chromium's testing infrastructure. Pam Greene talks about what they are, how to run them, how to debug problems within them, and even touches on how to write your own. She also covers advanced (but easy to use) tools for rebaselining and tracking flakyness. Any Chromium developer that works on WebKit really should check this out!
Painting in Chromium
with Brett Wilson
Because of Chromium's multi-process architecture, painting within Chromium is far from typical. In this talk, Brett Wilson starts from Skia and the WebKit render tree, follows the bits across the process boundaries, and continues all the way to your screen. He also details many of the differences in painting between platforms, how things work in test shell, and interesting corner cases like resizing.
WebKit's Guts
with Eric Seidel
A large percentage of Chromium's code (and part of what makes it so fast) is WebKit. In this talk, Eric Seidel gives us a 30,000 foot view of how WebKit actually renders a page. He starts with how resources are loaded, explains how they're parsed into a DOM tree, and then talks about the various trees involved in rendering. In addition, he touches on many other important topics like hit testing (figuring out what you're hovering over and clicking on). This is a must-see for anyone working on the guts of WebKit.
This is not ready for consumers yet — everything you see can and probably will change by the time Google Chrome OS-based devices are available late next year.
Please note that Google has not released an official binary for Chromium OS and therefore if you download Chromium OS binaries please ensure that you trust the site you are downloading them from.
While we will try our best to help you through the Chromium discussion forums, we will not be officially supporting any of these builds. Remember that you are downloading that specific site/developer's build of Chromium OS.
We have also received a number of questions that we wanted to answer directly and so we put together the following FAQ to clarify some of these issues.
One of the top questions has been around the distinction between Google Chrome OS and Chromium OS. Google Chrome OS is to Chromium OS what Google Chrome browser is to Chromium. Chromium OS is the open source project, used primarily by developers, with code that is available for anyone to checkout, modify and build their own version with. Meanwhile, Google Chrome OS is the Google product that OEMs will ship on Netbooks next year. Therefore, dear developers who have built and posted Chromium OS binaries, you're awesome and we appreciate what you are doing, however we have to ask you to call the binaries you've put up for download "Chromium OS" and not "Google Chrome OS".
See Getting a WebGL Implementation for instructions on getting a Chromium build and enabling WebGL support. This is an early version with many caveats, but with it you can get a taste of the new functionality coming to the web.
Shiny teapot demo illustrating compositing of 3D graphics with the web page
Particle system demo showing how to use the GPU to animate particles
The WebGL wiki is the central location for information about the evolving specification, including the draft spec, introductory articles, tutorials, mailing lists and forums. See the WebGL demo repository for more demos and instructions on how to check out their source code.
We're looking forward to finalizing the WebGL specification and making this functionality available to web developers, and look forward to your feedback. For Chromium-specific questions, use the Chromium-dev mailing list, for more general WebGL questions, use the WebGL forums or WebGL public mailing list.
The Web Sockets API enables web applications to handle bidirectional communications with server-side process in a straightforward way. Developers have been using XMLHttpRequest ("XHR") for such purposes, but XHR makes developing web applications that communicate back and forth to the server unnecessarily complex. XHR is basically asynchronous HTTP, and because you need to use a tricky technique like long-hanging GET for sending data from the server to the browser, simple tasks rapidly become complex. As opposed to XMLHttpRequest, Web Sockets provide a real bidirectional communication channel in your browser. Once you get a Web Socket connection, you can send data from browser to server by calling a send() method, and receive data from server to browser by an onmessage event handler. A simple example is included below.
if ("WebSocket" in window) { var ws = new WebSocket("ws://example.com/service"); ws.onopen = function() { // Web Socket is connected. You can send data by send() method. ws.send("message to send"); .... }; ws.onmessage = function (evt) { var received_msg = evt.data; ... }; ws.onclose = function() { // websocket is closed. }; } else { // the browser doesn't support WebSocket. }
In addition to the new Web Sockets API, there is also a new protocol (the "web socket protocol") that the browser uses to communicate with servers. The protocol is not raw TCP because it needs to provide the browser's "same-origin" security model. It's also not HTTP because web socket traffic differers from HTTP's request-response model. Web socket communications using the new web socket protocol should use less bandwidth because, unlike a series of XHRs and hanging GETs, no headers are exchanged once the single connection has been established. To use this new API and protocol and take advantage of the simpler programming model and more efficient network traffic, you do need a new server implementation to communicate with — but don't worry. We also developed pywebsocket, which can be used as an Apache extension module, or can even be run as standalone server.
You can use Google Chrome and pywebsocket to start implementing Web Socket-enabled web applications now. We're more than happy to hear your feedback not only on our implementation, but also on API and/or protocol design. The protocol has not been completely locked down and is still in discussion in IETF, so we are especially grateful for any early adopter feedback.
Posted by Yuzo Fujishima (藤島 勇造), Fumitoshi Ukai (鵜飼 文敏), and Takeshi Yoshino (吉野 剛史), Software Engineers
In many cases, though, Google Chrome needs to keep pages from related tabs in the same process, since they may access each other's contents using JavaScript code. For example, clicking links that open in a new window will generally cause the new and old pages to share a process.
In practice, web developers may find situations where they would like links to other pages to open in a separate process. As one example, links from messages in your webmail client would be nice to isolate from the webmail client itself. This is easy to achieve now, thanks to new support in WebKit for HTML5's "noreferrer" link relation.
To cause a link to open in a separate process from your web page, just add rel="noreferrer" and target="_blank" as attributes to the <a> tag, and then point it at a URL on a different domain name. For example:
In this case, Google Chrome knows that the page will be opened in a new window, that no referrer information will be passed to the new page, and that the window.opener value will be null in the new page. As a result, the two pages cannot script each other, so Chrome can load them in separate processes. Google Chrome will still keep same-site pages in the same process, to allow them to share caches and minimize overhead.