Android Chromium 沉浸式地址栏

地址栏是如何与网页联动的

地址栏在chromium内核中只是一个虚拟的概念,通过Android的开发者模式来观察Chrome浏览器的地址栏我们会发现,地址栏是一个原生的控件,他与网页是无关的,chromium在内核中根据用户的滑动手势,动态的调整网页viewport的偏移同时将偏移位置通知到应用层,应用层基于此偏移动态的调整地址栏控件的偏移位置(margin or translation)从而达到地址栏与网页根据用户手势沉浸式联动的效果。

BrowserControlsOffsetManager是内核中地址栏概念的管理类,它的主要职责有:

1. 管理当前地址栏的模式(仅显示、仅隐藏、自动)
2. 根据网页滑动事件计算当前地址栏的偏移
3. 当用户手势抬起后决定是否启用动画展示或者隐藏地址栏

网页滑动时代码处理流程如下:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| Renderer |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
viewport.ScrollBy
  |-->ShouldBrowserControlsConsumeScroll [If Result True]
    |-->ScrollBrowserControls
      |-->host_impl_->browser_controls_manager()->ScrollBy
        |-->BrowserControlsOffsetManager.ScrollBy [Compute Scroll Delta For TopControls]

BrowserControlsOffsetManager依据网页滚动计算偏移用于:
1、通知偏移值到Browser,从而通知地址栏更新位置
2、记录偏移值,再松手后决定是显示还是隐藏地址栏

自动动画显示或者隐藏时代码处理流程如下:

收到滑动事件结束后BrowserControlsOffsetManager准备动画,在下一帧绘制时重新计算偏移

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| Renderer |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

BrowserControlsOffsetManager.ScrollEnd
  |-->StartAnimationIfNecessary
  |-->SetupAnimation

在Render收到绘制指令时BrowserControlsOffsetManager通过动画插值器计算偏移,同时根据动画状态决定是否继续触发下一次绘制

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| Renderer |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SynchronousCompositorProxy.BeginFrame
  |-->SynchronousLayerTreeFrameSink.BeginFrame
    |-->viz::ExternalBeginFrameSource[begin_frame_source.cc].onBeginFrame
      |-->FilterAndIssueBeginFrame
        |-->BeginFrameObserver.OnBeginFrame
        |-->BeginFrameObserBase[extends BeginFrameObserver].OnBeginFrame
          |-->BeginFrameObserBase[begin_frame_source.cc].OnBeginFrameDerivedImpl
          |-->Scheduler[extends BeginFrameObserverBase].OnBeginFrameDerivedImpl
            |-->BeginImplFrameSynchronous
              |-->BeginImplFrame
                |-->SchedulerClient.WillBeginImplFrame
                |-->ProxyImpl[extends SchedulerClient].WillBeginFrame
                  |-->LayerTreeHostImpl.WillBeginImplFrame
                    |-->Animate
                      |-->AnimateInternal
                        |-->AnimateBrowserControls
                          |-->BrowserControlsOffsetManager.Animat [计算偏移]
                          |-->viewport.ScrollBy [滚动网页窗口]

基于Chromium内核实现一个地址栏

前面说了BrowserControlsOffsetMnanager管理了地址栏的偏移,那么他是如何通知到Android层的呢,代码流程如下:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| Renderer |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

SynchronousCompositorProxy.DemandDrawHwAsync [Browser发起绘制]
  |-->DemandDraw
    |-->SynchronousLayerTreeFrameSink.DemandDrawHw
      |-->InvokeComposite
        |-->LayerTreeFrameSinkClient.onDraw
        |-->LayerTreeHostImpl[extends LayerTreeFrameSinkClient].onDraw
          |-->LayerTreeHostImplClient.OnDrawForLayerTreeFrameSink
          |-->ProxyImpl[extends LayerTreeHostImplClient].OnDrawForLayerTreeFrameSink
            |-->Scheduler.OnDrawForLayerTreeFrameSink
              |-->OnBeginImplFrameDeadline
                |-->ProcessScheduledActions
                  |-->DrawIfPossible
                    |-->SchedulerClient.ScheduledActionDrawIfPossible
                    |-->ProxyImpl[extends SchedulerClient].ScheduledActionDrawIfPossible
                      |-->DrawInternal
                        |-->LayerTreeHostImpl.DrawLayers
                          |-->GenerateCompositorFrame
                            |-->MakeRenderFrameMetadata [设置最新的地址栏偏移参数]
                            |-->RenderFrameMetadataObserver.OnRenderFrameSubmission
                            |-->RenderFrameMetadataObserverImpl[extends RenderFrameMetadataObserver].OnRenderFrameSubmission
                              |-->cc::mojom::blink::RenderFrameMetadataObserverClient.OnRenderFrameMetadataChanged [IPC调用,通知Browser] ----|
                                                                                                                                            |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| Browser |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                                   |
                                                                                                                                            |
RenderFrameMetadataProviderImpl.OnRenderFrameMetadataChanged ---------------------------------mojom-----------------------------------------|
  |-->RenderFrameMetadataProvider::Observer.OnRenderFrameMetadataChangedBeforeActivation
  |-->RenderWidgetHostViewAndroid[extends RenderFrameMetadataProvider::Observer].OnRenderFrameMetadataChangedBeforeActivation
    |-->UpdateControls [按需更新地址栏偏移]
      |-->ViewAndroid.OnTopControlsChanged
        |-->Java_ViewAndroidDelegate_onTopControlsChanged
        |-->ViewAndroidDelegate.onTopControlsChanged [通知到Java端]

因此想要实现一个自己的地址栏效果,我们只需要根据ViewAndroidDelgate中的onTopControlsChanged偏移参数,动态的调整地址栏的偏移

至此,我们了解了地址栏的生效流程,并且也可以基于此完成一个基于chromium内核的定制化地址栏,需要注意一点的是它的设计仅仅是与chromium或者chrome的整体架构兼容的,原生的地址栏偏移通知是滞后一帧的,针对这种情况我们只需要在做偏移的时候,从内核中同步取出准确的地址栏偏移即可,同时还需要处理好事件分发时的坐标偏移。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值