Android Chromium 沉浸式地址栏

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

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

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

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

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

plaintext 复制代码
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| 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准备动画,在下一帧绘制时重新计算偏移

plaintext 复制代码
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| Renderer |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

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

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

plaintext 复制代码
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| 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层的呢,代码流程如下:

plaintext 复制代码
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| 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的整体架构兼容的,原生的地址栏偏移通知是滞后一帧的,针对这种情况我们只需要在做偏移的时候,从内核中同步取出准确的地址栏偏移即可,同时还需要处理好事件分发时的坐标偏移。

相关推荐
小码哥_常6 分钟前
你发的原图可能暴露你家地址——聊聊图片 EXIF 隐私
前端
java1234_小锋17 分钟前
【技术专题】CSS3 网页技术 - CSS3 优先级
前端·css·css3
鸿蒙开发2 小时前
共享 Schema 与 SchemaFactory
前端·后端·harmonyos
屏什么录2 小时前
录屏超过两小时就卡顿崩盘?从参数调优到代码实现,一文彻底搞定长时间录屏
前端·音视频开发
计算机魔术师2 小时前
950亿怎么拆:Meta给AI基建配的三档弹药
前端
碳基生物猛吃膳食纤维2 小时前
结合DEEPSEEK和CHATGPT弄了个小脚本,批量检查商品主图
前端
绝世唐门三哥2 小时前
CSS 换行三剑客:overflow-wrap、word-break 与 white-space 完全指南
前端·css
kyriewen2 小时前
别再用防抖做懒加载了:120 张图只加载出 4 张
前端·javascript·程序员
计算机魔术师2 小时前
Hugging Face CEO 转评前 DOGE 研究人员用 AI 智能体渗透 Anthropic 系统事件
前端
IT_陈寒2 小时前
刚解决一个 Java 并发问题,这坑踩得我怀疑人生
前端·人工智能·后端