普通文本  |  157行  |  4.18 KB

// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "extensions/browser/process_map.h"

#include "content/public/browser/child_process_security_policy.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/process_map_factory.h"
#include "extensions/common/extension.h"
#include "extensions/common/features/feature.h"

namespace extensions {

// Item
struct ProcessMap::Item {
  Item() : process_id(0), site_instance_id(0) {
  }

  // Purposely implicit constructor needed on older gcc's. See:
  // http://codereview.chromium.org/8769022/
  explicit Item(const ProcessMap::Item& other)
      : extension_id(other.extension_id),
        process_id(other.process_id),
        site_instance_id(other.site_instance_id) {
  }

  Item(const std::string& extension_id, int process_id,
       int site_instance_id)
      : extension_id(extension_id),
        process_id(process_id),
        site_instance_id(site_instance_id) {
  }

  ~Item() {
  }

  bool operator<(const ProcessMap::Item& other) const {
    if (extension_id < other.extension_id)
      return true;

    if (extension_id == other.extension_id &&
        process_id < other.process_id) {
      return true;
    }

    if (extension_id == other.extension_id &&
        process_id == other.process_id &&
        site_instance_id < other.site_instance_id) {
      return true;
    }

    return false;
  }

  std::string extension_id;
  int process_id;
  int site_instance_id;
};


// ProcessMap
ProcessMap::ProcessMap() {
}

ProcessMap::~ProcessMap() {
}

// static
ProcessMap* ProcessMap::Get(content::BrowserContext* browser_context) {
  return ProcessMapFactory::GetForBrowserContext(browser_context);
}

bool ProcessMap::Insert(const std::string& extension_id, int process_id,
                        int site_instance_id) {
  return items_.insert(Item(extension_id, process_id, site_instance_id)).second;
}

bool ProcessMap::Remove(const std::string& extension_id, int process_id,
                        int site_instance_id) {
  return items_.erase(Item(extension_id, process_id, site_instance_id)) > 0;
}

int ProcessMap::RemoveAllFromProcess(int process_id) {
  int result = 0;
  for (ItemSet::iterator iter = items_.begin(); iter != items_.end(); ) {
    if (iter->process_id == process_id) {
      items_.erase(iter++);
      ++result;
    } else {
      ++iter;
    }
  }
  return result;
}

bool ProcessMap::Contains(const std::string& extension_id,
                          int process_id) const {
  for (ItemSet::const_iterator iter = items_.begin(); iter != items_.end();
       ++iter) {
    if (iter->process_id == process_id && iter->extension_id == extension_id)
      return true;
  }
  return false;
}

bool ProcessMap::Contains(int process_id) const {
  for (ItemSet::const_iterator iter = items_.begin(); iter != items_.end();
       ++iter) {
    if (iter->process_id == process_id)
      return true;
  }
  return false;
}

std::set<std::string> ProcessMap::GetExtensionsInProcess(int process_id) const {
  std::set<std::string> result;
  for (ItemSet::const_iterator iter = items_.begin(); iter != items_.end();
       ++iter) {
    if (iter->process_id == process_id)
      result.insert(iter->extension_id);
  }
  return result;
}

Feature::Context ProcessMap::GetMostLikelyContextType(
    const Extension* extension,
    int process_id) const {
  // WARNING: This logic must match Dispatcher::ClassifyJavaScriptContext, as
  // much as possible.

  if (content::ChildProcessSecurityPolicy::GetInstance()->HasWebUIBindings(
          process_id)) {
    return Feature::WEBUI_CONTEXT;
  }

  if (!extension) {
    return Feature::WEB_PAGE_CONTEXT;
  }

  if (!Contains(extension->id(), process_id)) {
    // This could equally be UNBLESSED_EXTENSION_CONTEXT, but we don't record
    // which processes have extension frames in them.
    // TODO(kalman): Investigate this.
    return Feature::CONTENT_SCRIPT_CONTEXT;
  }

  if (extension->is_hosted_app() &&
      extension->location() != Manifest::COMPONENT) {
    return Feature::BLESSED_WEB_PAGE_CONTEXT;
  }

  return Feature::BLESSED_EXTENSION_CONTEXT;
}

}  // namespace extensions