1// Copyright 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#ifndef EXTENSIONS_BROWSER_PROCESS_MAP_H_ 6#define EXTENSIONS_BROWSER_PROCESS_MAP_H_ 7 8#include <set> 9#include <string> 10 11#include "base/basictypes.h" 12#include "components/keyed_service/core/keyed_service.h" 13#include "extensions/common/features/feature.h" 14 15namespace content { 16class BrowserContext; 17} 18 19namespace extensions { 20class Extension; 21 22// Contains information about which extensions are assigned to which processes. 23// 24// The relationship between extensions and processes is complex: 25// 26// - Extensions can be either "split" mode or "spanning" mode. 27// - In spanning mode, extensions share a single process between all incognito 28// and normal windows. This was the original mode for extensions. 29// - In split mode, extensions have separate processes in incognito windows. 30// - There are also hosted apps, which are a kind of extensions, and those 31// usually have a process model similar to normal web sites: multiple 32// processes per-profile. 33// - A single hosted app can have more than one SiteInstance in the same process 34// if we're over the process limit and force them to share a process. 35// 36// In general, we seem to play with the process model of extensions a lot, so 37// it is safest to assume it is many-to-many in most places in the codebase. 38// 39// Note that because of content scripts, frames, and other edge cases in 40// Chrome's process isolation, extension code can still end up running outside 41// an assigned process. 42// 43// But we only allow high-privilege operations to be performed by an extension 44// when it is running in an assigned process. 45// 46// =========================================================================== 47// WARNINGS - PLEASE UNDERSTAND THESE BEFORE CALLING OR MODIFYING THIS CLASS 48// =========================================================================== 49// 50// 1. This class contains the processes for hosted apps as well as extensions 51// and packaged apps. Just because a process is present here *does not* mean 52// it is an "extension process" (e.g., for UI purposes). It may contain only 53// hosted apps. See crbug.com/102533. 54// 55// 2. An extension can show up in multiple processes. That is why there is no 56// GetExtensionProcess() method here. There are two cases: a) The extension 57// is actually a hosted app, in which case this is normal, or b) there is an 58// incognito window open and the extension is "split mode". It is *not safe* 59// to assume that there is one process per extension. If you only care about 60// extensions (not hosted apps), and you are on the UI thread, and you don't 61// care about incognito version of this extension (or vice versa if you're in 62// an incognito profile) then use 63// extensions::ProcessManager::GetSiteInstanceForURL()->[Has|Get]Process(). 64// 65// 3. The process ids contained in this class are *not limited* to the Profile 66// you got this map from. They can also be associated with that profile's 67// incognito/normal twin. If you care about this, use 68// RenderProcessHost::FromID() and check the profile of the resulting object. 69// 70// TODO(aa): The above warnings suggest this class could use improvement :). 71// 72// TODO(kalman): This class is not threadsafe, but is used on both the UI and 73// IO threads. Somebody should fix that, either make it 74// threadsafe or enforce single thread. Investigation required. 75class ProcessMap : public KeyedService { 76 public: 77 ProcessMap(); 78 virtual ~ProcessMap(); 79 80 // Returns the instance for |browser_context|. An instance is shared between 81 // an incognito and a regular context. 82 static ProcessMap* Get(content::BrowserContext* browser_context); 83 84 size_t size() const { return items_.size(); } 85 86 bool Insert(const std::string& extension_id, int process_id, 87 int site_instance_id); 88 89 bool Remove(const std::string& extension_id, int process_id, 90 int site_instance_id); 91 int RemoveAllFromProcess(int process_id); 92 93 bool Contains(const std::string& extension_id, int process_id) const; 94 bool Contains(int process_id) const; 95 96 std::set<std::string> GetExtensionsInProcess(int process_id) const; 97 98 // Gets the most likely context type for the process with ID |process_id| 99 // which hosts Extension |extension|, if any (may be NULL). Context types are 100 // renderer (JavaScript) concepts but the browser can do a decent job in 101 // guessing what the process hosts. 102 // 103 // |extension| is the funky part - unfortunately we need to trust the 104 // caller of this method to be correct that indeed the context does feature 105 // an extension. This matters for iframes, where an extension could be 106 // hosted in another extension's process (privilege level needs to be 107 // downgraded) or in a web page's process (privilege level needs to be 108 // upgraded). 109 // 110 // The latter of these is slightly problematic from a security perspective; 111 // if a web page renderer gets owned it could try to pretend it's an 112 // extension and get access to some unprivileged APIs. Luckly, when OOP 113 // iframes lauch, it won't be an issue. 114 // 115 // Anyhow, the expected behaviour is: 116 // - For hosted app processes, this will be blessed_web_page. 117 // - For other extension processes, this will be blessed_extension. 118 // - For WebUI processes, this will be a webui. 119 // - For any other extension we have the choice of unblessed_extension or 120 // content_script. Since content scripts are more common, guess that. 121 // We *could* in theory track which web processes have extension frames 122 // in them, and those would be unblessed_extension, but we don't at the 123 // moment, and once OOP iframes exist then there won't even be such a 124 // thing as an unblessed_extension context. 125 // - For anything else, web_page. 126 Feature::Context GetMostLikelyContextType(const Extension* extension, 127 int process_id) const; 128 129 private: 130 struct Item; 131 132 typedef std::set<Item> ItemSet; 133 ItemSet items_; 134 135 DISALLOW_COPY_AND_ASSIGN(ProcessMap); 136}; 137 138} // namespace extensions 139 140#endif // EXTENSIONS_BROWSER_PROCESS_MAP_H_ 141