};
查找android_view_ThreadedRenderer_setForceDark()方法
frameworks/base/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
static void android_view_ThreadedRenderer_setForceDark(JNIEnv* env, jobject clazz,
jlong proxyPtr, jboolean enable) {
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
// 调用RenderProxy的setForceDark方法
proxy->setForceDark(enable);
}
frameworks/base/libs/hwui/renderthread/RenderProxy.cpp
void RenderProxy::setForceDark(bool enable) {
// 调用CanvasContext的setForceDark方法
mRenderThread.queue().post(this, enable { mContext->setForceDark(enable); });
}
frameworks/base/libs/hwui/renderthread/CanvasContext.h
// Force Dark的默认值是false
bool mUseForceDark = false;
// 设置mUseForceDark标志
void setForceDark(bool enable) { mUseForceDark = enable; }
bool useForceDark() {
return mUseForceDark;
}
接着查找调用userForceDark()方法的地方
frameworks/base/libs/hwui/TreeInfo.cpp
-
TreeInfo::TreeInfo(TraversalMode mode, renderthread::CanvasContext& canvasContext)
- mode(mode)
, prepareTextures(mode == MODE_FULL)
, canvasContext(canvasContext)
// 设置disableForceDark变量
, disableForceDark(canvasContext.useForceDark() ? 0 : 1)
, screenSize(canvasContext.getNextFrameSize()) {}
} // namespace android::uirenderer
frameworks/base/libs/hwui/TreeInfo.h
class TreeInfo {
public:
// …
int disableForceDark;
// …
};
到了这里,可以看出,当设置了Force Dark之后,最终会设置到TreeInfo类中的disableForceDark变量,如果没有设置主题的Force Dark,那么根据false的默认值,disableForceDark变量会别设置成1,如果设置了使用强制深色模式,那么disableForceDark会变成0。
这个变量最终会用在RenderNode的RenderNode.handleForceDark()过程中,到达的流程如下图:
frameworks/base/libs/hwui/RenderNode.cpp
void RenderNode::prepareTreeImpl(TreeObserver& observer, TreeInfo& info, bool functorsNeedLayer) {
// …
// 同步正在处理的RenderNode Property变化
if (info.mode == TreeInfo::MODE_FULL) {
pushStagingPropertiesChanges(info);
}
// 如果当前View不允许被ForceDark,那么info.disableForceDark值+1
if (!mProperties.getAllowForceDark()) {
info.disableForceDark++;
}
// …
// 同步正在处理的Render Node的Display List,实现具体深色的逻辑
if (info.mode == TreeInfo::MODE_FULL) {
pushStagingDisplayListChanges(observer, info);
}
if (mDisplayList) {
info.out.hasFunctors |= mDisplayList->hasFunctor();
bool isDirty = mDisplayList->prepareListAndChildren(
observer, info, childFunctorsNeedLayer,
[](RenderNode* child, TreeObserver& observer, TreeInfo& info,
bool functorsNeedLayer) {
// 递归调用子节点的prepareTreeImpl。
// 递归调用之前,若父节点不允许强制深色模式,disableForceDark已经不为0,
// 子节点再设置允许强制深色模式不会使得disableForceDark的值减少,
// 因此有第三个规则:父节点设置了不允许深色模式,子节点再设置允许深色模式无效。
// 同样的,递归调用之前,若父节点允许深色模式,disableForceDark为0,
// 子节点再设置不允许强制深色模式,则disableForceDark值还是会++,不为0
// 因此有第四个规则:子节点设置不允许强制深色模式不受父节点设置允许强制深色模式影响。
child->prepareTreeImpl(observer, info, functorsNeedLayer);
});
if (isDirty) {
damageSelf(info);
}
}
pushLayerUpdate(info);
// 递归结束后将之前设置过+1的值做回退-1恢复操作,避免影响其他兄弟结点的深色模式值判断
if (!mProperties.getAllowForceDark()) {
info.disableForceDark–;
}
info.damageAccumulator->popTransform();
}
void RenderNode::pushStagingDisplayListChanges(TreeObserver& observer, TreeInfo& info) {
// …
// 同步DisplayList
syncDisplayList(observer, &info);
// …
}
void RenderNode::syncDisplayList(TreeObserver& observer, TreeInfo* info) {
// …
if (mDisplayList) {
WebViewSyncData syncData {
// 设置WebViewSyncData的applyForceDark
.applyForceDark = info && !info->disableForceDark
};
mDisplayList->syncContents(syncData);
// 强制执行深色模式执行
handleForceDark(info);
}
}
void RenderNode::handleForceDark(android::uirenderer::TreeInfo *info) {
if (CC_LIKELY(!info || info->disableForceDark)) {
// 如果disableForceDark不为0,关闭强制深色模式,则直接返回
return;
}
auto usage = usageHint();
const auto& children = mDisplayList->mChildNodes;
// 如果有文字表示是前景策略
if (mDisplayList->hasText()) {
usage =