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 #include "extensions/browser/process_map.h" 6 7 #include "content/public/browser/child_process_security_policy.h" 8 #include "extensions/browser/extension_registry.h" 9 #include "extensions/browser/process_map_factory.h" 10 #include "extensions/common/extension.h" 11 #include "extensions/common/features/feature.h" 12 13 namespace extensions { 14 15 // Item 16 struct ProcessMap::Item { 17 Item() : process_id(0), site_instance_id(0) { 18 } 19 20 // Purposely implicit constructor needed on older gcc's. See: 21 // http://codereview.chromium.org/8769022/ 22 explicit Item(const ProcessMap::Item& other) 23 : extension_id(other.extension_id), 24 process_id(other.process_id), 25 site_instance_id(other.site_instance_id) { 26 } 27 28 Item(const std::string& extension_id, int process_id, 29 int site_instance_id) 30 : extension_id(extension_id), 31 process_id(process_id), 32 site_instance_id(site_instance_id) { 33 } 34 35 ~Item() { 36 } 37 38 bool operator<(const ProcessMap::Item& other) const { 39 if (extension_id < other.extension_id) 40 return true; 41 42 if (extension_id == other.extension_id && 43 process_id < other.process_id) { 44 return true; 45 } 46 47 if (extension_id == other.extension_id && 48 process_id == other.process_id && 49 site_instance_id < other.site_instance_id) { 50 return true; 51 } 52 53 return false; 54 } 55 56 std::string extension_id; 57 int process_id; 58 int site_instance_id; 59 }; 60 61 62 // ProcessMap 63 ProcessMap::ProcessMap() { 64 } 65 66 ProcessMap::~ProcessMap() { 67 } 68 69 // static 70 ProcessMap* ProcessMap::Get(content::BrowserContext* browser_context) { 71 return ProcessMapFactory::GetForBrowserContext(browser_context); 72 } 73 74 bool ProcessMap::Insert(const std::string& extension_id, int process_id, 75 int site_instance_id) { 76 return items_.insert(Item(extension_id, process_id, site_instance_id)).second; 77 } 78 79 bool ProcessMap::Remove(const std::string& extension_id, int process_id, 80 int site_instance_id) { 81 return items_.erase(Item(extension_id, process_id, site_instance_id)) > 0; 82 } 83 84 int ProcessMap::RemoveAllFromProcess(int process_id) { 85 int result = 0; 86 for (ItemSet::iterator iter = items_.begin(); iter != items_.end(); ) { 87 if (iter->process_id == process_id) { 88 items_.erase(iter++); 89 ++result; 90 } else { 91 ++iter; 92 } 93 } 94 return result; 95 } 96 97 bool ProcessMap::Contains(const std::string& extension_id, 98 int process_id) const { 99 for (ItemSet::const_iterator iter = items_.begin(); iter != items_.end(); 100 ++iter) { 101 if (iter->process_id == process_id && iter->extension_id == extension_id) 102 return true; 103 } 104 return false; 105 } 106 107 bool ProcessMap::Contains(int process_id) const { 108 for (ItemSet::const_iterator iter = items_.begin(); iter != items_.end(); 109 ++iter) { 110 if (iter->process_id == process_id) 111 return true; 112 } 113 return false; 114 } 115 116 std::set<std::string> ProcessMap::GetExtensionsInProcess(int process_id) const { 117 std::set<std::string> result; 118 for (ItemSet::const_iterator iter = items_.begin(); iter != items_.end(); 119 ++iter) { 120 if (iter->process_id == process_id) 121 result.insert(iter->extension_id); 122 } 123 return result; 124 } 125 126 Feature::Context ProcessMap::GetMostLikelyContextType( 127 const Extension* extension, 128 int process_id) const { 129 // WARNING: This logic must match Dispatcher::ClassifyJavaScriptContext, as 130 // much as possible. 131 132 if (content::ChildProcessSecurityPolicy::GetInstance()->HasWebUIBindings( 133 process_id)) { 134 return Feature::WEBUI_CONTEXT; 135 } 136 137 if (!extension) { 138 return Feature::WEB_PAGE_CONTEXT; 139 } 140 141 if (!Contains(extension->id(), process_id)) { 142 // This could equally be UNBLESSED_EXTENSION_CONTEXT, but we don't record 143 // which processes have extension frames in them. 144 // TODO(kalman): Investigate this. 145 return Feature::CONTENT_SCRIPT_CONTEXT; 146 } 147 148 if (extension->is_hosted_app() && 149 extension->location() != Manifest::COMPONENT) { 150 return Feature::BLESSED_WEB_PAGE_CONTEXT; 151 } 152 153 return Feature::BLESSED_EXTENSION_CONTEXT; 154 } 155 156 } // namespace extensions 157