1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/process_map.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/child_process_security_policy.h"
85f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "extensions/browser/extension_registry.h"
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/process_map_factory.h"
105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "extensions/common/extension.h"
115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "extensions/common/features/feature.h"
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions {
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Item
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ProcessMap::Item {
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Item() : process_id(0), site_instance_id(0) {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Purposely implicit constructor needed on older gcc's. See:
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // http://codereview.chromium.org/8769022/
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit Item(const ProcessMap::Item& other)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : extension_id(other.extension_id),
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        process_id(other.process_id),
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        site_instance_id(other.site_instance_id) {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Item(const std::string& extension_id, int process_id,
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       int site_instance_id)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : extension_id(extension_id),
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        process_id(process_id),
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        site_instance_id(site_instance_id) {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~Item() {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool operator<(const ProcessMap::Item& other) const {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (extension_id < other.extension_id)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (extension_id == other.extension_id &&
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        process_id < other.process_id) {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (extension_id == other.extension_id &&
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        process_id == other.process_id &&
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        site_instance_id < other.site_instance_id) {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string extension_id;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int process_id;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int site_instance_id;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ProcessMap
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProcessMap::ProcessMap() {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProcessMap::~ProcessMap() {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// static
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ProcessMap* ProcessMap::Get(content::BrowserContext* browser_context) {
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return ProcessMapFactory::GetForBrowserContext(browser_context);
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProcessMap::Insert(const std::string& extension_id, int process_id,
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        int site_instance_id) {
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return items_.insert(Item(extension_id, process_id, site_instance_id)).second;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProcessMap::Remove(const std::string& extension_id, int process_id,
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        int site_instance_id) {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return items_.erase(Item(extension_id, process_id, site_instance_id)) > 0;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ProcessMap::RemoveAllFromProcess(int process_id) {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int result = 0;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ItemSet::iterator iter = items_.begin(); iter != items_.end(); ) {
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (iter->process_id == process_id) {
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      items_.erase(iter++);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ++result;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ++iter;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProcessMap::Contains(const std::string& extension_id,
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          int process_id) const {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ItemSet::const_iterator iter = items_.begin(); iter != items_.end();
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ++iter) {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (iter->process_id == process_id && iter->extension_id == extension_id)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProcessMap::Contains(int process_id) const {
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ItemSet::const_iterator iter = items_.begin(); iter != items_.end();
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ++iter) {
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (iter->process_id == process_id)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::set<std::string> ProcessMap::GetExtensionsInProcess(int process_id) const {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::set<std::string> result;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ItemSet::const_iterator iter = items_.begin(); iter != items_.end();
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ++iter) {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (iter->process_id == process_id)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      result.insert(iter->extension_id);
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)Feature::Context ProcessMap::GetMostLikelyContextType(
1276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    const Extension* extension,
1286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    int process_id) const {
1295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // WARNING: This logic must match Dispatcher::ClassifyJavaScriptContext, as
1305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // much as possible.
1315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (content::ChildProcessSecurityPolicy::GetInstance()->HasWebUIBindings(
1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          process_id)) {
1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return Feature::WEBUI_CONTEXT;
1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!extension) {
1385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return Feature::WEB_PAGE_CONTEXT;
1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!Contains(extension->id(), process_id)) {
1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // This could equally be UNBLESSED_EXTENSION_CONTEXT, but we don't record
1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // which processes have extension frames in them.
1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // TODO(kalman): Investigate this.
1455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return Feature::CONTENT_SCRIPT_CONTEXT;
1465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (extension->is_hosted_app() &&
1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      extension->location() != Manifest::COMPONENT) {
1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return Feature::BLESSED_WEB_PAGE_CONTEXT;
1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return Feature::BLESSED_EXTENSION_CONTEXT;
1545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace extensions
157