从微观看chrome 之二:围绕Profile的ProfileService系统

本来要上下简单的uml图,但是不知道怎么穿不上来,就简单描述下巴。

Chrome中profile是一个核心的对象,profile用来进行chrome账户之间的隔离,不用的账户所持有的profile不一样。所有的逻辑或多或少,直接间接的都与他发生关联。大部分的chrome服务类, 都可以通过profile来获取。这些服务类彼此之间相互依赖,提供基础的服务给浏览器的上层使用,本文大概分析下这些服务的实现结构。

实现上来说每个service都有对应的一个继承自ProfileKeyedServiceFactory的一个对应工厂类。工厂类以Singleton<>类为实体存在,维护了每个profile所对应的service的生命周期。ProfileKeyedServiceFactory负责生产service的实体对象,用map保存profile和service之间的对应关系.同时借助于ProfileDependencyManager来维护各个Service之间的互相依赖关系。摘抄一个Service的核心代码如下:

class ExtensionActionManager : public ProfileKeyedService,
                               public content::NotificationObserver {
 public:
  ..........
 
static ExtensionActionManager* Get(Profile* profile)
{
   return ExtensionActionManagerFactory::GetForProfile(profile);
}
.......................
};
class ExtensionActionManagerFactory : public ProfileKeyedServiceFactory {
 public:
  // ProfileKeyedServiceFactory implementation:
  static ExtensionActionManager* GetForProfile(Profile* profile) {
    return static_cast<ExtensionActionManager*>(
        GetInstance()->GetServiceForProfile(profile, true));
  }

  static ExtensionActionManagerFactory* GetInstance();

 private:
  friend struct DefaultSingletonTraits<ExtensionActionManagerFactory>;

  ExtensionActionManagerFactory()
      : ProfileKeyedServiceFactory("ExtensionActionManager",
                                   ProfileDependencyManager::GetInstance()) {
  }

  virtual ProfileKeyedService* BuildServiceInstanceFor(
      Profile* profile) const OVERRIDE {
    return new ExtensionActionManager(profile);
  }

  virtual bool ServiceRedirectedInIncognito() const OVERRIDE {
    return true;
  }
};

ExtensionActionManagerFactory*
ExtensionActionManagerFactory::GetInstance() {
  return Singleton<ExtensionActionManagerFactory>::get();
}

通过ExtensionActionManager::Get函数可以获取到某个profile对应的service,通过上面的代码可以清晰地看到ExtensionActionManagerFactory和ExtensionActionManager之间的关系,要全读懂的话,最好看下ProfileKeyedServiceFactory 的源码。

chrome中的service实现相对来说简单,但是管理service之间依赖关系的ProfileDependencyManager值得研究下. 该类内部已有向图的方式管理各个service, 程序运行时建立起各个服务组件间的依赖关系, 然后通过 有向图排列出 服务的创建和销毁顺序. 把用算法排序的函数超出来看看

void ProfileDependencyManager::BuildDestructionOrder(Profile* profile) {

  // Step 1: Build a set of nodes with no incoming edges.
  std::deque<ProfileKeyedBaseFactory*> queue;
  std::copy(all_components_.begin(),
            all_components_.end(),
            std::back_inserter(queue));

  std::deque<ProfileKeyedBaseFactory*>::iterator queue_end = queue.end();
  for (EdgeMap::const_iterator it = edges_.begin();
       it != edges_.end(); ++it) {
    queue_end = std::remove(queue.begin(), queue_end, it->second);
  }
  queue.erase(queue_end, queue.end());

  // Step 2: Do the Kahn topological sort.
  std::vector<ProfileKeyedBaseFactory*> output;
  EdgeMap edges(edges_);
  while (!queue.empty()) {
    ProfileKeyedBaseFactory* node = queue.front();
    queue.pop_front();
    output.push_back(node);

    std::pair<EdgeMap::iterator, EdgeMap::iterator> range =
        edges.equal_range(node);
    EdgeMap::iterator it = range.first;
    while (it != range.second) {
      ProfileKeyedBaseFactory* dest = it->second;
      EdgeMap::iterator temp = it;
      it++;
      edges.erase(temp);

      bool has_incoming_edges = false;
      for (EdgeMap::iterator jt = edges.begin(); jt != edges.end(); ++jt) {
        if (jt->second == dest) {
          has_incoming_edges = true;
          break;
        }
      }

      if (!has_incoming_edges)
        queue.push_back(dest);
    }
  }

  if (edges.size()) {
    NOTREACHED() << "Dependency graph has a cycle. We are doomed.";
  }

  std::reverse(output.begin(), output.end());
  destruction_order_ = output;
}
原文地址:https://www.cnblogs.com/kwliu/p/3116053.html