Home | History | Annotate | Download | only in browser
      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