显示图形系统分析之开发者模式中打开刷新率显示流程分析

1,362 阅读13分钟

「这是我参与2022首次更文挑战的第3天,活动详情查看:2022首次更文挑战」。

在开发者模式中有一个显示刷新频率的开关,打开后在手机系统的左上角会绘制一个当前屏幕刷新频率的数字,那么它是如何来实现的呢?

开发者模式中,显示刷新屏幕开关的设定应是在ShowRefreshRatePreferenceController.java文件中进行控制的,因此,我们从此处开始分析下显示刷新率逻辑。

分析Settings应用的话,应该明确在继承自DeveloperOptionsPreferenceController类的对象在初始化的时候,应是首先调用其单参(Context类)构造函数,因此

static final String SURFACE_FLINGER_SERVICE_KEY = "SurfaceFlinger";
 
public ShowRefreshRatePreferenceController(Context context) {
    super(context);
    // 获取SurfaceFlinger服务
    mSurfaceFlinger = ServiceManager.getService(SURFACE_FLINGER_SERVICE_KEY);
}

可以看到,此处主要是通过ServiceManager来获取到SurfaceFlinger服务

此后,当我们切换显示刷新屏幕的菜单的时候,会调用其onPreferenceChange函数,因此

@Override

public boolean onPreferenceChange(Preference preference, Object newValue) {
    // 当前设置的开关的值
    final boolean isEnabled = (Boolean) newValue;
    // 写入显示屏幕刷新事件给到SurfaceFlinger服务
    // 并更新当前显示刷新率的菜单开关
    writeShowRefreshRateSetting(isEnabled);
    return true;
}

@VisibleForTesting
void writeShowRefreshRateSetting(boolean isEnabled) {
    try {
        if (mSurfaceFlinger != null) {
           // 1. SurfaceFlinger通信并传递信息
            final Parcel data = Parcel.obtain();
           // 设置interface token为”android.os.ISurfaceComposer”
            data.writeInterfaceToken(SURFACE_COMPOSER_INTERFACE_KEY);
           // 设置信息
            final int showRefreshRate = isEnabled ? SETTING_VALUE_ON : SETTING_VALUE_OFF;
            data.writeInt(showRefreshRate);
           // binder机制,调用SurfaceFlinger的transact函数
           // 注意,此处由于不需要有Binder反馈,因此此处reply设置为null
           // 传递的code为1034
            mSurfaceFlinger.transact(SURFACE_FLINGER_CODE, data,
                    null /* reply */, 0 /* flags */);
            data.recycle();
        }
    }
    // .....catch异常,省略
    // 2. 更新当前的显示屏幕刷新菜单开关
    updateShowRefreshRateSetting();
}

因此

SurfaceFlinger通信并传递信息

由上述的代码分析可知,最终会调用SurfaceFlinger的transact函数,因此

status_t BBinder::transact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    data.setDataPosition(0);
    status_t err = NO_ERROR;
    switch (code) {
        // ......其他条件均不满足,会进入default分支
        default:
           // 调用SurfaceFlinger的onTransact函数
            err = onTransact(code, data, reply, flags);
            break;
    }
    // ...... 此处为不走的代码,省略
    return err;
}

最终会调用到onTransact函数,且传递的code为1034

status_t SurfaceFlinger::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
                                    uint32_t flags) {
    status_t credentialCheck = CheckTransactCodeCredentials(code);
    if (credentialCheck != OK) {
        return credentialCheck;
    }
 
    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
        // 判断interface token是否是android.os.ISurfaceComposer
        CHECK_INTERFACE(ISurfaceComposer, data, reply);
        // ...... 获取调用的主体是否具有system权限,
        // 且是否有android.permission.HARDWARE_TEST权限
        int n;
        switch (code) {
            // ......无关的分支,省略
            case 1034: {
               // 获取此前设定的数据信息,打开 or 关闭
                switch (n = data.readInt32()) {
                    case 0:
                    case 1:
                      // 调用打开或者关闭屏幕刷新率函数
                        enableRefreshRateOverlay(static_cast<bool>(n));
                        break;
                    default: {
                        Mutex::Autolock lock(mStateLock);
                        reply->writeBool(mRefreshRateOverlay != nullptr);
                    }
                }
                return NO_ERROR;
            }
            // ...... 无关分支,省略
        }
    }
    return err;
}

调用enableRefreshRateOverlay函数处理

void SurfaceFlinger::enableRefreshRateOverlay(bool enable) {
    // 1. 生成schedule函数返回值指针
    static_cast<void>(schedule([=] {
        // 2. 初始化指向RefresnRateOverlay对象的指针
        // 这边可以看到,当enable为false的时候,即关闭显示屏幕刷新率的时候,直接不初始化
        // 只有在enable为true的时候,即打开显示屏幕刷新率的时候才会初始化对象
        std::unique_ptr<RefreshRateOverlay> overlay;
        if (enable) {
            overlay = std::make_unique<RefreshRateOverlay>(*this);
        }
        {
            Mutex::Autolock lock(mStateLock);
            // Destroy the layer of the current overlay, if any, outside the lock.
            mRefreshRateOverlay.swap(overlay);
            // 当关闭刷新屏幕刷新率的时候,直接退出不做处理
            // 打开开关的情况,跳过这边代码,进入下个分析阶段
            if (!mRefreshRateOverlay) return;
            // 3. 获取当前系统的默认显示设备DeviceDisplay对象,并且设置其显示区域
            if (const auto display = getDefaultDisplayDeviceLocked()) {
                mRefreshRateOverlay->setViewport(display->getSize());
            }
            // 4. RefreshRateOverlay的刷新率变化函数
            mRefreshRateOverlay->changeRefreshRate(
                    mRefreshRateConfigs->getCurrentRefreshRate());
        }
    }));
}

这段代码可以看到,当关闭显示屏幕刷新率的时候,直接不做任何处理并退出,只有当打开显示屏幕刷新率的时候,才会做其他处理,此处我们只分析打开显示屏幕刷新率的情况,因此,按照以下步骤分析

schedule函数的具体实现

首先看这个函数的定义和实现

template <typename F, typename T>
inline std::future<T> SurfaceFlinger::schedule(F&& f) {
    // 生成一个std::pair结构体对象,第一个参数为Task对象,
    // 第二个参数为Task对象的mTask封装的函数,即传入参数
    auto [task, future] = makeTask(std::move(f));
    // 发送消息处理
    // 最终会调用task指针对象的handleMessage函数,此处不做分析,有兴趣可以自行看下
    mEventQueue->postMessage(std::move(task));
    // 返回函数指针
    return std::move(future);
}
 
MessageQueue.h
template <typename F>
inline auto makeTask(F&& f) {
    // 初始化Task指针对象
    sp<Task<F>> task = new Task<F>(std::move(f));
    // 生成pair,第一个参数为task对象,第二个参数为其mTask封装的函数指针
    return std::make_pair(task, task->mTask.get_future());
}

template <typename F>
class Task : public MessageHandler {
    template <typename G>
    friend auto makeTask(G&&);
    explicit Task(F&& f) : mTask(std::move(f)) {}
    void handleMessage(const Message&) override { mTask(); }
    using T = std::invoke_result_t<F>;
    std::packaged_task<T()> mTask;
};

可以看到,这段代码最终的结果是schedule函数中的参数函数指针对应的函数被运行

初始化指向RefresnRateOverlay对象的指针

初始化直接使用其构造函数

RefreshRateOverlay::RefreshRateOverlay(SurfaceFlinger& flinger)
      : mFlinger(flinger), mClient(new Client(&mFlinger)) {
    createLayer();
    primeCache();
}

从这边可以看到,首先初始化一个指向Client对象的指针,然后调用createLayer函数创建一个Surface,最后调用primeCache渲染

当然我们重点看下后面两个步骤

RefreshRateOverlay::createLayer

bool RefreshRateOverlay::createLayer() {
    // 调用SurfaceFlinger::createLayer函数初始化一个Layer指针对象
    // 注意,此处的Layer的大小,这边传入的是
    // static constexpr uint32_t DIGIT_HEIGHT = 100;
    // static constexpr uint32_t BUFFER_HEIGHT = DIGIT_HEIGHT;
    // static constexpr uint32_t BUFFER_WIDTH = 3 * DIGIT_WIDTH + 2 * DIGIT_SPACE;
    // static constexpr uint32_t DIGIT_WIDTH = 64;
    // static constexpr uint32_t DIGIT_SPACE = 16;
    const status_t ret =
            mFlinger.createLayer(String8("RefreshRateOverlay"), mClient,
                      SevenSegmentDrawer::getWidth(), SevenSegmentDrawer::getHeight(),
                      PIXEL_FORMAT_RGBA_8888,
                      ISurfaceComposerClient::eFXSurfaceBufferState, LayerMetadata(),
                      &mIBinder, &mGbp, nullptr);
    // ...... 容错判断,此处省略
    Mutex::Autolock _l(mFlinger.mStateLock);
    // 获取刚刚创建的Layer指针对象
    mLayer = mClient->getLayerUser(mIBinder);
    // 设置Layer的帧率
    mLayer->setFrameRate(Layer::FrameRate(0, Layer::FrameRateCompatibility::NoVote));
    // setting Layer's Z requires resorting layersSortedByZ
    // 设置Layer的z轴
    ssize_t idx = mFlinger.mCurrentState.layersSortedByZ.indexOf(mLayer);
    if (mLayer->setLayer(INT32_MAX - 2) && idx >= 0) {
        mFlinger.mCurrentState.layersSortedByZ.removeAt(idx);
        mFlinger.mCurrentState.layersSortedByZ.add(mLayer);
    }
    return true;
}

这边

首先使用SurfaceFlinger::createLayer初始化一个Layer指针对象

status_t SurfaceFlinger::createLayer(const String8& name, const sp<Client>& client, uint32_t w,
                                     uint32_t h, PixelFormat format, uint32_t flags,
                                     LayerMetadata metadata, sp<IBinder>* handle,
                                     sp<IGraphicBufferProducer>* gbp,
                                     const sp<IBinder>& parentHandle,
const sp<Layer>& parentLayer,
                                     uint32_t* outTransformHint) {
    // ...... 错误判断代码,省略
    status_t result = NO_ERROR;
    sp<Layer> layer;
    // 获取Layer的名称
    std::string uniqueName = getUniqueLayerName(name.string());
    bool primaryDisplayOnly = false;
    // ...... 判断Window Type,此处不会进入,省略
    switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
        // ...... 不会进入,此处省略
        case ISurfaceComposerClient::eFXSurfaceBufferState:
            result = createBufferStateLayer(client, std::move(uniqueName), w, h, flags,
                                            std::move(metadata), handle, &layer);
            break;
        // ...... 不会进入,此处省略
    }
    // ...... 错误判断代码,省略
    // 判断是否有权限
    bool addToCurrentState = callingThreadHasUnscopedSurfaceFlingerAccess();
    // 添加到mLayers集合
    result = addClientLayer(client, *handle, *gbp, layer, parentHandle, parentLayer,
                            addToCurrentState, outTransformHint);
    if (result != NO_ERROR) {
        return result;
    }
    mInterceptor->saveSurfaceCreation(layer);
    // 通知绘制
    setTransactionFlags(eTransactionNeeded);
    return result;
}

在这边

首先通过createBufferStateLayer函数创建一个Layer对象
status_t SurfaceFlinger::createBufferStateLayer(const sp<Client>& client, std::string name,
                                                uint32_t w, uint32_t h, uint32_t flags,
                                                LayerMetadata metadata, sp<IBinder>* handle,
                                                sp<Layer>* outLayer) {
    // 整合参数
    LayerCreationArgs args(this, client, std::move(name), w, h, flags, std::move(metadata));
    args.textureName = getNewTexture();
    // 创建指向BufferStateLayer对象的指针
    sp<BufferStateLayer> layer = getFactory().createBufferStateLayer(args);
    // 获取Layer对应的索引,注意,此处是给传入参数handle赋值
    *handle = layer->getHandle();
    // 赋值操作,注意是令传入参数outLayer指向刚刚创建的BufferStateLayer对象
    *outLayer = layer;
    return NO_ERROR;
}

sp<BufferStateLayer> DefaultFactory::createBufferStateLayer(const LayerCreationArgs& args) {
    // 初始化一个指向BufferStateLayer的指针
    return new BufferStateLayer(args);
}

BufferStateLayer::BufferStateLayer(const LayerCreationArgs& args)
      : BufferLayer(args), mHwcSlotGenerator(new HwcSlotGenerator()) {
    // 设置BufferStateLayer对象的参数
    mOverrideScalingMode = NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW;
    mCurrentState.dataspace = ui::Dataspace::V0_SRGB;
}

如上,会初始化一个指向BufferStateLayer对象的指针

Layer::onFirstRef

在此处,有必要看下BufferStateLayer的家族

classDiagram
Layer <|-- BufferLayer
BufferLayer <|-- BufferStateLayer
Layer : +sp<SurfaceFlinger> mFlinger
Layer : +sp<Client> mClientRef
Layer : +onFirstRefs()

因此,在BufferStateLayer指针对象初始化的时候,需要调用其onFirstRefs函数,从而从继承关系中可以看到最终会调用Layer::onFirstRefs函数,也即

void Layer::onFirstRef() {
    mFlinger->onLayerFirstRef(this);
}

void SurfaceFlinger::onLayerFirstRef(Layer* layer) {
    // 创建一个Layer对象,在SurfaceFlinger中的Layer数量要加1
    mNumLayers++;
    // 调用Scheduler的registerLayer函数,注册Layer
    mScheduler->registerLayer(layer);
}

void Scheduler::registerLayer(Layer* layer) {
    if (!mLayerHistory) return;
    // 这边是获取系统支持的最小屏幕刷新率以及最大屏幕刷新率
    // 这边的RefreshRateConfigs对象是在系统启动之后,从HwComposer中获取到的RefreshRateConfig
    const auto minFps = mRefreshRateConfigs.getMinRefreshRate().getFps();
    const auto maxFps = mRefreshRateConfigs.getMaxRefreshRate().getFps();
    // Layer在创建的时候,window type未设置,值为0
    if (layer->getWindowType() == InputWindowInfo::TYPE_STATUS_BAR) {
        // ......此处无法进入,省略
    } else if (!mUseContentDetection) {
        // If the content detection feature is off, all layers are registered at Max.
        // We still keep the layer history, since we use it for other features
        // (like Frame Rate API), so layers still need to be registered.
        // 主要通过LayerHistoryV2对象的registerLayer函数,
        // 初始化LayerInfo对象添加到mLayerInfos中,
        // 并设定LayerInfo的类型为scheduler::LayerHistory::LayerVoteType::Max
        mLayerHistory->registerLayer(layer, minFps, maxFps,
                         scheduler::LayerHistory::LayerVoteType::Max);
    }
    // ......else分支无法进入,省略
}

可见,在创建完Layer对象后,均需要在Scheduler中对这些Layer的信息进行注册

SurfaceFlinger::addClientLayer
result = addClientLayer(client, *handle, *gbp, layer, parentHandle, parentLayer,
                            addToCurrentState, outTransformHint);

status_t SurfaceFlinger::addClientLayer(const sp<Client>& client, const sp<IBinder>& handle,
                                        const sp<IGraphicBufferProducer>& gbc, const sp<Layer>& lbc,
                                        const sp<IBinder>& parentHandle,
                                        const sp<Layer>& parentLayer, bool addToCurrentState,
                                        uint32_t* outTransformHint) {
    // add this layer to the current state list
    {
        Mutex::Autolock _l(mStateLock);
        sp<Layer> parent;
        // ...... 判断函数无法进入,省略
        parent = parentLayer;
        // ...... 判错机制,省略(当Layer数量大于4096的时候,提示NO_MOMERY)
        // 添加到Local binder token
        mLayersByLocalBinderToken.emplace(handle->localBinder(), lbc);
 
        if (parent == nullptr && addToCurrentState) {
            mCurrentState.layersSortedByZ.add(lbc);
        }
        // ...... 无法走入代码,省略
        // 此处会根据默认系统的变化参数,对当前的Layer进行对应的处理
        if (const auto display = getDefaultDisplayDeviceLocked()) {
            lbc->updateTransformHint(display->getTransformHint());
        }
        // ...... 无法进入代码,省略
        mLayersAdded = true;
    }
    // attach this layer to the client
    // 将当前的Layer的索引handle和对应的Layer组成键值对,添加到Client::mLayers
    client->attachLayer(handle, lbc);
    return NO_ERROR;
}
总结

此处通过SurfaceFlinger::createLayer函数初始化了一个BufferStateLayer指针对象,通过Layer::onFirstRef函数将刚创建的BufferStateLayer对象注册到LayerHistory中,最后通过SurfaceFlinger::addClientLayer函数,将初始化的BufferStateLayer添加到Client::mLayers,且对BufferStateLayer对象作出系统变换带来的一些变动

BufferStateLayer配置

在创建完成BufferStateLayer之后,会对这个Layer进行一些必要的设置,设置这个Layer图层在屏幕的最上方,即z轴的较大值(INT32_MAX – 2)

RefreshRateOverlay::primeCache

void RefreshRateOverlay::primeCache() {
    // 这边会从RefreshRateConfigs中获取到所有支持的刷新率配置,
    // 这些数据是在SurfaceFlinger在初始化的过程中,从HardwareComposer中获取到的
    auto& allRefreshRates = mFlinger.mRefreshRateConfigs->getAllRefreshRates();
    // 若系统显示设备只支持一种系统刷新率,则直接获取其刷新率数值
    // SevenSegmentDrawer::drawNumber函数会根据对应的数据和信息将对应的buffer数据写入到初始化的GraphicBuffer中
    // 并且将刷新率和SevenSegmentDrawer::drawNumber获取到的GraphicBuffer作为键值对存储在mBufferCache中
    if (allRefreshRates.size() == 1) {
        auto fps = allRefreshRates.begin()->second->getFps();
        half4 color = {LOW_FPS_COLOR, ALPHA};
        mBufferCache.emplace(fps, SevenSegmentDrawer::drawNumber(fps, color));
        return;
    }
    // 若系统显示设备支持的屏幕刷新率不止一种,则对其进行相对应的处理
    std::vector<uint32_t> supportedFps;
    supportedFps.reserve(allRefreshRates.size());
    for (auto& [ignored, refreshRate] : allRefreshRates) {
        supportedFps.push_back(refreshRate->getFps());
    }
    // 需要先将刷新率按照刷新率大小来排序
    std::sort(supportedFps.begin(), supportedFps.end());
    const auto mLowFps = supportedFps[0];
    const auto mHighFps = supportedFps[supportedFps.size() - 1];
    // 根据当前的刷新率来生成对应的颜色,并使用SeventSegmentDrawer::drawNumber函数来分别
    // 生成对应的GraphicBuffer,并且和其对应的屏幕刷新率组成键值对添加到mBufferCache中
    for (auto fps : supportedFps) {
        const auto fpsScale = float(fps - mLowFps) / (mHighFps - mLowFps);
        half4 color;
        color.r = HIGH_FPS_COLOR.r * fpsScale + LOW_FPS_COLOR.r * (1 - fpsScale);
        color.g = HIGH_FPS_COLOR.g * fpsScale + LOW_FPS_COLOR.g * (1 - fpsScale);
        color.b = HIGH_FPS_COLOR.b * fpsScale + LOW_FPS_COLOR.b * (1 - fpsScale);
        color.a = ALPHA;
        mBufferCache.emplace(fps, SevenSegmentDrawer::drawNumber(fps, color));
    }
}

总结

通过如上的代码可知,在初始化RefreshRateOverlay指针对象的时候,会

1.通过SurfaceFlinger的createLayer函数创建对应的BufferStateLayer图层,并且添加到Client::mLayers中进行管理

2.创建每个显示设备支持屏幕刷新率对应的GraphicBuffer对象(并绘制对应的屏幕上需要显示的视图),并添加到mBufferCache中

获取系统默认显示设备对象,并设置其显示区域

调用代码如下

// 这边会调用getDefaultDisplayDeviceLocked函数来获取默认的显示设备DisplayDevice对象
// 这个对象在SurfaceFlinger初始化的过程中,当SurfaceFlinger的init函数中,
// 调用HwComposer的setConfiguration函数时,由驱动测的Composer对象返回给系统一个设备添加的消息
// 从而触发默认显示设备的加载并获取默认DisplayDevice对象
if (const auto display = getDefaultDisplayDeviceLocked()) {
    // 此后获取默认DeviceDisplay对象的显示区域,并设置给上述创建的BufferStateLayer对象
    mRefreshRateOverlay->setViewport(display->getSize());
}

如上描述,因此

void RefreshRateOverlay::setViewport(ui::Size viewport) {
    Rect frame(viewport.width >> 3, viewport.height >> 5);
    frame.offsetBy(viewport.width >> 5, viewport.height >> 4);
    // 设置BufferStateLayer对象的frame
    mLayer->setFrame(frame);
    mFlinger.mTransactionFlags.fetch_or(eTransactionMask);
}

bool BufferStateLayer::setFrame(const Rect& frame) {
    int x = frame.left;
    int y = frame.top;
    int w = frame.getWidth();
    int h = frame.getHeight();
    // ...... 判错设置代码,省略
    if (mCurrentState.active.transform.tx() == x && mCurrentState.active.transform.ty() == y &&
        mCurrentState.active.w == w && mCurrentState.active.h == h) {
        return false;
    }
    //...... 判错设置代码,省略
    mCurrentState.active.transform.set(x, y);
    mCurrentState.active.w = w;
    mCurrentState.active.h = h;
    mCurrentState.sequence++;
    mCurrentState.modified = true;
    setTransactionFlags(eTransactionNeeded);
    return true;
}

这边主要是更新mCurrentState的状态和有效区域等,不做具体讨论

调用change显示刷新率函数

在上述代码段中,最后一步,通过RefreshRateOverlay的changeRefreshRate函数来达到更新Layer的刷新率

// 从RefreshRateConfigs配置中获取到当前的刷新率
mRefreshRateOverlay->changeRefreshRate(mRefreshRateConfigs->getCurrentRefreshRate());

void RefreshRateOverlay::changeRefreshRate(const RefreshRate& refreshRate) {
    // 获取对应fps对应的GraphicBuffer指针对象
    auto buffer = mBufferCache[refreshRate.getFps()];
    // 将上述获取到的GraphicBuffer指针对象设置给创建的图层BufferStateLayer
    mLayer->setBuffer(buffer, Fence::NO_FENCE, 0, 0, {});
    mFlinger.mTransactionFlags.fetch_or(eTransactionMask);
}

bool BufferStateLayer::setBuffer(const sp<GraphicBuffer>& buffer, const sp<Fence>& acquireFence,
                                 nsecs_t postTime, nsecs_t desiredPresentTime,
                                 const client_cache_t& clientCacheId) {
    // ...... 设置mCurrentState的参数,此处省略
    // 声明当前显示的图层新增加一个(显示历史中)
    mFlinger->mScheduler->recordLayerHistory(this, desiredPresentTime,
                                             LayerHistory::LayerUpdateType::Buffer);
    addFrameEvent(acquireFence, postTime, desiredPresentTime);
    return true;
}

如上代码,当系统显示设备刷新的时候,我们创建的BufferStateLayer图层就被加入到显示图层中,并在显示设备中显现出来

更新上层的开发者模式中的显示刷新率菜单的开关

当第一步中的SurfaceFlinger创建完图层后,在开发者模式中需要将显示刷新率开关菜单更新一下,会调用updateShowRefreshRateSetting函数

@VisibleForTesting
void updateShowRefreshRateSetting() {
    // magic communication with surface flinger.
    try {
        if (mSurfaceFlinger != null) {
            final Parcel data = Parcel.obtain();
            // 需要注意,此处不为NULL,也就是说这边需要返回值
            final Parcel reply = Parcel.obtain();
            // 同上面一样,此处为”android.os.ISurfaceComposer”
            data.writeInterfaceToken(SURFACE_COMPOSER_INTERFACE_KEY);
            // 这个值为2
            data.writeInt(SETTING_VALUE_QUERY);
            // Code和上面更新的code一致均为1034
            mSurfaceFlinger.transact(SURFACE_FLINGER_CODE, data, reply, 0 /* flags */);
            // 等到上述Binder通信完成,此处reply也就有值了,因此获取该值,并设置菜单的开关
            final boolean enabled = reply.readBoolean();
            ((SwitchPreference) mPreference).setChecked(enabled);
            reply.recycle();
            data.recycle();
        }
    } catch (RemoteException ex) {
        // intentional no-op
    }
}

刚刚data中带的值是0或者1,此处设置为2,就导致调用函数不一致

case 1034: {
    // 获取此前设定的数据信息,打开 or 关闭
    switch (n = data.readInt32()) {
        // ...... 0和1不会走到,因此此处省略
        default: {
            Mutex::Autolock lock(mStateLock);
            // 哦哦哦,原来此处是直接设置RefreshRateOverlay指针对象是否创建成功
            // 成功即表明传入的参数为1,而且创建了一个图层
            // 为nullptr的时候表明,传入参数为0,或者流程出现问题,未能成功创建指针,因此返回失败
            reply->writeBool(mRefreshRateOverlay != nullptr);
        }
    }
    return NO_ERROR;
}

如上段代码及解析,此处直接更新了开发者模式中的显示刷新率菜单开关

总结

在打开或者关闭开发者模式中的显示刷新率菜单开关的时候,

首先,打开开关时会创建一个BufferStateLayer图层以及为图层添加对应的GraphicBuffer,同时将该图层加入到SurfaceFlinger需要显示的所有图层中,并且刷新显示设备

其次,通过和SurfaceFlinger之间的通信,保证确认SurfaceFlinger端创建和显示图层正常后,更新开发者模式中的显示刷新率菜单开关