当前位置:首页 > 芯闻号 > 充电吧
[导读]一、概述       之前有介绍过chromium的界面层的相关知识,这篇文章则是重点介绍chromium中书签这一个模块,不仅有界面层的知识,还会较多的介绍逻辑层的一些内容。接下来会详细介绍chro

一、概述
       之前有介绍过chromium的界面层的相关知识,这篇文章则是重点介绍chromium中书签这一个模块,不仅有界面层的知识,还会较多的介绍逻辑层的一些内容。接下来会详细介绍chromium中书签功能的详细实现。主要问题有:
              1、书签数据在硬盘和内存中存储结构;
              2、初始化过程;
              3、相关操作的实现步骤;
              4、线程模型;
              5、书签同步。

二、书签结构综述
        Bookmark界面层在..srcchromebrowseruiviewsbookmarks中实现。Bookmark逻辑层在..srcchromebrowserbookmarks 中实现,包括读写书签文件,书签导入导出等。
       书签在整个工程中是chrome特色功能,它包括三种类型,书签栏、其他、和“mobile”。书签栏管理用户创建的所有书签
       作为chromium拓展中心的一个功能,整体流程图如图:
 
    图1 书签整体流程图

       在书签模块中,其中主要的两个模块是底层数据处理和界面显示,具体实现分别在BookmarkModel和BookmarkBarView中,它们之间采用的是observer设计模式,BookmarkModel(具体目标),BookmarkBarView(具体观察者)。

三、书签存储结构
       书签的存储结构需要从配置文件中结构及内存中存储结构两方面分析。
       书签配置文件中存储在本地Bookmarks中,以JSON的格式存储。并在书签模块启动的时候load文件中的书签数据。本地JSON书签数据如下:
         "children": [ {
            "date_added": "12994954482846617",
            "id": "7",
            "name": "Google",
            "type": "url",
            "url": "http://www.google.com.hk/"
         },
       在内存中每个节点对应一个BookmarkNode。其中包含了favicon, id and type等节点信息。
       在BookmarkModel中定义了如下几个节点:
         BookmarkNode root_;
         BookmarkPermanentNode* bookmark_bar_node_;
         BookmarkPermanentNode* other_node_;
         BookmarkPermanentNode* mobile_node_;
       root_作为根节点,是书签栏中节点和“其他”文件夹中节点的父节点。BookmarkPermanentNode只是BookmarkNode一个简单的封装,用来管理书签栏及“其他”等这种固定的文件夹。

四、书签初始化及释放
       书签功能的初始化:可以分为两个部分,数据逻辑层和界面层。从上面的主流程图中我们可以看出,数据逻辑层先于界面层初始化,具体初始化流程如下:
       数据逻辑层:
       初始化流程,拓展中心统一初始化,在ExtensionService::InitEventRouters()中调用
       bookmark_event_router_.reset(new BookmarkExtensionEventRouter(
             BookmarkModelFactory::GetForProfile(profile_)));
             bookmark_event_router_->Init();
       最终在BookmarkModelFactory完成BookmarkModel的创建。另外,BookmarkExtensionEventRouter继承自BookmarkModelObserver,是BookmarkModel的一个具体观察者。会将bookmark中的修改通知装换成event传给extension system
       逻辑层初始化执行顺序如下图:

 
图2 书签数据逻辑层执行
       为防止阻塞UI线程,书签文件的加载是在一个后台进程中完成的,chromium启动的时候,主线程Post出一个文件加载的Task,同时传入了一个回调函数的指针参数,当消息中心处理这个Task时会调用之前传入的回调,并完成书签文件的加载接JSON数据的解析。注意这个步骤是在File加载线程中完成的。加载解析完成后,File加载线程会POST出一个Task,并将操作权交还给主线程,去完成后需初始化工作。
        书签文件的解析是在JSONFileValueSerializer中完成的,在这个里面会将JSON文件反序列化。并将其内容存入BookmarkLoadDetails中,供接下来的调用。

       界面层:
       BookmarkBarView类是BookmarkModel的具体观察者,负责书签数据的渲染布局等,与书签界面层相关的操作主要在这里面实现。
       BookmarkBarView由BrowserView统一管理,BrowserView不会主动创建BookmarkBarView,而是在之后执行需要书签的操作中,如UpdateUIForContents,若书签界面层尚未创建,则执行创建操作,否则跳过。

       书签模块的释放:同样重点完成数据逻辑层和界面层的释放。释放的过程和创建相反。先delete 管理界面模块的BookmarkBarView,这部分功能由BrowserView统一管理释放。之后再进一步delete管理逻辑层的模块BookmarkModel,这部分释放工作在配置文件管理中心统一释放。

五、书签操作执行流程
       书签界面层与逻辑层的类关系图如下。

 
   图3 界面层、逻辑层类关系图
    
       BookmarkModel继承自PofileDeyedService,因而可以实现在配置文件管理中心统一释放
       BookmarkBarView继承自DetachableToolbarView,是一个与Chrome frame分离的view控件。
       BookmarkModel与BookmarkBarView均继承自消息中心NotificationObserver,并会通过registrar_注册自己需要接受的通知。

       BookmarkModel类中的实现。它是是observer模式中的具体目标及数据逻辑层的核心实现。BookmarkModel对象需要通过 BookmarkModelFactory才能创建,而不能直接创建。
       BookmarkModel类管理者内存中的书签数据,也向外提供了很多的操作接口,如AddNode、RemoveAndDeleteNode、RemoveNode等。用户操作书签时,都会通过调用这些接口来修改书签内容。
       在BookmarkModel中通过定义一个BookmarkStorage的对象来操作书签的磁盘读写,上面提到的文件加载就是通过这个对象来执行的。另外,当书签数据与磁盘同步也在   这个里面完成,当用户修改了书签内容时,会调用其中的ScheduleSave()函数写回磁盘。
       书签磁盘读写的类图如下:
 

  图4 书签磁盘读写类图
       其中BookmarkLoadDetails是用来临时存储书签数据的对象。

       BookmarkBarView类派生自BookmarkModelObserver,是observer模式中一个具体的观察者。中完成书签界面展示以及部分用户操作。

       另外,书签栏内部的子文件夹显示也存在菜单栏的弹出,包括点击文件夹及拖动书签节点至文件夹都会弹出。BookmarkBarView中定义了两个菜单对书签栏的子菜单进行管理:
         BookmarkMenuController* bookmark_menu_;
         BookmarkMenuController* bookmark_drop_menu_;
       其中bookmark_menu_用于管理用户点击BookmarkBarView中的文件夹时弹出的菜单(BookmarkBarView是MenuButtonListener的子类,可以收听到这个事件)。bookmark_drop_menu_是用户拖拽一个node到文件夹上时弹出的菜单。


 
图5 书签右键菜单实现类图

       Chromium中书签最基本的操作有添加、删除、修改等。同时,用户操作书签的方式也有很多,如快捷键,主菜单,书签右键菜单等。书签操作的执行顺序基本如下。

 

图6 书签操作执行顺序


       书签的显示实现
       在chromium的代码中,每次调用网页时都会调用void Browser::UpdateBookmarkBarState(BookmarkBarStateChangeReason reason),用以判断是否需要显示书签,书签有三种状态,SHOW(显示与地址栏不分离)、DETACHED(显示与地址栏分离)、HIDDEN(不显示)。
[cpp] view plaincopy void Browser::UpdateBookmarkBarState(BookmarkBarStateChangeReason reason) {     BookmarkBar::State state;     // The bookmark bar is hidden in fullscreen mode, unless on the new tab page.     if (browser_defaults::bookmarks_enabled &&         profile_->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar) &&         (!window_ || !window_->IsFullscreen())) {       state = BookmarkBar::SHOW;     } else {       WebContents* web_contents = chrome::GetActiveWebContents(this);       BookmarkTabHelper* bookmark_tab_helper =           web_contents ? BookmarkTabHelper::FromWebContents(web_contents) : NULL;       if (bookmark_tab_helper && bookmark_tab_helper->ShouldShowBookmarkBar())         state = BookmarkBar::DETACHED;       else         state = BookmarkBar::HIDDEN;     }        // Only allow the bookmark bar to be shown in default mode.     if (!search_model_->mode().is_default())       state = BookmarkBar::HIDDEN;        if (state == bookmark_bar_state_)       return;        bookmark_bar_state_ = state;        if (!window_)       return;  // This is called from the constructor when window_ is NULL.        if (reason == BOOKMARK_BAR_STATE_CHANGE_TAB_SWITCH) {       // Don't notify BrowserWindow on a tab switch as at the time this is invoked       // BrowserWindow hasn't yet switched tabs. The BrowserWindow implementations       // end up querying state once they process the tab switch.       return;     }        BookmarkBar::AnimateChangeType animate_type =         (reason == BOOKMARK_BAR_STATE_CHANGE_PREF_CHANGE) ?         BookmarkBar::ANIMATE_STATE_CHANGE :         BookmarkBar::DONT_ANIMATE_STATE_CHANGE;     window_->BookmarkBarStateChanged(animate_type);   }  
       在这个函数中最终会调用window_->BookmarkBarStateChanged(animate_type),其中会调用到BrowserView的实现中,再由其中的bookmark_bar_view_来统一接手管理界面的工作。

       书签栏中点击打开网页
       当从书签栏中点击打开网页时,先会调用void BookmarkBarView::ButtonPressed函数,并在此函数中会调用page_navigator_->OpenURL(params);进一步调用WebContentsImple相应的方法来实现。

       当前页直接添加书签
       将当前页添加到书签则会调用void BookmarkCurrentPage(Browser* browser)(browser_commands.cc中的全局函数),再调用void BrowserView::ShowBookmarkBubble(const GURL& url, bool already_bookmarked)最终是在BookmarkBubbleView中完成。

六、书签线程模型
       在整个书签模块中,除了文件读取是在后台File线程中完成外,其余操作均在主线程中执行,线程执行方法与整个chromium的线程模型保持一致。
       为了保证书签文件在加载是不出现线程安全问题,chromium中设计了一个BookmarkStorage的中间层来读写书签文件,并在BookmarkStorage中定义了一个BookmarkLoadDetails,通过操作它来加载书签文件中的详细信息。加载完成后回调到主线程,并把所有权交还给BookmarkModel。但BookmarkModel中没有对BookmarkLoadDetails的引用,不能直接操作其中的内容,这样就确保解决了线程可能带来的问题。

七、登陆后书签同步
       用户登陆成功后,数据同步中心会对相关数据进行同步,书签也包括在内。在Chromium中会由browser_sync同步中心统一管理用户同步相关操作。BookmarkModelAssociator负责实现bookmark model 和sync model之间的联系算法、为sync node 及bookmark node之间的相互获取提供方法。同步完成后最终会调用BookmarkModel的相关方法来实现书签的更新。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

9月2日消息,不造车的华为或将催生出更大的独角兽公司,随着阿维塔和赛力斯的入局,华为引望愈发显得引人瞩目。

关键字: 阿维塔 塞力斯 华为

加利福尼亚州圣克拉拉县2024年8月30日 /美通社/ -- 数字化转型技术解决方案公司Trianz今天宣布,该公司与Amazon Web Services (AWS)签订了...

关键字: AWS AN BSP 数字化

伦敦2024年8月29日 /美通社/ -- 英国汽车技术公司SODA.Auto推出其旗舰产品SODA V,这是全球首款涵盖汽车工程师从创意到认证的所有需求的工具,可用于创建软件定义汽车。 SODA V工具的开发耗时1.5...

关键字: 汽车 人工智能 智能驱动 BSP

北京2024年8月28日 /美通社/ -- 越来越多用户希望企业业务能7×24不间断运行,同时企业却面临越来越多业务中断的风险,如企业系统复杂性的增加,频繁的功能更新和发布等。如何确保业务连续性,提升韧性,成...

关键字: 亚马逊 解密 控制平面 BSP

8月30日消息,据媒体报道,腾讯和网易近期正在缩减他们对日本游戏市场的投资。

关键字: 腾讯 编码器 CPU

8月28日消息,今天上午,2024中国国际大数据产业博览会开幕式在贵阳举行,华为董事、质量流程IT总裁陶景文发表了演讲。

关键字: 华为 12nm EDA 半导体

8月28日消息,在2024中国国际大数据产业博览会上,华为常务董事、华为云CEO张平安发表演讲称,数字世界的话语权最终是由生态的繁荣决定的。

关键字: 华为 12nm 手机 卫星通信

要点: 有效应对环境变化,经营业绩稳中有升 落实提质增效举措,毛利润率延续升势 战略布局成效显著,战新业务引领增长 以科技创新为引领,提升企业核心竞争力 坚持高质量发展策略,塑强核心竞争优势...

关键字: 通信 BSP 电信运营商 数字经济

北京2024年8月27日 /美通社/ -- 8月21日,由中央广播电视总台与中国电影电视技术学会联合牵头组建的NVI技术创新联盟在BIRTV2024超高清全产业链发展研讨会上宣布正式成立。 活动现场 NVI技术创新联...

关键字: VI 传输协议 音频 BSP

北京2024年8月27日 /美通社/ -- 在8月23日举办的2024年长三角生态绿色一体化发展示范区联合招商会上,软通动力信息技术(集团)股份有限公司(以下简称"软通动力")与长三角投资(上海)有限...

关键字: BSP 信息技术
关闭
关闭