libchecker-chart-rules

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Chart rule contribution guide

LibChecker图表规则贡献指南

This directory contains the declarative statistics shown on LibChecker's chart page. A rule describes the data that LibChecker should inspect, the condition that produces a match, and the labels and icon shown to the user.
Rules cannot execute scripts or arbitrary code. LibChecker owns all APK, DEX, manifest, and native-file traversal. A rule can only use evidence and operators that the installed app already implements.
本目录包含LibChecker图表页面展示的声明式统计规则。一条规则定义了LibChecker需要检查的数据、匹配条件,以及展示给用户的标签和图标。
规则无法执行脚本或任意代码。LibChecker全权负责APK、DEX、清单文件和原生文件的遍历。规则只能使用已安装应用已实现的证据和运算符。

Before you start

开始之前

Answer these questions before writing JSON:
  1. What does the chart measure, and why is it useful to LibChecker users?
  2. Which installed-app evidence proves a match?
  3. Can an app produce one yes/no result, or can it match several capabilities?
  4. Is there a primary HTTPS source that explains the technology or capability?
  5. Can you test the rule against both matching and non-matching APKs?
Schema v1 supports only the evidence listed in Evidence reference. If your rule needs another source, such as a DEX field, resource-table entry, native symbol, certificate property, or arbitrary file content, propose a generic evidence provider in the LibChecker app first. Do not encode a workaround in the rule.
New rules should normally start with
"releaseChannel": "preview-only"
. Move them to
stable
only after the preview bundle has been tested with a compatible LibChecker build.
编写JSON前,请先回答以下问题:
  1. 该图表衡量什么?对LibChecker用户有何用处?
  2. 哪些已安装应用的证据可以证明匹配?
  3. 应用只能产生是/否结果,还是可以匹配多种能力?
  4. 是否有权威HTTPS来源解释该技术或能力?
  5. 能否针对匹配和不匹配的APK测试该规则?
Schema v1仅支持证据参考中列出的证据。如果你的规则需要其他来源,比如DEX字段、资源表条目、原生符号、证书属性或任意文件内容,请先在LibChecker应用中提出通用证据提供者的需求,不要在规则中编写变通方案。
新规则通常应从
"releaseChannel": "preview-only"
开始。只有在预览bundle通过兼容的LibChecker版本测试后,才能将其移至
stable
通道。

Contribution workflow

贡献工作流

  1. Fork the repository and create a topic branch.
  2. Choose the closest example in
    rules/
    :
    • flutter.json
      for exact native-library detection.
    • reactivex.json
      for exact APK entries with a DEX fallback.
    • itgsa.json
      for facets, recursive conditions, DEX queries, and manifest receiver actions.
    • The predicate example below for a numeric comparison.
  3. Add one UTF-8 JSON file under
    rules/
    . Use four-space indentation and name the file after the final segment of the rule ID.
  4. Add the referenced SVG under
    icons/
    .
  5. Update the tests that enumerate rule IDs, icons, catalog size, and stable channel contents. Add focused assertions for the new detection data.
  6. Run the unit tests and build a preview bundle in a temporary directory.
  7. Test the preview rule with known matching and non-matching apps.
  8. Regenerate
    cloud/v1/chart.bundle
    and
    cloud/v1/manifest.json
    with the bundle version and minimum app version agreed for the target branch.
  9. Submit the source rule, icon, tests, generated bundle, and manifest in one pull request. Include your evidence source and manual test results in the PR description.
Run commands from the repository root:
shell
python3 -m unittest chart.tools.test_build_bundle
python3 chart/tools/build_bundle.py \
  --bundle-version 12 \
  --channel preview \
  --minimum-app-version-code 2731 \
  --output-dir /tmp/libchecker-chart-preview
The numbers above are examples. Read
chart/cloud/v1/manifest.json
and the target branch before choosing a bundle version or minimum app version.
  1. Fork仓库并创建主题分支。
  2. rules/
    中选择最接近的示例:
    • flutter.json
      :用于精确检测原生库。
    • reactivex.json
      :用于精确检测APK条目,同时支持DEX fallback。
    • itgsa.json
      :用于多维度规则、递归条件、DEX查询以及清单接收器动作。
    • 下方的谓词示例:用于数值比较。
  3. rules/
    下添加一个UTF-8编码的JSON文件。使用4空格缩进,文件名与规则ID的最后一段一致。
  4. icons/
    下添加引用的SVG图标。
  5. 更新枚举规则ID、图标、目录大小和稳定通道内容的测试,为新的检测数据添加针对性断言。
  6. 运行单元测试,并在临时目录中构建预览bundle。
  7. 使用已知匹配和不匹配的应用测试预览规则。
  8. 针对目标分支,使用约定的bundle版本和最低应用版本重新生成
    cloud/v1/chart.bundle
    cloud/v1/manifest.json
  9. 在一个Pull Request中提交源规则、图标、测试、生成的bundle和清单文件。在PR描述中包含你的证据来源和手动测试结果。
从仓库根目录运行以下命令:
shell
python3 -m unittest chart.tools.test_build_bundle
python3 chart/tools/build_bundle.py \
  --bundle-version 12 \
  --channel preview \
  --minimum-app-version-code 2731 \
  --output-dir /tmp/libchecker-chart-preview
以上数字仅为示例。在选择bundle版本或最低应用版本前,请先查看
chart/cloud/v1/manifest.json
和目标分支。

Repository layout

仓库结构

PathPurpose
rules/
Reviewed source definitions, one JSON file per statistic.
icons/
SVG assets referenced by source rules.
schema/v1/chart-rule.schema.json
Machine-readable schema for source rules.
schema/v1/manifest.schema.json
Machine-readable schema for the generated manifest.
tools/build_bundle.py
Validator and deterministic bundle generator.
tools/test_build_bundle.py
Source validation and bundle regression tests.
cloud/v1/chart.bundle
Generated catalog and icons consumed by LibChecker.
cloud/v1/manifest.json
Generated version, compatibility, size, and checksum metadata.
路径用途
rules/
已审核的源规则定义,每个统计对应一个JSON文件。
icons/
源规则引用的SVG资源。
schema/v1/chart-rule.schema.json
源规则的机器可读schema。
schema/v1/manifest.schema.json
生成的清单文件的机器可读schema。
tools/build_bundle.py
验证器和确定性bundle生成工具。
tools/test_build_bundle.py
源规则验证和bundle回归测试。
cloud/v1/chart.bundle
LibChecker使用的生成目录和图标。
cloud/v1/manifest.json
生成的版本、兼容性、大小和校验和元数据。

Minimal rule

最简规则示例

This is a complete single-predicate rule:
json
{
    "id": "official.example-sdk",
    "revision": 1,
    "source": "official",
    "releaseChannel": "preview-only",
    "title": {
        "translations": {
            "en": "Example SDK",
            "zh-Hans": "示例 SDK"
        }
    },
    "details": {
        "description": {
            "translations": {
                "en": "Example SDK provides a documented capability for Android apps.",
                "zh-Hans": "示例 SDK 为 Android 应用提供一项有公开文档的能力。"
            }
        },
        "referenceUrl": "https://example.com/android-sdk"
    },
    "icon": {
        "asset": "icons/example-sdk.svg",
        "renderMode": "monochrome",
        "tintRole": "on_surface"
    },
    "calculation": {
        "kind": "predicate",
        "predicate": {
            "evidence": "native_library",
            "operator": "contains",
            "value": {
                "string": "libexample.so"
            },
            "matchedTitle": {
                "translations": {
                    "en": "Example SDK apps",
                    "zh-Hans": "示例 SDK 应用"
                }
            },
            "unmatchedTitle": {
                "translations": {
                    "en": "Other apps",
                    "zh-Hans": "其他应用"
                }
            }
        }
    },
    "fingerprint": "artifact"
}
以下是一个完整的单谓词规则:
json
{
    "id": "official.example-sdk",
    "revision": 1,
    "source": "official",
    "releaseChannel": "preview-only",
    "title": {
        "translations": {
            "en": "Example SDK",
            "zh-Hans": "示例 SDK"
        }
    },
    "details": {
        "description": {
            "translations": {
                "en": "Example SDK provides a documented capability for Android apps.",
                "zh-Hans": "示例 SDK 为 Android 应用提供一项有公开文档的能力。"
            }
        },
        "referenceUrl": "https://example.com/android-sdk"
    },
    "icon": {
        "asset": "icons/example-sdk.svg",
        "renderMode": "monochrome",
        "tintRole": "on_surface"
    },
    "calculation": {
        "kind": "predicate",
        "predicate": {
            "evidence": "native_library",
            "operator": "contains",
            "value": {
                "string": "libexample.so"
            },
            "matchedTitle": {
                "translations": {
                    "en": "Example SDK apps",
                    "zh-Hans": "示例 SDK 应用"
                }
            },
            "unmatchedTitle": {
                "translations": {
                    "en": "Other apps",
                    "zh-Hans": "其他应用"
                }
            }
        }
    },
    "fingerprint": "artifact"
}

Top-level fields

顶层字段

The source schema does not allow unknown fields. The following fields are available to official online rules.
FieldRequiredType or allowed valuesMeaning
id
YesString matching
official.<name>
Permanent identity of the statistic.
revision
YesInteger, minimum
1
Version of this rule definition.
source
Yes
official
Online rules in this repository are official rules.
title
YesTranslated textChart title shown by LibChecker.
details
YesObjectIn-app description and primary reference URL.
icon
YesObjectBundled SVG and its rendering behavior.
calculation
Yes
predicate
or
facets
How apps are classified.
releaseChannel
No
stable
or
preview-only
Controls which generated bundle includes the rule. Defaults to
stable
.
availability
No
always
Availability gate. Schema v1 online rules only support
always
.
requiresFeatureInitialization
NoBooleanHides the chart until feature initialization finishes. Defaults to
false
.
controls
NoEmpty array onlyOnline controls are not supported in schema v1.
dashboard
No
none
Online dashboard integrations are not supported in schema v1.
fingerprint
No
standard
,
features
, or
artifact
Selects the app-data fingerprint used to invalidate cached chart results.
JSON Schema
default
values document client defaults. The bundle builder does not insert missing optional fields into the generated catalog.
源schema不允许未知字段。以下字段适用于官方在线规则。
字段是否必填类型或允许值含义
id
匹配
official.<name>
的字符串
统计规则的永久标识。
revision
整数,最小值为
1
该规则定义的版本。
source
official
本仓库中的在线规则均为官方规则。
title
多语言文本LibChecker展示的图表标题。
details
对象应用内描述和主参考URL。
icon
对象打包的SVG及其渲染行为。
calculation
predicate
facets
应用分类方式。
releaseChannel
stable
preview-only
控制该规则包含在哪个生成的bundle中,默认值为
stable
availability
always
可用性限制。Schema v1在线规则仅支持
always
requiresFeatureInitialization
布尔值控制图表是否在功能初始化完成后显示,默认值为
false
controls
仅允许空数组Schema v1不支持在线控件。
dashboard
none
Schema v1不支持在线仪表盘集成。
fingerprint
standard
features
artifact
选择用于使缓存图表结果失效的应用数据指纹类型。
JSON Schema的
default
值记录了客户端默认值。bundle构建器不会将缺失的可选字段插入到生成的目录中。

id

id

The ID must match:
text
^official\.[a-z0-9]+(?:[.-][a-z0-9]+)*$
Examples:
  • Valid:
    official.flutter
    ,
    official.android-api-level
    ,
    official.vendor.capability
    .
  • Invalid:
    flutter
    ,
    official.Flutter
    ,
    official_target_sdk
    .
Use a specific, technology-neutral ID. Once a rule has been published, never reuse its ID for a different statistic. The source filename should match the last ID segment, such as
official.flutter
in
flutter.json
.
ID必须匹配以下格式:
text
^official\.[a-z0-9]+(?:[.-][a-z0-9]+)*$
示例:
  • 有效:
    official.flutter
    official.android-api-level
    official.vendor.capability
  • 无效:
    flutter
    official.Flutter
    official_target_sdk
使用具体、技术中立的ID。规则发布后,请勿将其ID重新用于其他统计规则。源文件名应与ID的最后一段一致,例如
official.flutter
对应
flutter.json

revision

revision

Start a new rule at revision
1
. Increase the revision whenever a published rule changes its matching logic, titles, description, icon, calculation type, or other presentation metadata. A change to repository documentation alone does not require a rule revision.
The revision belongs to one rule. It is independent of the generated bundle's
bundleVersion
.
新规则从版本
1
开始。每当已发布的规则更改匹配逻辑、标题、描述、图标、计算类型或其他展示元数据时,需递增版本号。仅修改仓库文档不需要更新规则版本。
版本号属于单个规则,与生成bundle的
bundleVersion
独立。

source

source

Every rule submitted to this repository must use:
json
"source": "official"
The builder rejects other values.
提交到本仓库的所有规则必须使用:
json
"source": "official"
构建器会拒绝其他值。

Translated text

多语言文本

title
,
details.description
, predicate group titles, and facet titles use the same wrapper. Optional facet short titles use it as well:
json
{
    "translations": {
        "en": "English text",
        "zh-Hans": "简体中文文本"
    }
}
title
details.description
、谓词组标题和维度标题使用相同的包装格式。可选的维度短标题也使用该格式:
json
{
    "translations": {
        "en": "English text",
        "zh-Hans": "简体中文文本"
    }
}

Translated-text parameters

多语言文本参数

ParameterTypeRequiredAllowed values and limitsMeaning
translations
ObjectYes2 to 16 locale entries; must include
en
and
zh-Hans
Maps locale tags to the text shown by LibChecker.
translations.<locale>
StringYes for each declared localeNon-empty; 80 characters for chart and group titles, 40 for facet titles and short titles, 1,500 for descriptionsLocalized value for one BCP 47-style locale tag.
Locale keyAllowedMeaning
en
RequiredEnglish text and runtime fallback.
zh-Hans
RequiredSimplified Chinese text.
zh
,
zh-CN
RejectedThese tags are intentionally not accepted; use
zh-Hans
.
Other schema-compatible tagsOptionalAdditional translations, for example
pt-BR
or
es-419
, up to 16 locales total.
Rules for translations:
  • en
    and
    zh-Hans
    are required. English is the runtime fallback.
  • Use
    zh-Hans
    for Simplified Chinese.
    zh
    and
    zh-CN
    are rejected.
  • A translated object must contain 2 to 16 locales.
  • Locale keys use BCP 47-style tags accepted by the schema, such as
    en
    ,
    zh-Hans
    ,
    pt-BR
    , or
    es-419
    .
  • Each translation must be a non-empty string.
  • title
    ,
    matchedTitle
    , and
    unmatchedTitle
    allow up to 80 characters.
  • A facet
    title
    and
    shortTitle
    allow up to 40 characters.
  • details.description
    allows up to 1,500 characters.
  • Keep equivalent meaning across locales. Do not add claims to one language that are absent from another.
Use short labels for chart and group titles. The matched and unmatched titles name the two result groups, for example
Flutter apps
and
Other apps
.
参数类型是否必填允许值和限制含义
translations
对象2到16个区域条目;必须包含
en
zh-Hans
映射区域标签到LibChecker展示的文本。
translations.<locale>
字符串是(每个声明的区域)非空;图表和组标题最多80字符,维度标题和短标题最多40字符,描述最多1500字符单个BCP 47格式区域标签的本地化值。
区域键是否允许含义
en
必填英文文本,作为运行时 fallback。
zh-Hans
必填简体中文文本。
zh
zh-CN
拒绝这些标签不被接受,请使用
zh-Hans
其他兼容schema的标签可选额外的翻译,例如
pt-BR
es-419
,最多支持16个区域。
翻译规则:
  • 必须包含
    en
    zh-Hans
    ,英文作为运行时 fallback。
  • 使用
    zh-Hans
    表示简体中文,拒绝
    zh
    zh-CN
  • 多语言对象必须包含2到16个区域。
  • 区域键使用schema接受的BCP 47格式标签,例如
    en
    zh-Hans
    pt-BR
    es-419
  • 每个翻译必须是非空字符串。
  • title
    matchedTitle
    unmatchedTitle
    最多允许80字符。
  • 维度
    title
    shortTitle
    最多允许40字符。
  • details.description
    最多允许1500字符。
  • 保持不同语言的含义一致,不要在一种语言中添加另一种语言没有的声明。
图表和组标题使用简短标签。匹配和不匹配标题用于命名两个结果组,例如
Flutter apps
Other apps

Details and reference URL

详情和参考URL

details
is required:
json
"details": {
    "description": {
        "translations": {
            "en": "A neutral introduction to the technology.",
            "zh-Hans": "对该技术的中性介绍。"
        }
    },
    "referenceUrl": "https://project.example/documentation"
}
details
为必填项:
json
"details": {
    "description": {
        "translations": {
            "en": "A neutral introduction to the technology.",
            "zh-Hans": "对该技术的中性介绍。"
        }
    },
    "referenceUrl": "https://project.example/documentation"
}

Details parameters

详情参数

ParameterTypeRequiredAllowed values and limitsMeaning
details.description
Translated textYes
en
and
zh-Hans
; 1 to 1,500 characters per locale
Neutral in-app introduction to the technology or capability.
details.referenceUrl
StringYesHTTPS URL, valid host, no credentials or whitespace, maximum 512 charactersPrimary source opened from the introduction dialog.
Write a short, neutral description of the technology or capability. Do not say that the currently selected app matches the rule. LibChecker appends the actual analysis result at runtime. Faceted rules also list the matched facet titles.
referenceUrl
must:
  • use HTTPS;
  • contain a valid host;
  • contain no username, password, or whitespace;
  • be no longer than 512 characters;
  • point to a primary project, standards body, vendor, or platform document.
Do not use tracking links, URL shorteners, affiliate links, search results, or an unreviewed third-party summary.
参数类型是否必填允许值和限制含义
details.description
多语言文本包含
en
zh-Hans
;每个区域1到1500字符
对技术或能力的中性应用内介绍。
details.referenceUrl
字符串HTTPS URL,包含有效主机,无凭据或空白字符,最多512字符从介绍对话框打开的主来源。
编写简短、中性的技术或能力描述。不要说明当前选中的应用是否匹配规则,LibChecker会在运行时追加实际分析结果。多维度规则还会列出匹配的维度标题。
referenceUrl
必须满足:
  • 使用HTTPS;
  • 包含有效主机;
  • 不包含用户名、密码或空白字符;
  • 长度不超过512字符;
  • 指向项目、标准机构、厂商或平台的官方文档。
请勿使用跟踪链接、短链接、联盟链接、搜索结果或未审核的第三方摘要。

Icons

图标

Every online rule references one repository asset:
json
"icon": {
    "asset": "icons/example-sdk.svg",
    "renderMode": "monochrome",
    "tintRole": "on_surface"
}
每个在线规则引用一个仓库资源:
json
"icon": {
    "asset": "icons/example-sdk.svg",
    "renderMode": "monochrome",
    "tintRole": "on_surface"
}

Icon fields

图标字段

FieldRequiredAllowed valuesMeaning
asset
Yes
icons/<safe-name>.svg
Repository-relative path included in the bundle.
renderMode
No
monochrome
,
original
Whether LibChecker applies a theme tint. Defaults to
monochrome
.
tintRole
No
on_surface
,
on_surface_variant
,
primary
,
secondary
,
tertiary
Theme color used for a monochrome icon. Defaults to
on_surface
.
Use
original
only when the original brand colors carry meaning. LibChecker does not apply
tintRole
to an
original
icon. Use
monochrome
for a shape that should adapt to the active theme.
字段是否必填允许值含义
asset
icons/<safe-name>.svg
仓库相对路径,会被包含在bundle中。
renderMode
monochrome
original
LibChecker是否应用主题色调,默认值为
monochrome
tintRole
on_surface
on_surface_variant
primary
secondary
tertiary
单色图标的主题颜色,默认值为
on_surface
仅当原始品牌颜色具有特殊含义时使用
original
。LibChecker不会对
original
图标应用
tintRole
。对于需要适配当前主题的形状,使用
monochrome

SVG requirements

SVG要求

An SVG must:
  • use a
    0 0 1024 1024
    viewBox;
  • keep the artwork approximately within a centered
    800 x 800
    area so that icons have consistent optical size;
  • remain below 64 KiB;
  • be valid UTF-8;
  • contain no scripts, styles, text nodes, linked images, entities, external references, or
    url(...)
    content.
The validator rejects
<!doctype
,
<!entity
,
<?xml-stylesheet
,
<script
,
<foreignObject
,
<image
,
<style
,
<text
,
href=
,
xlink:
, and
url(
. Convert text to paths and inline any required fill colors.
SVG必须满足:
  • 使用
    0 0 1024 1024
    的viewBox;
  • 图形大致位于居中的
    800 x 800
    区域内,确保图标视觉大小一致;
  • 大小不超过64 KiB;
  • 为有效的UTF-8编码;
  • 不包含脚本、样式、文本节点、链接图片、实体、外部引用或
    url(...)
    内容。
验证器会拒绝
<!doctype
<!entity
<?xml-stylesheet
<script
<foreignObject
<image
<style
<text
href=
xlink:
url(
。将文本转换为路径,并内联所有必要的填充颜色。

Choosing a calculation type

选择计算类型

Use
predicate
when every app belongs to one of two groups. Use
facets
when one app can match several named capabilities and the UI should show each match as a chip.
QuestionUse
Does the app target SDK 35 or newer?
predicate
Does the app contain
libflutter.so
?
predicate
Which ITGSA capabilities does the app implement?
facets
当每个应用只能属于两个组之一时,使用
predicate
。当一个应用可以匹配多个命名能力,且UI需要将每个匹配显示为标签时,使用
facets
问题使用类型
应用的目标SDK是否为35或更高?
predicate
应用是否包含
libflutter.so
predicate
应用实现了哪些ITGSA能力?
facets

Calculation parameters

计算参数

ParameterTypeRequiredPossible valuesMeaning
calculation.kind
StringYes
predicate
,
facets
Selects the calculation object that must accompany it.
calculation.predicate
ObjectRequired when
kind
is
predicate
See Predicate calculationsProduces matched and unmatched groups from one condition.
calculation.facets
ObjectRequired when
kind
is
facets
See Facet calculationsProduces matched and unmatched groups plus per-app capability chips.
Only the object selected by
kind
is allowed. Online rules cannot use the client's built-in
native
calculation type.
Facets are for overlapping capabilities. Do not use them for mutually exclusive buckets or numeric distributions. Schema v1 has no online calculation type for those cases.
参数类型是否必填可能值含义
calculation.kind
字符串
predicate
facets
选择对应的计算对象。
calculation.predicate
对象
kind
predicate
时必填
查看谓词计算通过一个条件生成匹配和不匹配组。
calculation.facets
对象
kind
facets
时必填
查看维度计算生成匹配和不匹配组,以及每个应用的能力标签。
仅允许
kind
选择的对象。在线规则不能使用客户端内置的
native
计算类型。
维度适用于重叠的能力。请勿将其用于互斥的分类或数值分布。Schema v1没有针对这些场景的在线计算类型。

Predicate calculations

谓词计算

A predicate requires
matchedTitle
,
unmatchedTitle
, and exactly one complete condition. For a single evidence leaf, put
evidence
,
operator
, and
value
directly in
predicate
:
ParameterTypeRequiredPossible values and limitsMeaning
predicate.matchedTitle
Translated textYes1 to 80 characters per localeLabel for apps whose condition evaluates to true.
predicate.unmatchedTitle
Translated textYes1 to 80 characters per localeLabel for apps whose condition evaluates to false.
predicate.evidence
StringRequired for direct-leaf form
target_sdk
,
native_library
,
archive_entry
,
dex_class
,
manifest_receiver_action
,
manifest_attribute
Evidence provider used by the leaf.
predicate.operator
StringRequired for direct-leaf formDepends on
evidence
Comparison applied to the evidence.
predicate.value
ObjectRequired for direct-leaf formExactly one value variant compatible with
evidence
Expected value for the comparison.
predicate.condition
ConditionRequired for recursive formOne leaf,
all
,
any
, or
not
Recursive condition used instead of the three direct-leaf fields.
json
"calculation": {
    "kind": "predicate",
    "predicate": {
        "evidence": "target_sdk",
        "operator": "greater_than_or_equal",
        "value": {
            "integer": 35
        },
        "matchedTitle": {
            "translations": {
                "en": "Target SDK 35 or newer",
                "zh-Hans": "Target SDK 35 及以上"
            }
        },
        "unmatchedTitle": {
            "translations": {
                "en": "Target SDK 34 or older",
                "zh-Hans": "Target SDK 34 及以下"
            }
        }
    }
}
For logical composition, replace the direct leaf fields with one
condition
:
json
"predicate": {
    "condition": {
        "any": [
            {
                "evidence": "native_library",
                "operator": "contains",
                "value": {
                    "string": "libexample.so"
                }
            },
            {
                "evidence": "manifest_receiver_action",
                "operator": "contains_any",
                "value": {
                    "strings": [
                        "com.example.ACTION_READY"
                    ]
                }
            }
        ]
    },
    "matchedTitle": {
        "translations": {
            "en": "Example apps",
            "zh-Hans": "示例应用"
        }
    },
    "unmatchedTitle": {
        "translations": {
            "en": "Other apps",
            "zh-Hans": "其他应用"
        }
    }
}
Do not provide both the direct fields and
condition
. Partial direct tuples are also rejected.
谓词需要
matchedTitle
unmatchedTitle
和一个完整的条件。对于单个证据节点,直接在
predicate
中设置
evidence
operator
value
参数类型是否必填可能值和限制含义
predicate.matchedTitle
多语言文本每个区域1到80字符条件为真的应用标签。
predicate.unmatchedTitle
多语言文本每个区域1到80字符条件为假的应用标签。
predicate.evidence
字符串直接节点形式必填
target_sdk
native_library
archive_entry
dex_class
manifest_receiver_action
manifest_attribute
节点使用的证据提供者。
predicate.operator
字符串直接节点形式必填取决于
evidence
应用于证据的比较方式。
predicate.value
对象直接节点形式必填
evidence
兼容的单个值变体
比较的预期值。
predicate.condition
条件递归形式必填单个节点、
all
any
not
替代三个直接节点字段的递归条件。
json
"calculation": {
    "kind": "predicate",
    "predicate": {
        "evidence": "target_sdk",
        "operator": "greater_than_or_equal",
        "value": {
            "integer": 35
        },
        "matchedTitle": {
            "translations": {
                "en": "Target SDK 35 or newer",
                "zh-Hans": "Target SDK 35 及以上"
            }
        },
        "unmatchedTitle": {
            "translations": {
                "en": "Target SDK 34 or older",
                "zh-Hans": "Target SDK 34 及以下"
            }
        }
    }
}
对于逻辑组合,将直接节点字段替换为一个
condition
json
"predicate": {
    "condition": {
        "any": [
            {
                "evidence": "native_library",
                "operator": "contains",
                "value": {
                    "string": "libexample.so"
                }
            },
            {
                "evidence": "manifest_receiver_action",
                "operator": "contains_any",
                "value": {
                    "strings": [
                        "com.example.ACTION_READY"
                    ]
                }
            }
        ]
    },
    "matchedTitle": {
        "translations": {
            "en": "Example apps",
            "zh-Hans": "示例应用"
        }
    },
    "unmatchedTitle": {
        "translations": {
            "en": "Other apps",
            "zh-Hans": "其他应用"
        }
    }
}
请勿同时提供直接字段和
condition
,部分直接元组也会被拒绝。

Facet calculations

维度计算

A facet calculation contains 1 to 8 ordered items:
ParameterTypeRequiredPossible values and limitsMeaning
facets.matchedTitle
Translated textYes1 to 80 characters per localeChart label for apps matching at least one facet.
facets.unmatchedTitle
Translated textYes1 to 80 characters per localeChart label for apps matching no facets.
facets.items
ArrayYes1 to 8 facet objectsOrdered capability definitions.
items[].id
StringYesLowercase rule-local ID matching the documented pattern; unique within the ruleStable internal identity of a facet.
items[].title
Translated textYes1 to 40 characters per localeFull facet label used in detailed result surfaces and chart chips.
items[].shortTitle
Translated textNo1 to 40 characters per localeCompact label used in matched-facet summaries; falls back to
title
when omitted.
items[].condition
ConditionYesOne leaf,
all
,
any
, or
not
Determines whether this facet matches an app.
json
"calculation": {
    "kind": "facets",
    "facets": {
        "matchedTitle": {
            "translations": {
                "en": "Example capability apps",
                "zh-Hans": "示例能力应用"
            }
        },
        "unmatchedTitle": {
            "translations": {
                "en": "Other apps",
                "zh-Hans": "其他应用"
            }
        },
        "items": [
            {
                "id": "service-kit",
                "title": {
                    "translations": {
                        "en": "Service Kit",
                        "zh-Hans": "服务套件"
                    }
                },
                "shortTitle": {
                    "translations": {
                        "en": "Kit",
                        "zh-Hans": "套件"
                    }
                },
                "condition": {
                    "evidence": "native_library",
                    "operator": "contains",
                    "value": {
                        "string": "libexample_service.so"
                    }
                }
            }
        ]
    }
}
Each item requires:
  • a rule-local
    id
    matching
    ^[a-z][a-z0-9]*(?:[.-][a-z0-9]+)*$
    ;
  • a unique, stable ID within the rule;
  • a translated
    title
    of at most 40 characters per locale;
  • an optional translated
    shortTitle
    of at most 40 characters per locale;
  • exactly one
    condition
    .
An app enters the matched chart group when at least one facet matches. All matching facet titles are shown as chips in the order declared by
items
. Compact matched-facet summaries use
shortTitle
when present and otherwise fall back to
title
. Do not duplicate facet conditions in a separate root
any
expression.
维度计算包含1到8个有序条目:
参数类型是否必填可能值和限制含义
facets.matchedTitle
多语言文本每个区域1到80字符至少匹配一个维度的应用的图表标签。
facets.unmatchedTitle
多语言文本每个区域1到80字符不匹配任何维度的应用的图表标签。
facets.items
数组1到8个维度对象有序的能力定义。
items[].id
字符串符合文档格式的小写规则本地ID;在规则内唯一维度的稳定内部标识。
items[].title
多语言文本每个区域1到40字符详细结果界面和图表标签中使用的完整维度标签。
items[].shortTitle
多语言文本每个区域1到40字符匹配维度摘要中使用的紧凑标签;省略时回退到
title
items[].condition
条件单个节点、
all
any
not
确定该维度是否匹配应用。
json
"calculation": {
    "kind": "facets",
    "facets": {
        "matchedTitle": {
            "translations": {
                "en": "Example capability apps",
                "zh-Hans": "示例能力应用"
            }
        },
        "unmatchedTitle": {
            "translations": {
                "en": "Other apps",
                "zh-Hans": "其他应用"
            }
        },
        "items": [
            {
                "id": "service-kit",
                "title": {
                    "translations": {
                        "en": "Service Kit",
                        "zh-Hans": "服务套件"
                    }
                },
                "shortTitle": {
                    "translations": {
                        "en": "Kit",
                        "zh-Hans": "套件"
                    }
                },
                "condition": {
                    "evidence": "native_library",
                    "operator": "contains",
                    "value": {
                        "string": "libexample_service.so"
                    }
                }
            }
        ]
    }
}
每个条目需要:
  • 符合
    ^[a-z][a-z0-9]*(?:[.-][a-z0-9]+)*$
    的规则本地
    id
  • 规则内唯一的稳定ID;
  • 每个区域最多40字符的多语言
    title
  • 可选的每个区域最多40字符的多语言
    shortTitle
  • 一个
    condition
当应用至少匹配一个维度时,进入匹配图表组。所有匹配的维度标题会按照
items
声明的顺序显示为标签。紧凑的匹配维度摘要会使用
shortTitle
(如果存在),否则回退到
title
。请勿在单独的根
any
表达式中重复维度条件。

Conditions

条件

A condition is either one typed evidence leaf or one logical operator. Additional properties are rejected.
条件可以是一个类型化的证据节点,也可以是一个逻辑运算符。额外的属性会被拒绝。

Condition object parameters

条件对象参数

ParameterTypeRequiredPossible values and limitsMeaning
evidence
StringRequired for a leaf
target_sdk
,
native_library
,
archive_entry
,
dex_class
,
manifest_receiver_action
,
manifest_attribute
Selects the app data to inspect.
operator
StringRequired for a leaf
equal
,
greater_than_or_equal
,
less_than_or_equal
,
contains
,
contains_any
; compatibility depends on
evidence
Selects the comparison.
value
ObjectRequired for a leafExactly one of
integer
,
string
,
strings
,
dexClasses
,
manifestAttribute
Supplies the expected value.
all
Array of conditionsRequired for an
all
node
1 to 16 childrenTrue when every child is true.
any
Array of conditionsRequired for an
any
node
1 to 16 childrenTrue when at least one child is true.
not
ConditionRequired for a
not
node
One child objectInverts the child result.
Exactly one operation is allowed. A leaf must contain all of
evidence
,
operator
, and
value
; a logical node must contain only
all
,
any
, or
not
.
参数类型是否必填可能值和限制含义
evidence
字符串节点必填
target_sdk
native_library
archive_entry
dex_class
manifest_receiver_action
manifest_attribute
选择要检查的应用数据。
operator
字符串节点必填
equal
greater_than_or_equal
less_than_or_equal
contains
contains_any
;兼容性取决于
evidence
选择比较方式。
value
对象节点必填
integer
string
strings
dexClasses
manifestAttribute
中的一个
提供预期值。
all
条件数组
all
节点必填
1到16个子条件所有子条件为真时为真。
any
条件数组
any
节点必填
1到16个子条件至少一个子条件为真时为真。
not
条件
not
节点必填
一个子条件对象反转子条件的结果。
仅允许一个操作。节点必须包含
evidence
operator
value
;逻辑节点必须仅包含
all
any
not

Value object parameters

值对象参数

ParameterTypeUsed byAllowed values and limitsMeaning
integer
Integer
target_sdk
Any JSON integerNumeric comparison target.
string
String
native_library
1 to 160 safe filename charactersExact native-library filename.
strings
Array of strings
archive_entry
,
manifest_receiver_action
1 to 16 values, each 1 to 160 safe characters for its evidence typeExact archive entries or receiver actions; any listed value may match.
dexClasses
Array of DEX class queries
dex_class
1 to 16 queriesClass queries; any query may match.
manifestAttribute
Manifest attribute query
manifest_attribute
One
application
element, one safe
android:
attribute name, and one Boolean
Exact application-manifest Boolean attribute and expected value.
One value object must contain exactly one of these parameters.
参数类型适用场景允许值和限制含义
integer
整数
target_sdk
任意JSON整数数值比较目标。
string
字符串
native_library
1到160个安全文件名字符精确的原生库文件名。
strings
字符串数组
archive_entry
manifest_receiver_action
1到16个值,每个值对应证据类型为1到160个安全字符精确的归档条目或接收器动作;列出的任意值均可匹配。
dexClasses
DEX类查询数组
dex_class
1到16个查询类查询;任意查询均可匹配。
manifestAttribute
清单属性查询
manifest_attribute
一个
application
元素、一个安全的
android:
属性名和一个布尔值
精确的应用清单布尔属性及其预期值。
一个值对象必须仅包含上述参数中的一个。

Evidence leaf

证据节点

json
{
    "evidence": "native_library",
    "operator": "contains",
    "value": {
        "string": "libflutter.so"
    }
}
All three fields are required and must use a compatible combination from the evidence table below.
json
{
    "evidence": "native_library",
    "operator": "contains",
    "value": {
        "string": "libflutter.so"
    }
}
三个字段均为必填项,且必须使用下方证据表中的兼容组合。

Logical operators

逻辑运算符

OperatorValueResult
all
Array of 1 to 16 conditionsMatches when every child matches.
any
Array of 1 to 16 conditionsMatches when at least one child matches.
not
One condition objectInverts the child result.
Example:
json
{
    "all": [
        {
            "evidence": "target_sdk",
            "operator": "greater_than_or_equal",
            "value": {
                "integer": 35
            }
        },
        {
            "not": {
                "evidence": "native_library",
                "operator": "contains",
                "value": {
                    "string": "liblegacy.so"
                }
            }
        }
    ]
}
运算符结果
all
1到16个条件的数组所有子条件匹配时匹配。
any
1到16个条件的数组至少一个子条件匹配时匹配。
not
一个条件对象反转子条件的结果。
示例:
json
{
    "all": [
        {
            "evidence": "target_sdk",
            "operator": "greater_than_or_equal",
            "value": {
                "integer": 35
            }
        },
        {
            "not": {
                "evidence": "native_library",
                "operator": "contains",
                "value": {
                    "string": "liblegacy.so"
                }
            }
        }
    ]
}

Condition limits

条件限制

  • Maximum nesting depth: 8, with the root condition at depth 1.
  • Maximum condition nodes: 64 per predicate calculation. A facet rule shares the same 64-node budget across all facet conditions.
  • Maximum children in one
    all
    or
    any
    : 16.
  • A condition object must define exactly one operation. It cannot mix a leaf with
    all
    ,
    any
    , or
    not
    .
Prefer the narrowest condition that is supported by reliable evidence. A long condition is not necessarily a more accurate condition.
  • 最大嵌套深度:8,根条件为深度1。
  • 最大条件节点:每个谓词计算64个。维度规则的所有维度条件共享64个节点的预算。
  • 单个
    all
    any
    的最大子条件数:16。
  • 条件对象必须仅定义一个操作,不能将节点与
    all
    any
    not
    混合。
优先选择可靠证据支持的最窄条件。长条件不一定更准确。

Evidence reference

证据参考

EvidenceOperatorValue objectMatch behavior
target_sdk
equal
,
greater_than_or_equal
,
less_than_or_equal
{ "integer": <integer> }
Compares the app's target SDK value.
native_library
contains
{ "string": "<library-name>" }
Matches an exact native-library filename.
archive_entry
contains_any
{ "strings": ["<entry-name>", ...] }
Matches when any exact entry exists in the base or split APKs.
dex_class
contains_any
{ "dexClasses": [<query>, ...] }
Matches when any query matches one DEX class.
manifest_receiver_action
contains_any
{ "strings": ["<action>", ...] }
Matches when any listed action is declared by a manifest receiver.
manifest_attribute
equal
{ "manifestAttribute": { "element": "application", "name": "android:<name>", "boolean": <Boolean> } }
Matches an explicitly declared application-manifest Boolean attribute.
证据运算符值对象匹配行为
target_sdk
equal
greater_than_or_equal
less_than_or_equal
{ "integer": <integer> }
比较应用的目标SDK值。
native_library
contains
{ "string": "<library-name>" }
匹配精确的原生库文件名。
archive_entry
contains_any
{ "strings": ["<entry-name>", ...] }
当基础APK或拆分APK中存在任意精确条目时匹配。
dex_class
contains_any
{ "dexClasses": [<query>, ...] }
当任意查询匹配一个DEX类时匹配。
manifest_receiver_action
contains_any
{ "strings": ["<action>", ...] }
当清单接收器声明了任意列出的动作时匹配。
manifest_attribute
equal
{ "manifestAttribute": { "element": "application", "name": "android:<name>", "boolean": <Boolean> } }
匹配显式声明的应用清单布尔属性。

target_sdk

target_sdk

The integer is compared with the target API recorded for the installed app. The schema does not impose an API-level range, but the value should represent a real Android API level.
json
{
    "evidence": "target_sdk",
    "operator": "less_than_or_equal",
    "value": {
        "integer": 34
    }
}
Use
fingerprint: standard
or omit
fingerprint
for a rule that only depends on target SDK metadata.
整数与已安装应用记录的目标API级别比较。Schema不限制API级别范围,但值应代表真实的Android API级别。
json
{
    "evidence": "target_sdk",
    "operator": "less_than_or_equal",
    "value": {
        "integer": 34
    }
}
对于仅依赖目标SDK元数据的规则,使用
fingerprint: standard
或省略
fingerprint

native_library

native_library

The value is an exact
.so
filename, not a path and not a regular expression. LibChecker checks extracted libraries and libraries packaged in the APK.
json
{
    "evidence": "native_library",
    "operator": "contains",
    "value": {
        "string": "libflutter.so"
    }
}
The string must be 1 to 160 characters and may contain ASCII letters, digits, periods, underscores, plus signs, and hyphens. Use
fingerprint: artifact
.
值为精确的
.so
文件名,不是路径或正则表达式。LibChecker会检查提取的库和APK中打包的库。
json
{
    "evidence": "native_library",
    "operator": "contains",
    "value": {
        "string": "libflutter.so"
    }
}
字符串必须为1到160字符,可包含ASCII字母、数字、句点、下划线、加号和连字符。使用
fingerprint: artifact

archive_entry

archive_entry

This evidence checks exact ZIP entry names across the base and split APKs. It does not read file contents and does not support prefixes, globs, or regular expressions.
json
{
    "evidence": "archive_entry",
    "operator": "contains_any",
    "value": {
        "strings": [
            "META-INF/example.properties"
        ]
    }
}
The list must contain 1 to 16 entry names. Each name must be 1 to 160 characters, use only ASCII letters, digits, periods, underscores, plus signs, hyphens, and slashes, and must not end in a slash or contain
.
or
..
path segments. Use
fingerprint: artifact
.
该证据检查基础APK和拆分APK中的精确ZIP条目名称。它不读取文件内容,不支持前缀、通配符或正则表达式。
json
{
    "evidence": "archive_entry",
    "operator": "contains_any",
    "value": {
        "strings": [
            "META-INF/example.properties"
        ]
    }
}
列表必须包含1到16个条目名称。每个名称必须为1到160字符,仅使用ASCII字母、数字、句点、下划线、加号、连字符和斜杠,且不能以斜杠结尾或包含
.
..
路径段。使用
fingerprint: artifact

manifest_receiver_action

manifest_receiver_action

This evidence reads actions from manifest-declared broadcast receivers across the base and split APKs. It matches when at least one supplied action is found.
json
{
    "evidence": "manifest_receiver_action",
    "operator": "contains_any",
    "value": {
        "strings": [
            "com.example.ACTION_TRIM",
            "com.example.ACTION_KILL"
        ]
    }
}
The list must contain 1 to 16 strings. Each action must be 1 to 160 characters and may contain ASCII letters, digits, underscores, periods, and hyphens. Use
fingerprint: artifact
.
该证据读取基础APK和拆分APK中清单声明的广播接收器的动作。当找到任意提供的动作时匹配。
json
{
    "evidence": "manifest_receiver_action",
    "operator": "contains_any",
    "value": {
        "strings": [
            "com.example.ACTION_TRIM",
            "com.example.ACTION_KILL"
        ]
    }
}
列表必须包含1到16个字符串。每个动作必须为1到160字符,可包含ASCII字母、数字、下划线、句点和连字符。使用
fingerprint: artifact

manifest_attribute

manifest_attribute

This evidence reads an explicitly declared Boolean attribute from the APK's
application
manifest element. A missing attribute does not match, even when the Android platform supplies the same value as a runtime default.
json
{
    "evidence": "manifest_attribute",
    "operator": "equal",
    "value": {
        "manifestAttribute": {
            "element": "application",
            "name": "android:enableOnBackInvokedCallback",
            "boolean": true
        }
    }
}
The attribute name must use the
android:
namespace followed by an ASCII letter and up to 79 ASCII letters, digits, or underscores. Schema v1 supports only the
application
element and Boolean values. Resource-backed Boolean attributes are compared after resource resolution. Use
fingerprint: artifact
.
该证据读取APK的
application
清单元素中显式声明的布尔属性。即使Android平台在运行时提供相同的默认值,缺失的属性也不会匹配。
json
{
    "evidence": "manifest_attribute",
    "operator": "equal",
    "value": {
        "manifestAttribute": {
            "element": "application",
            "name": "android:enableOnBackInvokedCallback",
            "boolean": true
        }
    }
}
属性名必须使用
android:
命名空间,后跟一个ASCII字母和最多79个ASCII字母、数字或下划线。Schema v1仅支持
application
元素和布尔值。资源支持的布尔属性会在资源解析后进行比较。使用
fingerprint: artifact

dex_class

dex_class

dex_class
accepts 1 to 16 class queries. The outer
dexClasses
list is OR: the evidence matches when any query matches any class in the app's base or split APKs.
json
{
    "evidence": "dex_class",
    "operator": "contains_any",
    "value": {
        "dexClasses": [
            {
                "name": {
                    "operator": "starts_with",
                    "value": "Lcom/example/sdk/"
                },
                "stringConstants": [
                    "com.example.ACTION_READY"
                ],
                "methodReferences": [
                    {
                        "definingClass": "Landroid/content/IntentFilter;",
                        "name": "addAction",
                        "parameterTypes": [
                            "Ljava/lang/String;"
                        ]
                    }
                ]
            }
        ]
    }
}
Each query may contain
name
,
stringConstants
,
methodReferences
, or a combination of them. At least one field is required.
dex_class
接受1到16个类查询。外层
dexClasses
列表为OR关系:当任意查询匹配应用基础APK或拆分APK中的任意类时,证据匹配。
json
{
    "evidence": "dex_class",
    "operator": "contains_any",
    "value": {
        "dexClasses": [
            {
                "name": {
                    "operator": "starts_with",
                    "value": "Lcom/example/sdk/"
                },
                "stringConstants": [
                    "com.example.ACTION_READY"
                ],
                "methodReferences": [
                    {
                        "definingClass": "Landroid/content/IntentFilter;",
                        "name": "addAction",
                        "parameterTypes": [
                            "Ljava/lang/String;"
                        ]
                    }
                ]
            }
        ]
    }
}
每个查询可包含
name
stringConstants
methodReferences
或它们的组合。至少需要一个字段。

DEX class query parameters

DEX类查询参数

ParameterTypeRequiredAllowed values and limitsMeaning
name
ObjectNo
operator
plus
value
Restricts the class descriptor.
stringConstants
Array of stringsNo1 to 16 strings, each 1 to 160 characters without control charactersMatches if the class references any listed string.
methodReferences
Array of method-reference objectsNo1 to 16 referencesMatches if the class references any listed method.
At least one query parameter is required. If several parameters are present, all parameter categories must match the same class.
The fields inside one query are AND categories and must be satisfied by the same DEX class:
  • name
    , when present, must match that class.
  • stringConstants
    , when present, succeeds if the class references any string in the list.
  • methodReferences
    , when present, succeeds if the class references any method in the list.
For example, a query containing both
stringConstants
and
methodReferences
requires one class that contains at least one listed string and at least one listed method reference. The matching instructions do not have to appear in the same method. Use separate entries in
dexClasses
when the evidence may be found in different classes.
Use
fingerprint: artifact
for every DEX rule.
参数类型是否必填允许值和限制含义
name
对象
operator
value
限制类描述符。
stringConstants
字符串数组1到16个字符串,每个字符串1到160字符,无控制字符如果类引用了任意列出的字符串,则匹配。
methodReferences
方法引用对象数组1到16个引用如果类引用了任意列出的方法,则匹配。
至少需要一个查询参数。如果存在多个参数,所有参数类别必须匹配同一个类。
一个查询中的字段为AND关系,必须由同一个DEX类满足:
  • 如果存在
    name
    ,必须匹配该类。
  • 如果存在
    stringConstants
    ,当类引用列表中的任意字符串时成功。
  • 如果存在
    methodReferences
    ,当类引用列表中的任意方法时成功。
例如,同时包含
stringConstants
methodReferences
的查询需要一个类,该类至少包含一个列出的字符串和一个列出的方法引用。匹配的指令不需要出现在同一个方法中。当证据可能存在于不同类中时,使用
dexClasses
中的单独条目。
每个DEX规则都使用
fingerprint: artifact

Class names

类名

DEX class names use descriptors, not Java or Kotlin dotted names.
GoalOperatorExample
Match one class
equal
Lcom/example/sdk/EntryPoint;
Match a package or nested prefix
starts_with
Lcom/example/sdk/
Name parameterTypeRequiredPossible values and limitsMeaning
name.operator
StringYes
equal
,
starts_with
Exact descriptor match or descriptor-prefix match.
name.value
StringYesDEX class descriptor pattern beginning with
L
;
equal
must end in
;
Descriptor or prefix to match.
equal
requires the trailing semicolon.
starts_with
may omit it and usually uses a trailing slash for a package prefix. Values begin with
L
and may use letters, digits, underscores, dollar signs, slashes, and hyphens.
DEX类名使用描述符,而不是Java或Kotlin的点分隔名称。
目标运算符示例
匹配单个类
equal
Lcom/example/sdk/EntryPoint;
匹配包或嵌套前缀
starts_with
Lcom/example/sdk/
名称参数类型是否必填可能值和限制含义
name.operator
字符串
equal
starts_with
精确描述符匹配或描述符前缀匹配。
name.value
字符串
L
开头的DEX类描述符模式;
equal
必须以
;
结尾
要匹配的描述符或前缀。
equal
需要结尾的分号。
starts_with
可以省略分号,通常使用结尾的斜杠作为包前缀。值以
L
开头,可包含字母、数字、下划线、美元符号、斜杠和连字符。

String constants

字符串常量

stringConstants
contains 1 to 16 strings, each 1 to 160 characters. Control characters are rejected. These strings are literal DEX string references, not regular expressions or substrings.
stringConstants
包含1到16个字符串,每个字符串1到160字符。拒绝控制字符。这些字符串是字面DEX字符串引用,不是正则表达式或子字符串。

Method references

方法引用

A method reference requires
definingClass
and
name
:
json
{
    "definingClass": "Landroid/content/IntentFilter;",
    "name": "<init>",
    "parameterTypes": [
        "Ljava/lang/String;"
    ]
}
FieldRequiredConstraint
definingClass
YesFull DEX class descriptor ending in
;
, up to the schema limit.
name
YesDEX method name, 1 to 80 characters.
<init>
and
<clinit>
are accepted.
parameterTypes
NoExact parameter descriptor list, at most 16 entries.
Omit
parameterTypes
to match any overload with the same defining class and method name. Provide it to require an exact parameter list. An empty array matches a zero-parameter method.
Primitive descriptors are
Z
(boolean),
B
(byte),
S
(short),
C
(char),
I
(int),
J
(long),
F
(float), and
D
(double). Prefix a descriptor with
[
for each array dimension. Object types use full descriptors such as
Ljava/lang/String;
.
方法引用需要
definingClass
name
json
{
    "definingClass": "Landroid/content/IntentFilter;",
    "name": "<init>",
    "parameterTypes": [
        "Ljava/lang/String;"
    ]
}
字段是否必填约束
definingClass
完整的DEX类描述符,以
;
结尾,不超过schema限制。
name
DEX方法名,1到80字符。接受
<init>
<clinit>
parameterTypes
精确的参数描述符列表,最多16个条目。
省略
parameterTypes
以匹配具有相同定义类和方法名的任意重载。提供该参数以要求精确的参数列表。空数组匹配零参数方法。
原始类型描述符为
Z
(布尔值)、
B
(字节)、
S
(短整型)、
C
(字符)、
I
(整型)、
J
(长整型)、
F
(浮点型)和
D
(双精度浮点型)。为每个数组维度添加
[
前缀。对象类型使用完整描述符,例如
Ljava/lang/String;

Optional metadata

可选元数据

releaseChannel

releaseChannel

  • stable
    is the default and is included in both preview and stable bundles.
  • preview-only
    is included only when the builder uses
    --channel preview
    .
The builder removes
releaseChannel
from the generated catalog. It is a repository publication control, not runtime chart metadata.
  • stable
    为默认值,包含在预览和稳定bundle中。
  • preview-only
    仅在构建器使用
    --channel preview
    时包含。
构建器会从生成的目录中移除
releaseChannel
。它是仓库发布控制,不是运行时图表元数据。

availability

availability

Schema v1 online rules only accept
always
, which is also the default. Omit this field unless a future schema adds a supported online availability gate.
Schema v1在线规则仅接受
always
,这也是默认值。除非未来schema添加支持的在线可用性限制,否则省略该字段。

requiresFeatureInitialization

requiresFeatureInitialization

When
true
, LibChecker hides the chart until its feature initialization has finished. Current online evidence types do not require feature data, so new online rules should normally omit this field or use
false
.
当为
true
时,LibChecker会在功能初始化完成后才显示图表。当前在线证据类型不需要功能数据,因此新的在线规则通常应省略该字段或设置为
false

controls

controls

Schema v1 allows no online chart controls. Omit this field. An explicit empty array is valid but adds no behavior.
Schema v1不允许在线图表控件。省略该字段。显式的空数组是有效的,但不会添加任何行为。

dashboard

dashboard

Schema v1 online rules only accept
none
, which is the default. Omit it.
Schema v1在线规则仅接受
none
,这也是默认值。省略该字段。

fingerprint

fingerprint

The fingerprint controls when LibChecker discards cached chart results after installed-app data changes. It does not grant access to additional evidence.
ValueUse
standard
Metadata-based rules such as
target_sdk
. This is the default.
artifact
Rules that inspect native libraries, archive entries, DEX, or manifest contents.
features
Rules that depend on LibChecker's initialized feature data. No schema v1 online evidence currently needs it.
Choose the fingerprint that covers every evidence leaf in the rule. A rule that combines target SDK with DEX evidence should use
artifact
.
指纹控制LibChecker在已安装应用数据更改时何时丢弃缓存的图表结果。它不授予访问额外证据的权限。
用途
standard
基于元数据的规则,例如
target_sdk
。这是默认值。
artifact
检查原生库、归档条目、DEX或清单内容的规则。
features
依赖LibChecker初始化功能数据的规则。目前没有Schema v1在线证据需要它。
选择覆盖规则中所有证据节点的指纹。结合目标SDK和DEX证据的规则应使用
artifact

Validation and tests

验证和测试

Run:
shell
python3 -m unittest chart.tools.test_build_bundle
The JSON Schema defines the complete object shape and field constraints. The Python builder performs additional semantic validation. It rejects incompatible evidence/operator/value combinations, unsafe URLs, unsafe icon paths and SVG content, duplicate IDs, duplicate facet IDs, and complexity-limit violations.
When adding a rule, update the existing assertions in
chart/tools/test_build_bundle.py
:
  1. Add the ID in sorted order to
    test_source_rules_are_valid
    .
  2. Add a new icon path in sorted archive order and update the expected catalog count in
    test_bundle_is_deterministic_and_contains_only_expected_files
    .
  3. Update
    test_stable_bundle_excludes_preview_only_rules
    according to the rule's release channel.
  4. Add one focused test that asserts the important detection values, condition ordering, icon render mode, details URL, or another property that reviewers should not accidentally change.
  5. Add negative validation tests when you introduce a new schema capability or validator branch.
Do not weaken limits or delete regression assertions only to make a new rule pass.
运行:
shell
python3 -m unittest chart.tools.test_build_bundle
JSON Schema定义了完整的对象结构和字段约束。Python构建器会执行额外的语义验证,拒绝不兼容的证据/运算符/值组合、不安全的URL、不安全的图标路径和SVG内容、重复ID、重复维度ID以及违反复杂度限制的内容。
添加规则时,更新
chart/tools/test_build_bundle.py
中的现有断言:
  1. 将ID按排序顺序添加到
    test_source_rules_are_valid
    中。
  2. 按归档顺序添加新的图标路径,并在
    test_bundle_is_deterministic_and_contains_only_expected_files
    中更新预期的目录计数。
  3. 根据规则的发布通道更新
    test_stable_bundle_excludes_preview_only_rules
  4. 添加一个针对性测试,断言重要的检测值、条件顺序、图标渲染模式、详情URL或其他评审人员不应意外更改的属性。
  5. 当引入新的schema功能或验证分支时,添加负向验证测试。
请勿为了让新规则通过而削弱限制或删除回归断言。

Bundle generation

Bundle生成

For a local preview, write to a temporary directory so that validation does not modify tracked generated files:
shell
python3 chart/tools/build_bundle.py \
  --bundle-version 12 \
  --channel preview \
  --minimum-app-version-code 2731 \
  --output-dir /tmp/libchecker-chart-preview
For the final branch artifact, omit
--output-dir
to write to
chart/cloud/v1/
:
shell
python3 chart/tools/build_bundle.py \
  --bundle-version 12 \
  --channel preview \
  --minimum-app-version-code 2731
Builder arguments:
ArgumentRequiredMeaning
--bundle-version
YesPositive, monotonically increasing publication version for the target branch.
--channel
No
preview
by default, or
stable
. Preview includes both release channels; stable excludes
preview-only
.
--minimum-app-version-code
NoFirst LibChecker version code that can safely load every rule in the bundle. Defaults to
0
, which should only be published when all supported clients are compatible.
--output-dir
NoDestination directory. Defaults to
chart/cloud/v1/
.
If the rule uses only evidence and calculation features already supported by the published app, retain the branch's compatible minimum app version. If it depends on a new client capability, coordinate the app change first and set the exact first compatible version code. Do not guess this number.
The builder:
  • validates every source rule and referenced SVG;
  • sorts rules by ID and icons by path;
  • writes a deterministic ZIP containing
    catalog.json
    and referenced icons;
  • limits the bundle to 64 rules and 2 MiB;
  • computes
    bundleSha256
    and
    bundleSize
    ;
  • writes
    manifest.json
    with schema, publication, and compatibility metadata.
Commit
chart.bundle
and
manifest.json
together. A checksum or size from one generation cannot be paired with a bundle from another generation.
对于本地预览,写入临时目录,以便验证不会修改已跟踪的生成文件:
shell
python3 chart/tools/build_bundle.py \
  --bundle-version 12 \
  --channel preview \
  --minimum-app-version-code 2731 \
  --output-dir /tmp/libchecker-chart-preview
对于最终分支工件,省略
--output-dir
以写入
chart/cloud/v1/
shell
python3 chart/tools/build_bundle.py \
  --bundle-version 12 \
  --channel preview \
  --minimum-app-version-code 2731
构建器参数:
参数是否必填含义
--bundle-version
目标分支的正整数、单调递增的发布版本。
--channel
默认值为
preview
,或
stable
。预览通道包含两个发布通道;稳定通道排除
preview-only
规则。
--minimum-app-version-code
可以安全加载bundle中所有规则的第一个LibChecker版本号。默认值为
0
,仅当所有支持的客户端都兼容时才应发布。
--output-dir
目标目录。默认值为
chart/cloud/v1/
如果规则仅使用已发布应用支持的证据和计算功能,请保留分支的兼容最低应用版本。如果它依赖新的客户端功能,请先协调应用变更,然后设置确切的第一个兼容版本号。请勿猜测该数字。
构建器会:
  • 验证每个源规则和引用的SVG;
  • 按ID排序规则,按路径排序图标;
  • 写入包含
    catalog.json
    和引用图标的确定性ZIP;
  • 将bundle限制为64个规则和2 MiB;
  • 计算
    bundleSha256
    bundleSize
  • 写入包含schema、发布和兼容性元数据的
    manifest.json
同时提交
chart.bundle
manifest.json
。一次生成的校验和或大小不能与另一次生成的bundle配对。

Manual verification

手动验证

Automated validation proves that a rule is well-formed. It does not prove that the evidence identifies the intended apps.
Before requesting stable publication:
  1. Install a compatible LibChecker build that reads the preview branch.
  2. Check at least one known matching app and one known non-matching app.
  3. For facets, verify every facet independently and confirm that an app matching several facets shows all expected chips in rule order.
  4. Check the chart title, group titles, description, reference link, icon size, colors, light theme, and dark theme.
  5. Record the app versions or sample APKs used for testing in the PR description.
  6. Rebuild with
    --channel stable
    and inspect the catalog before publishing. Every
    preview-only
    rule must be absent.
自动化验证只能证明规则格式正确,不能证明证据能识别预期的应用。
请求稳定发布前,请执行以下操作:
  1. 安装兼容的LibChecker版本,使其读取预览分支。
  2. 检查至少一个已知匹配的应用和一个已知不匹配的应用。
  3. 对于维度规则,独立验证每个维度,并确认匹配多个维度的应用会按规则顺序显示所有预期标签。
  4. 检查图表标题、组标题、描述、参考链接、图标大小、颜色、浅色主题和深色主题。
  5. 在PR描述中记录用于测试的应用版本或示例APK。
  6. 使用
    --channel stable
    重新构建,并在发布前检查目录。所有
    preview-only
    规则必须不存在。

Pull request checklist

Pull Request检查清单

  • The rule solves one clearly described statistic.
  • The ID and filename are stable and follow the naming rules.
  • A new rule starts at revision
    1
    ; an edited published rule increments its revision.
  • All text includes equivalent
    en
    and
    zh-Hans
    translations.
  • The description is neutral and the HTTPS reference is primary.
  • The calculation uses only supported evidence and compatible operators.
  • DEX queries use descriptors and preserve same-class matching semantics.
  • The SVG passes the safety and viewBox requirements.
  • The release channel and fingerprint match the rule's maturity and evidence.
  • Focused tests cover the important matching data and channel behavior.
  • Unit tests pass.
  • Matching and non-matching apps were checked with a compatible LibChecker build.
  • The generated bundle and manifest were rebuilt and committed together.
  • 规则解决一个清晰描述的统计需求。
  • ID和文件名稳定,符合命名规则。
  • 新规则从版本
    1
    开始;已发布的编辑规则递增版本号。
  • 所有文本包含等效的
    en
    zh-Hans
    翻译。
  • 描述中立,HTTPS参考为权威来源。
  • 计算仅使用支持的证据和兼容的运算符。
  • DEX查询使用描述符,保留同类匹配语义。
  • SVG通过安全和viewBox要求。
  • 发布通道和指纹与规则的成熟度和证据匹配。
  • 针对性测试覆盖重要的匹配数据和通道行为。
  • 单元测试通过。
  • 使用兼容的LibChecker版本检查了匹配和不匹配的应用。
  • 重新生成并同时提交了bundle和清单文件。

Recovery after a bad publication

错误发布后的恢复

Do not reuse an older bundle version. Restore the last known-good source rules and generated contents, then publish them with a higher
bundleVersion
. Compatible LibChecker clients retain their cached bundle when a download, checksum, schema, or minimum-version check fails.
请勿重用旧的bundle版本。恢复最后一个已知良好的源规则和生成内容,然后使用更高的
bundleVersion
发布。当下载、校验和、schema或最低版本检查失败时,兼容的LibChecker客户端会保留其缓存的bundle。