@buaa_smat/hometrans 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +141 -124
- package/agents/build-fixer.md +1 -0
- package/agents/code-review-fix.md +1 -0
- package/agents/code-reviewer.md +1 -0
- package/agents/logic-coding.md +1 -0
- package/agents/logic-context-builder.md +1 -0
- package/agents/review-fixer.md +1 -0
- package/agents/self-test-fixer.md +1 -0
- package/agents/self-tester.md +260 -233
- package/agents/spec-generator.md +1 -0
- package/agents/test-tools/autotest/README.md +223 -0
- package/agents/test-tools/autotest/config.yaml.example +58 -0
- package/agents/test-tools/autotest/pyproject.toml +16 -0
- package/agents/test-tools/autotest/report_tool.py +759 -0
- package/agents/test-tools/autotest/self_test_runner.py +773 -0
- package/agents/test-tools/autotest/testcases_schema.md +143 -0
- package/agents/test-tools/autotest/testcases_tool.py +215 -0
- package/agents/test-tools/autotest/uv.lock +3156 -0
- package/agents/test-tools/harmony_autotest-0.1.0-py3-none-any.whl +0 -0
- package/agents/test-tools/hypium-6.1.0.210-py3-none-any.whl +0 -0
- package/agents/test-tools/hypium_mcp-0.6.5-py3-none-any.whl +0 -0
- package/agents/test-tools/xdevice-6.1.0.210-py3-none-any.whl +0 -0
- package/agents/test-tools/xdevice_devicetest-6.1.0.210-py3-none-any.whl +0 -0
- package/agents/test-tools/xdevice_ohos-6.1.0.210-py3-none-any.whl +0 -0
- package/dist/cli/config-store.js +27 -2
- package/dist/cli/config.js +17 -6
- package/dist/cli/index.js +3 -2
- package/dist/cli/init.js +135 -22
- package/dist/cli/mcp.js +2 -2
- package/dist/context/index.js +165 -69
- package/package.json +59 -60
- package/skills/code-dev-review-fix/SKILL.md +279 -0
- package/skills/code-dev-review-fix-workspace/evals/evals.json +56 -0
- package/skills/code-dev-review-fix-workspace/iteration-1/routing-results.md +23 -0
- package/skills/convert_pipeline/SKILL.md +423 -439
- package/skills/hmos-resources-convert/SKILL.md +623 -0
- package/skills/hmos-resources-convert/evals/evals.json +171 -0
- package/skills/hmos-resources-convert/references/conversion-rules.md +663 -0
- package/skills/hmos-resources-convert/references/dependency-analysis-rules.md +388 -0
- package/skills/hmos-resources-convert/references/resource-mapping-rules.md +457 -0
- package/skills/hmos-resources-convert/references/xml-drawable-to-svg-rules.md +513 -0
- package/skills/hmos-resources-convert/template/AppScope/app.json5 +10 -0
- package/skills/hmos-resources-convert/template/AppScope/resources/base/element/string.json +8 -0
- package/skills/hmos-resources-convert/template/AppScope/resources/base/media/background.png +0 -0
- package/skills/hmos-resources-convert/template/AppScope/resources/base/media/foreground.png +0 -0
- package/skills/hmos-resources-convert/template/AppScope/resources/base/media/layered_image.json +7 -0
- package/skills/hmos-resources-convert/template/build-profile.json5 +42 -0
- package/skills/hmos-resources-convert/template/code-linter.json5 +32 -0
- package/skills/hmos-resources-convert/template/entry/build-profile.json5 +33 -0
- package/skills/hmos-resources-convert/template/entry/hvigorfile.ts +6 -0
- package/skills/hmos-resources-convert/template/entry/obfuscation-rules.txt +23 -0
- package/skills/hmos-resources-convert/template/entry/oh-package.json5 +10 -0
- package/skills/hmos-resources-convert/template/entry/src/main/ets/entryability/EntryAbility.ets +48 -0
- package/skills/hmos-resources-convert/template/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets +16 -0
- package/skills/hmos-resources-convert/template/entry/src/main/ets/pages/Index.ets +23 -0
- package/skills/hmos-resources-convert/template/entry/src/main/module.json5 +55 -0
- package/skills/hmos-resources-convert/template/entry/src/main/resources/base/element/color.json +8 -0
- package/skills/hmos-resources-convert/template/entry/src/main/resources/base/element/float.json +8 -0
- package/skills/hmos-resources-convert/template/entry/src/main/resources/base/element/string.json +16 -0
- package/skills/hmos-resources-convert/template/entry/src/main/resources/base/media/background.png +0 -0
- package/skills/hmos-resources-convert/template/entry/src/main/resources/base/media/foreground.png +0 -0
- package/skills/hmos-resources-convert/template/entry/src/main/resources/base/media/layered_image.json +7 -0
- package/skills/hmos-resources-convert/template/entry/src/main/resources/base/media/startIcon.png +0 -0
- package/skills/hmos-resources-convert/template/entry/src/main/resources/base/profile/backup_config.json +3 -0
- package/skills/hmos-resources-convert/template/entry/src/main/resources/base/profile/main_pages.json +5 -0
- package/skills/hmos-resources-convert/template/entry/src/main/resources/dark/element/color.json +8 -0
- package/skills/hmos-resources-convert/template/entry/src/mock/mock-config.json5 +2 -0
- package/skills/hmos-resources-convert/template/entry/src/ohosTest/ets/test/Ability.test.ets +35 -0
- package/skills/hmos-resources-convert/template/entry/src/ohosTest/ets/test/List.test.ets +5 -0
- package/skills/hmos-resources-convert/template/entry/src/ohosTest/module.json5 +16 -0
- package/skills/hmos-resources-convert/template/entry/src/test/List.test.ets +5 -0
- package/skills/hmos-resources-convert/template/entry/src/test/LocalUnit.test.ets +33 -0
- package/skills/hmos-resources-convert/template/hvigor/hvigor-config.json5 +23 -0
- package/skills/hmos-resources-convert/template/hvigorfile.ts +6 -0
- package/skills/hmos-resources-convert/template/oh-package-lock.json5 +28 -0
- package/skills/hmos-resources-convert/template/oh-package.json5 +10 -0
- package/skills/hmos-resources-convert/tools/apktool.bat +85 -0
- package/skills/hmos-resources-convert/tools/apktool_3.0.1.jar +0 -0
- package/skills/hmos-ui-align/SKILL.md +182 -0
- package/skills/hmos-ui-align/config-example.json +11 -0
- package/skills/hmos-ui-align/config.json +11 -0
- package/skills/hmos-ui-align/diff_analysis.md +53 -0
- package/skills/hmos-ui-align/page_align.md +62 -0
- package/skills/hmos-ui-align/readme.md +231 -0
- package/skills/hmos-ui-align/references/Comparison_Template.md +2 -0
- package/skills/hmos-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/@Link/350/243/205/351/245/260/345/231/250/357/274/232/347/210/266/345/255/220/345/217/214/345/220/221/345/220/214/346/255/245.md +648 -0
- package/skills/hmos-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/@Observed/350/243/205/351/245/260/345/231/250/345/222/214@ObjectLink/350/243/205/351/245/260/345/231/250/357/274/232/345/265/214/345/245/227/347/261/273/345/257/271/350/261/241/345/261/236/346/200/247/345/217/230/345/214/226.md +2089 -0
- package/skills/hmos-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/@Prop/350/243/205/351/245/260/345/231/250/357/274/232/347/210/266/345/255/220/345/215/225/345/220/221/345/220/214/346/255/245.md +1033 -0
- package/skills/hmos-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/@Provide/350/243/205/351/245/260/345/231/250/345/222/214@Consume/350/243/205/351/245/260/345/231/250/357/274/232/344/270/216/345/220/216/344/273/243/347/273/204/344/273/266/345/217/214/345/220/221/345/220/214/346/255/245.md +1183 -0
- package/skills/hmos-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/@State/350/243/205/351/245/260/345/231/250/357/274/232/347/273/204/344/273/266/345/206/205/347/212/266/346/200/201.md +576 -0
- package/skills/hmos-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/@Track/350/243/205/351/245/260/345/231/250/357/274/232class/345/257/271/350/261/241/345/261/236/346/200/247/347/272/247/346/233/264/346/226/260.md +297 -0
- package/skills/hmos-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/@Watch/350/243/205/351/245/260/345/231/250/357/274/232/347/212/266/346/200/201/345/217/230/351/207/217/346/233/264/346/224/271/351/200/232/347/237/245.md +395 -0
- package/skills/hmos-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/AppStorage/357/274/232/345/272/224/347/224/250/345/205/250/345/261/200/347/232/204UI/347/212/266/346/200/201/345/255/230/345/202/250.md +903 -0
- package/skills/hmos-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/Environment/357/274/232/350/256/276/345/244/207/347/216/257/345/242/203/346/237/245/350/257/242.md +106 -0
- package/skills/hmos-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/LocalStorage/357/274/232/351/241/265/351/235/242/347/272/247UI/347/212/266/346/200/201/345/255/230/345/202/250.md +1178 -0
- package/skills/hmos-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/MVVM/346/250/241/345/274/217V1.md +911 -0
- package/skills/hmos-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/MVVM/346/250/241/345/274/217/357/274/210V1/357/274/211.md +911 -0
- package/skills/hmos-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/PersistentStorage/357/274/232/346/214/201/344/271/205/345/214/226/345/255/230/345/202/250UI/347/212/266/346/200/201.md +355 -0
- package/skills/hmos-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243//347/256/241/347/220/206/345/272/224/347/224/250/346/213/245/346/234/211/347/232/204/347/212/266/346/200/201/346/246/202/350/277/260.md +11 -0
- package/skills/hmos-ui-align/references/UI_Analysis_Template.md +4 -0
- package/skills/hmos-ui-align/references/android-to-harmonyOS-ui-atomic-component-mapping-reference.md +2535 -0
- package/skills/hmos-ui-align/references/android-to-harmonyOS-ui-interaction-mapping-reference.md +555 -0
- package/skills/hmos-ui-align/references/android-to-harmonyOS-ui-layout-mapping-reference.md +117 -0
- package/skills/hmos-ui-align/scripts/app_feature_verify.py +443 -0
- package/skills/hmos-ui-align/scripts/navigation-capure.md +37 -0
- package/skills/hmos-ui-align/scripts/page_capture.py +592 -0
- package/skills/hmos-ui-align-batch/SKILL.md +99 -0
- package/skills/hmos-ui-align-batch/references/conversion-procedure.md +180 -0
- package/skills/hmos-ui-align-batch/references/mappings/android-to-harmonyOS-ui-atomic-component-mapping-reference.md +2535 -0
- package/skills/hmos-ui-align-batch/references/mappings/android-to-harmonyOS-ui-interaction-mapping-reference.md +555 -0
- package/skills/hmos-ui-align-batch/references/mappings/android-to-harmonyOS-ui-layout-mapping-reference.md +117 -0
- package/skills/hmos-ui-align-batch/references/mvvm/@Link/350/243/205/351/245/260/345/231/250/357/274/232/347/210/266/345/255/220/345/217/214/345/220/221/345/220/214/346/255/245.md +648 -0
- package/skills/hmos-ui-align-batch/references/mvvm/@Observed/350/243/205/351/245/260/345/231/250/345/222/214@ObjectLink/350/243/205/351/245/260/345/231/250/357/274/232/345/265/214/345/245/227/347/261/273/345/257/271/350/261/241/345/261/236/346/200/247/345/217/230/345/214/226.md +2089 -0
- package/skills/hmos-ui-align-batch/references/mvvm/@Prop/350/243/205/351/245/260/345/231/250/357/274/232/347/210/266/345/255/220/345/215/225/345/220/221/345/220/214/346/255/245.md +1033 -0
- package/skills/hmos-ui-align-batch/references/mvvm/@Provide/350/243/205/351/245/260/345/231/250/345/222/214@Consume/350/243/205/351/245/260/345/231/250/357/274/232/344/270/216/345/220/216/344/273/243/347/273/204/344/273/266/345/217/214/345/220/221/345/220/214/346/255/245.md +1183 -0
- package/skills/hmos-ui-align-batch/references/mvvm/@State/350/243/205/351/245/260/345/231/250/357/274/232/347/273/204/344/273/266/345/206/205/347/212/266/346/200/201.md +576 -0
- package/skills/hmos-ui-align-batch/references/mvvm/@Track/350/243/205/351/245/260/345/231/250/357/274/232class/345/257/271/350/261/241/345/261/236/346/200/247/347/272/247/346/233/264/346/226/260.md +297 -0
- package/skills/hmos-ui-align-batch/references/mvvm/@Watch/350/243/205/351/245/260/345/231/250/357/274/232/347/212/266/346/200/201/345/217/230/351/207/217/346/233/264/346/224/271/351/200/232/347/237/245.md +395 -0
- package/skills/hmos-ui-align-batch/references/mvvm/AppStorage/357/274/232/345/272/224/347/224/250/345/205/250/345/261/200/347/232/204UI/347/212/266/346/200/201/345/255/230/345/202/250.md +903 -0
- package/skills/hmos-ui-align-batch/references/mvvm/Environment/357/274/232/350/256/276/345/244/207/347/216/257/345/242/203/346/237/245/350/257/242.md +106 -0
- package/skills/hmos-ui-align-batch/references/mvvm/LocalStorage/357/274/232/351/241/265/351/235/242/347/272/247UI/347/212/266/346/200/201/345/255/230/345/202/250.md +1178 -0
- package/skills/hmos-ui-align-batch/references/mvvm/MVVM/346/250/241/345/274/217/357/274/210V1/357/274/211.md +911 -0
- package/skills/hmos-ui-align-batch/references/mvvm/PersistentStorage/357/274/232/346/214/201/344/271/205/345/214/226/345/255/230/345/202/250UI/347/212/266/346/200/201.md +355 -0
- package/skills/hmos-ui-align-batch/references/mvvm//347/256/241/347/220/206/345/272/224/347/224/250/346/213/245/346/234/211/347/232/204/347/212/266/346/200/201/346/246/202/350/277/260.md +11 -0
- package/skills/hmos-ui-align-batch/scripts/android_parse_fast.py +1606 -0
- package/skills/self-test/SKILL.md +369 -0
- package/skills/self-test/readme.md +309 -0
- package/skills/spec-generator-skill/SKILL.md +332 -0
- package/skills/spec-generator-skill/references/android-platform-tokens.md +105 -0
- package/skills/spec-generator-skill/references/spec-sample-1.md +78 -0
- package/skills/spec-generator-skill/references/spec-sample-2.md +58 -0
- package/skills/spec-generator-skill/references/spec-sample-3.md +116 -0
- package/skills/spec-generator-skill/references/step4-report-template.md +33 -0
- package/agents/self-test-setup.md +0 -165
- package/dist/context/resources/sdkConfig.json +0 -24
- package/src/context/resources/sdkConfig.json +0 -24
|
@@ -0,0 +1,623 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: hmos-resources-convert
|
|
3
|
+
description: Convert Android project resources to HarmonyOS project resources. Use this skill when the user wants to migrate, convert, or transfer resource files (strings, colors, dimensions, images, drawables, icons, etc.) from an Android project to a HarmonyOS project. Also trigger when the user mentions Android-to-HarmonyOS migration involving resource files, qualifier directories (like drawable-hdpi, values-zh), or resource format conversion (XML to JSON). Even partial mentions of "Android resources to HarmonyOS" or "migrate Android res" should trigger this skill.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Android to HarmonyOS Resource Converter
|
|
7
|
+
|
|
8
|
+
This skill converts resource files from an Android project into the resource format used by HarmonyOS projects. It attempts to build the Android APK and decompile it with apktool to get the complete merged resource set (including all library dependencies). If the build fails or no APK is available, it falls back to converting directly from the project's source `res/` directory — which may be missing library-provided resources, but still produces a useful conversion with clear reporting of what's missing and why. In addition to the standard conversion report, it also produces a dedicated Android resources ↔ HarmonyOS resources mapping markdown document at the user-provided `resource_mapping_path`.
|
|
9
|
+
|
|
10
|
+
## Inputs
|
|
11
|
+
|
|
12
|
+
1. **Android project path** — root directory of the Android project (contains `build.gradle` or `build.gradle.kts`)
|
|
13
|
+
2. **HarmonyOS project output path** — where the new HarmonyOS project will be created
|
|
14
|
+
3. **resource_mapping_path** — full output path of the markdown file that records the Android resource inventory and the Android ↔ HarmonyOS mapping details. Please write this file in 中文.
|
|
15
|
+
4. **Android apk path** (optional) — full path of the apk file corresponding to the "Android project path" above. If this is provided, then start the workflow below from step 3.
|
|
16
|
+
|
|
17
|
+
## Workflow
|
|
18
|
+
|
|
19
|
+
### Step 1: Initialize HarmonyOS Project
|
|
20
|
+
|
|
21
|
+
**Skip condition**: Before copying, check if the HarmonyOS output path already exists and is non-empty (i.e., it contains files or directories such as `AppScope/`, `entry/`, `build-profile.json5`, etc.). If it does, this is an existing HarmonyOS project — skip template initialization entirely and proceed directly to Step 2. Only copy the template when the output path doesn't exist or is empty.
|
|
22
|
+
|
|
23
|
+
When initialization is needed, copy the bundled HarmonyOS project template to the output path:
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
Template source: <skill_dir>/template/
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
- Copy the entire template directory to the target path
|
|
30
|
+
- Preserve the template's directory structure (AppScope, entry, hvigor, etc.)
|
|
31
|
+
- The main resource target directory is: `<output>/entry/src/main/resources/`
|
|
32
|
+
|
|
33
|
+
### Step 2: Attempt to Build the Android APK
|
|
34
|
+
|
|
35
|
+
Try to build the Android project to produce an APK containing all merged resources (source + library dependencies + generated resources). The decompiled APK is the ideal source because it contains everything — but building is not always possible.
|
|
36
|
+
|
|
37
|
+
1. Ask the user which Gradle build variant to use (e.g., `assembleDebug`, `assembleRelease`, `assembleFossDebug`). Default to `assembleDebug` if the user has no preference — debug builds include all resources without optimization.
|
|
38
|
+
|
|
39
|
+
2. Run the build:
|
|
40
|
+
```bash
|
|
41
|
+
cd <android_project>
|
|
42
|
+
./gradlew <variant>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
3. **If the build succeeds**: locate the APK in `<android_project>/app/build/outputs/apk/`. If multiple APKs exist, prefer the debug variant. Record `build_status = "success"` and proceed to Step 3 (decompile).
|
|
46
|
+
|
|
47
|
+
4. **If the build fails**: record the build error output and `build_status = "failed"`. Also check if a previously-built APK already exists at `<android_project>/app/build/outputs/apk/`. If an existing APK is found, use it and record `build_status = "failed_using_cached_apk"`. If no APK exists at all, skip Step 3 entirely and proceed to Step 4 using the source `res/` directory. Set `resource_source = "source_res"`.
|
|
48
|
+
|
|
49
|
+
The reason we prefer the decompiled APK: it contains all merged resources from source code AND library dependencies (AARs, Maven artifacts). When falling back to source `res/`, library resources are missing, which means some resource references may be unresolvable. The conversion report will clearly flag this.
|
|
50
|
+
|
|
51
|
+
### Step 3: Decompile the APK with apktool (skip if no APK)
|
|
52
|
+
|
|
53
|
+
If an APK is available (from a successful build or a cached previous build), decompile it:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
java -jar <skill_dir>/tools/apktool_3.0.1.jar d <apk_path> -o <decompiled_output_path>
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
The skill bundles `apktool_3.0.1.jar` in its `tools/` directory. Java must be available in the system PATH.
|
|
60
|
+
|
|
61
|
+
The decompiled output at `<decompiled_output_path>/res/` contains the **complete merged resource set**. Set `resource_source = "decompiled_apk"` and use this as the conversion source.
|
|
62
|
+
|
|
63
|
+
If no APK is available, skip this step. The conversion source will be the project's source `res/` directory (typically `<android_project>/app/src/main/res/`). Set `resource_source = "source_res"`.
|
|
64
|
+
|
|
65
|
+
### Step 4: Convert Resources
|
|
66
|
+
|
|
67
|
+
Read the detailed conversion rules from `references/conversion-rules.md` before performing conversions. Convert all resources found in the resource source directory (either decompiled `res/` or source `res/`). Read `references/resource-mapping-rules.md` before conversion as well — every conversion, skip, fallback, and unmappable case must also append structured mapping metadata for the final markdown written to `resource_mapping_path`.
|
|
68
|
+
|
|
69
|
+
**Determining the source `res/` directory when using source fallback:**
|
|
70
|
+
- Check `<android_project>/app/src/main/res/`
|
|
71
|
+
- If multi-module, also check other module directories
|
|
72
|
+
- If the project uses flavor source sets, include those too (e.g., `app/src/debug/res/`, `app/src/flavor/res/`)
|
|
73
|
+
|
|
74
|
+
#### 4.1 Resource Type Mapping
|
|
75
|
+
|
|
76
|
+
| Android Resource Dir | HarmonyOS Target | Notes |
|
|
77
|
+
|---|---|---|
|
|
78
|
+
| `drawable/` (images: png, jpg, webp, gif) | `base/media/` | Direct file copy |
|
|
79
|
+
| `drawable/` (nine-patch: `*.9.png`) | `base/media/` as `*_9.png` | Rename `.9.png` → `_9.png`; HarmonyOS does not allow `.` in resource filenames except for the final extension separator. Nine-patch stretching behavior is lost — log in report. |
|
|
80
|
+
| `drawable/` (Android vector drawables: `<vector>`) | `base/media/` as `.svg` | Convert VectorDrawable XML to SVG format |
|
|
81
|
+
| `drawable/` (shape drawables: `<shape>`) | `base/media/` as `.svg` | Convert shape XML to SVG |
|
|
82
|
+
| `drawable/` (layer-list drawables: `<layer-list>`) | `base/media/` as `.svg` | Convert layered drawable to SVG with nested elements |
|
|
83
|
+
| `drawable/` (selector/state-list drawables) | `base/media/` (default state as `.svg`) | Extract default state item and convert to SVG; log state variants in report |
|
|
84
|
+
| `drawable/` (ripple, animated-vector, transition) | No direct equivalent | Log as unmappable; note in report |
|
|
85
|
+
| `mipmap/` (PNG/WEBP images) | `base/media/` | App launcher icons — direct copy; rename `.9.png` → `_9.png` if nine-patch |
|
|
86
|
+
| `mipmap/` (adaptive-icon XML: `<adaptive-icon>`) | `base/media/` as `xxx_layered_image.json` | Convert to layered-image JSON (see below) |
|
|
87
|
+
| `mipmap/` (vector XML: `<vector>`) | `base/media/` as `.svg` | Convert VectorDrawable to SVG |
|
|
88
|
+
| `values/strings.xml` | `base/element/string.json` | XML → JSON conversion |
|
|
89
|
+
| `values/colors.xml` | `base/element/color.json` | XML → JSON; fix color format |
|
|
90
|
+
| `values/dimens.xml` | `base/element/float.json` | XML → JSON; convert units |
|
|
91
|
+
| `values/integers.xml` | `base/element/integer.json` | XML → JSON |
|
|
92
|
+
| `values/bools.xml` | `base/element/boolean.json` | XML → JSON |
|
|
93
|
+
| `values/arrays.xml` (string-array) | `base/element/strarray.json` | XML → JSON |
|
|
94
|
+
| `values/arrays.xml` (integer-array) | `base/element/intarray.json` | XML → JSON |
|
|
95
|
+
| `values/plurals.xml` | `base/element/plural.json` | XML → JSON |
|
|
96
|
+
| `values/styles.xml` | No direct equivalent | Log in report |
|
|
97
|
+
| `values/attrs.xml` | No direct equivalent | Log in report |
|
|
98
|
+
| `raw/` | `rawfile/` | Direct file copy |
|
|
99
|
+
| `font/` | `rawfile/fonts/` | Copy fonts to rawfile |
|
|
100
|
+
| `xml/` | `base/profile/` | Only config-like XML; rename to .json if possible |
|
|
101
|
+
| `anim/`, `animator/` | No direct equivalent | Log in report |
|
|
102
|
+
| `layout/` | No direct equivalent | ArkUI uses declarative UI; log in report |
|
|
103
|
+
| `menu/` | No direct equivalent | Log in report |
|
|
104
|
+
| `color/` (color state lists) | No direct equivalent | Log in report |
|
|
105
|
+
|
|
106
|
+
#### 4.1.1 Adaptive Icon → Layered-Image JSON Conversion
|
|
107
|
+
|
|
108
|
+
Android adaptive-icon XML files (root element `<adaptive-icon>`, commonly found in `mipmap-anydpi-v26/`) are converted to HarmonyOS layered-image JSON files.
|
|
109
|
+
|
|
110
|
+
**Conversion rules:**
|
|
111
|
+
1. Parse the `<adaptive-icon>` XML and extract the `<background>` and `<foreground>` elements
|
|
112
|
+
2. Only `background` and `foreground` are valid keys in the output JSON. Skip `monochrome` (and any other elements) **from the JSON output** — HarmonyOS has no layered-image equivalent. However, the resource *referenced* by `monochrome` (e.g., `@drawable/ic_launcher_monochrome`) is a real asset that should still be converted as a normal drawable.
|
|
113
|
+
3. Convert Android resource references to HarmonyOS format:
|
|
114
|
+
- `@drawable/xxx` → `$media:xxx`
|
|
115
|
+
- `@mipmap/xxx` → `$media:xxx`
|
|
116
|
+
- `@color/xxx` → **generate a solid color PNG** (see rule 4 below)
|
|
117
|
+
4. **Critical — color background handling**: HarmonyOS `layered-image` only accepts `$media:xxx` references. It does NOT support `$color:xxx`. When the `background` (or `foreground`) references a color (`@color/xxx`):
|
|
118
|
+
a. Look up the **resolved hex value** of `@color/xxx` from the resource source's `res/values*/colors.xml`. Follow reference chains if the color itself references another color — keep resolving until you reach a concrete hex value.
|
|
119
|
+
b. Generate a solid-color PNG filled entirely with that hex color. A minimal valid PNG of any small size (e.g., 1×1 or 108×108 pixels) is sufficient.
|
|
120
|
+
c. Name the PNG `<color_name>_bg.png` (e.g., `md_orange_700_bg.png`) and place it in `base/media/`.
|
|
121
|
+
d. Reference it as `$media:<color_name>_bg` in the layered-image JSON.
|
|
122
|
+
e. **If the color cannot be resolved** (e.g., it comes from a library and we're using source `res/`), log it as an unsatisfied dependency in the report and use a placeholder reference.
|
|
123
|
+
5. Output filename: `<original_name>_layered_image.json` (e.g., `ic_launcher.xml` → `ic_launcher_layered_image.json`)
|
|
124
|
+
6. Store in the target `media/` directory (typically `base/media/`)
|
|
125
|
+
|
|
126
|
+
**Example:**
|
|
127
|
+
```xml
|
|
128
|
+
<!-- mipmap-anydpi-v26/ic_launcher.xml -->
|
|
129
|
+
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
|
130
|
+
<background android:drawable="@color/md_orange_700" />
|
|
131
|
+
<foreground android:drawable="@mipmap/ic_launcher_foreground" />
|
|
132
|
+
<monochrome android:drawable="@drawable/ic_launcher_monochrome" />
|
|
133
|
+
</adaptive-icon>
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Suppose `@color/md_orange_700` resolves to `#F57C00`. Generate `base/media/md_orange_700_bg.png` (a solid `#F57C00` filled PNG). Then convert to `base/media/ic_launcher_layered_image.json`:
|
|
137
|
+
```json
|
|
138
|
+
{
|
|
139
|
+
"layered-image": {
|
|
140
|
+
"background": "$media:md_orange_700_bg",
|
|
141
|
+
"foreground": "$media:ic_launcher_foreground"
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
#### 4.2 Qualifier Directory Mapping
|
|
147
|
+
|
|
148
|
+
Android uses qualifiers as directory suffixes (e.g., `drawable-hdpi`, `values-ar`). HarmonyOS uses a different qualifier directory naming convention. Convert as follows:
|
|
149
|
+
|
|
150
|
+
**Screen density mapping** (Android DPI names differ from HarmonyOS):
|
|
151
|
+
|
|
152
|
+
| Android Qualifier | Android DPI | HarmonyOS Qualifier | HarmonyOS DPI Range |
|
|
153
|
+
|---|---|---|---|
|
|
154
|
+
| `ldpi` | ~120 | `sdpi` | (0, 120] |
|
|
155
|
+
| `mdpi` | ~160 | `mdpi` | (120, 160] |
|
|
156
|
+
| `hdpi` | ~240 | `ldpi` | (160, 240] |
|
|
157
|
+
| `xhdpi` | ~320 | `xldpi` | (240, 320] |
|
|
158
|
+
| `xxhdpi` | ~480 | `xxldpi` | (320, 480] |
|
|
159
|
+
| `xxxhdpi` | ~640 | `xxxldpi` | (480, 640] |
|
|
160
|
+
| `nodpi` | N/A | `base` | No density qualifier; use base |
|
|
161
|
+
| `anydpi` | N/A | `base` | No density qualifier; use base |
|
|
162
|
+
|
|
163
|
+
**Language/region mapping**:
|
|
164
|
+
- `values-ar` → `ar/element/`
|
|
165
|
+
- `values-zh-rCN` or `values-zh` → `zh_CN/element/` or `zh/element/`
|
|
166
|
+
- `values-en-rUS` → `en_US/element/`
|
|
167
|
+
- `drawable-ar` → `ar/media/`
|
|
168
|
+
|
|
169
|
+
The pattern: strip the base type prefix (e.g., `values-`, `drawable-`), convert the qualifier to HarmonyOS format, then place resources under the appropriate resource group directory (`element/`, `media/`, or `profile/`).
|
|
170
|
+
|
|
171
|
+
**Multi-qualifier directories**: Android directories can combine multiple qualifiers with hyphens (e.g., `mipmap-anydpi-v26`, `drawable-night-v21`). Parse ALL qualifiers individually, map each one, strip unsupported ones, and use whatever valid qualifiers remain. Never reject a directory just because one of its qualifiers is unsupported — strip it and keep going. If all qualifiers are stripped, use `base/`.
|
|
172
|
+
|
|
173
|
+
**Qualifiers to strip** (only these are silently removed):
|
|
174
|
+
- API level `v<N>` (e.g., `v26`, `v21`)
|
|
175
|
+
|
|
176
|
+
**Qualifiers without a HarmonyOS equivalent** (skip entirely):
|
|
177
|
+
- Smallest width `sw<N>dp` (e.g., `sw600dp`)
|
|
178
|
+
- Available width `w<N>dp` (e.g., `w480dp`)
|
|
179
|
+
- Available height `h<N>dp`
|
|
180
|
+
- Screen size (`small`, `normal`, `large`, `xlarge`)
|
|
181
|
+
|
|
182
|
+
These qualifiers have no HarmonyOS mapping. When a directory's only remaining qualifiers (after stripping API level etc.) are from this list, **skip all resources in that directory** and mark them as "unmapped" in the conversion report with reason "Unsupported qualifier: no HarmonyOS equivalent". Do NOT convert them to `base/` or preserve the qualifier as-is — skipping ensures correct conversion output.
|
|
183
|
+
|
|
184
|
+
**Common example**: `mipmap-anydpi-v26` → qualifiers: `anydpi` (→ `base`) + `v26` (→ strip) → target: `base/media/`. The files inside (typically `<adaptive-icon>` XML) should be processed normally by reading their XML content to determine the type — adaptive-icon XML gets converted to layered-image JSON.
|
|
185
|
+
|
|
186
|
+
**HarmonyOS qualifier directory naming rules**:
|
|
187
|
+
- Language and region are joined by underscore: `zh_CN`, `en_US`
|
|
188
|
+
- Multiple qualifier types are separated by hyphens: `zh_CN-dark-ldpi`
|
|
189
|
+
- Order: MCC_MNC-language_script_country/region-orientation-device-colormode-density
|
|
190
|
+
|
|
191
|
+
**Orientation mapping**:
|
|
192
|
+
- `land` → `horizontal`
|
|
193
|
+
- `port` → `vertical`
|
|
194
|
+
|
|
195
|
+
**Night mode mapping**:
|
|
196
|
+
- `night` → `dark`
|
|
197
|
+
- `notnight` → `light`
|
|
198
|
+
|
|
199
|
+
**Handling values with non-mappable qualifiers** (e.g., `values-sw600dp`, `values-w480dp`, `values-w600dp`):
|
|
200
|
+
These directories contain value resources qualified by screen-size constraints that HarmonyOS does not support. **Skip all resources in these directories** and mark them as "unmapped" in the conversion report with reason "Unsupported qualifier: `sw600dp` / `w480dp` / etc. — no HarmonyOS equivalent". Do NOT convert them to `base/element/` or preserve the qualifier as-is.
|
|
201
|
+
|
|
202
|
+
#### 4.2.1 Record Resource Mapping Metadata
|
|
203
|
+
|
|
204
|
+
As each Android resource is processed, maintain two parallel data sets for the final mapping document:
|
|
205
|
+
|
|
206
|
+
1. **Android resource inventory records** — one record per Android resource item
|
|
207
|
+
2. **Android ↔ HarmonyOS mapping records** — one record per conversion or non-conversion outcome
|
|
208
|
+
|
|
209
|
+
Use the rules in `references/resource-mapping-rules.md`.
|
|
210
|
+
|
|
211
|
+
**Minimum fields for each Android resource inventory record:**
|
|
212
|
+
- Android resource path
|
|
213
|
+
- Android resource name
|
|
214
|
+
- Function description
|
|
215
|
+
- Screen(s)
|
|
216
|
+
- Source category
|
|
217
|
+
- Type category
|
|
218
|
+
- Status
|
|
219
|
+
- Notes / evidence
|
|
220
|
+
|
|
221
|
+
**Minimum fields for each mapping record:**
|
|
222
|
+
- Android resource path
|
|
223
|
+
- Android screen(s)
|
|
224
|
+
- Android source category
|
|
225
|
+
- Android type category
|
|
226
|
+
- HarmonyOS target path (or `N/A`)
|
|
227
|
+
- Mapping kind
|
|
228
|
+
- Notes
|
|
229
|
+
|
|
230
|
+
**Recording granularity:**
|
|
231
|
+
- File resources (`drawable`, `mipmap`, `xml`, `font`, `raw`) → record at file level
|
|
232
|
+
- `values/*.xml` resources → record at entry level using `file_path#tag/name` notation, e.g. `app/src/main/res/values/strings.xml#string/app_name`
|
|
233
|
+
- One-to-many conversions (for example adaptive icon XML producing layered-image JSON plus generated PNG assets) → record each target as its own mapping row
|
|
234
|
+
- Many-to-one conversions (for example multiple Android value entries ending up in one HarmonyOS JSON file) → still record each Android source entry separately
|
|
235
|
+
- Unmappable resources, system resources, third-party-library-only resources, and runtime remote resources must also be recorded; never silently omit them from the mapping metadata
|
|
236
|
+
#### 4.3 Value Format Conversions
|
|
237
|
+
|
|
238
|
+
When converting `values/*.xml` to HarmonyOS JSON format:
|
|
239
|
+
|
|
240
|
+
**Colors**:
|
|
241
|
+
- Android `#RRGGBB` → HarmonyOS `#ffRRGGBB` (prepend `ff` for full opacity)
|
|
242
|
+
- Android `#AARRGGBB` → HarmonyOS `#AARRGGBB` (already in correct format, HarmonyOS uses same order)
|
|
243
|
+
- Android `#RGB` → expand to `#ffRRGGBB`
|
|
244
|
+
- Android `#ARGB` → expand to `#AARRGGBB`
|
|
245
|
+
|
|
246
|
+
**Dimensions** (for `dimens.xml` → `float.json`):
|
|
247
|
+
- `dp` → `vp` (virtual pixels, similar concept)
|
|
248
|
+
- `sp` → `fp` (font pixels)
|
|
249
|
+
- `px` → keep as `px`
|
|
250
|
+
- Plain numbers → append `vp`
|
|
251
|
+
|
|
252
|
+
**Strings**:
|
|
253
|
+
- XML entities (`&`, `<`, `>`, `"`, `'`) → decoded characters
|
|
254
|
+
- `\n`, `\t` → preserved
|
|
255
|
+
- CDATA sections → extract text content
|
|
256
|
+
- String format placeholders (`%1$s`, `%2$d`) → preserved (HarmonyOS uses same format)
|
|
257
|
+
|
|
258
|
+
**Booleans**:
|
|
259
|
+
- `"true"` / `"false"` → `true` / `false` (as JSON booleans)
|
|
260
|
+
|
|
261
|
+
**Integers**:
|
|
262
|
+
- Integer values from `integers.xml` MUST be stored as JSON number type, NOT as JSON strings
|
|
263
|
+
- `<integer name="max_lines">3</integer>` → `{"name": "max_lines", "value": 3}` (JSON number `3`, NOT string `"3"`)
|
|
264
|
+
- Integer-array item values must also be JSON numbers: `{"value": 100}` not `{"value": "100"}`
|
|
265
|
+
- If the source value contains non-numeric content (e.g., a resource reference), resolve the reference first, then convert the resolved value to a JSON number
|
|
266
|
+
- If a value cannot be parsed as a number after resolution, log a warning and use `0` as a fallback
|
|
267
|
+
|
|
268
|
+
**Plurals**:
|
|
269
|
+
- Android quantities: `zero`, `one`, `two`, `few`, `many`, `other`
|
|
270
|
+
- HarmonyOS quantities: `zero`, `one`, `two`, `few`, `many`, `other` (same set)
|
|
271
|
+
|
|
272
|
+
### Step 5: Analyze and Resolve Resource Dependencies
|
|
273
|
+
|
|
274
|
+
Android resources often reference other resources using `@type/name` syntax (e.g., `@color/primary`, `@drawable/icon`). Dependency analysis runs regardless of whether resources came from a decompiled APK or source `res/` — the difference is that source-based conversion may have more unresolvable references because library resources are absent.
|
|
275
|
+
|
|
276
|
+
Read `references/dependency-analysis-rules.md` for the complete dependency extraction patterns. Also use `references/resource-mapping-rules.md` during this step to infer resource function, screen ownership, source category, and type category for the mapping document.
|
|
277
|
+
|
|
278
|
+
#### 5.1 Build a Resource Value Lookup Table
|
|
279
|
+
|
|
280
|
+
Before resolving references, build a complete lookup table from whichever resource source is being used. This table maps every resource name to its concrete value:
|
|
281
|
+
|
|
282
|
+
- **Value resources** (`colors.xml`, `dimens.xml`, `strings.xml`, etc.): parse all `values*/*.xml` files and build `type → name → value` mappings across all qualifier directories
|
|
283
|
+
- **File resources** (`drawable/`, `mipmap/`): record `type → name → file_path` for each image or XML drawable
|
|
284
|
+
- **Mapping support metadata**: build and maintain side tables for Android screen candidates, resource usage sites, module ownership, and likely library provenance so these can be attached to inventory and mapping rows later
|
|
285
|
+
|
|
286
|
+
When working from source `res/`, this table will be **incomplete** — it won't contain resources defined in library dependencies. That's expected. The dependency analysis in Step 5.3 will identify these gaps.
|
|
287
|
+
|
|
288
|
+
#### 5.2 Resolve References to True Values
|
|
289
|
+
|
|
290
|
+
Scan all converted HarmonyOS resource files and replace resource references with their resolved concrete values:
|
|
291
|
+
|
|
292
|
+
**In element JSON files** (`color.json`, `float.json`, `string.json`, etc.):
|
|
293
|
+
- If a value field contains a HarmonyOS reference like `$color:name`, `$float:name`, `$string:name`, etc., look up the referenced resource in the lookup table
|
|
294
|
+
- Replace the reference with the actual resolved value
|
|
295
|
+
- Follow reference chains (resource A → resource B → concrete value) up to 5 levels deep to handle transitive references
|
|
296
|
+
- If a reference cannot be resolved (e.g., it points to a library resource not in source `res/`, or to a theme attribute `?attr/name`), keep the reference as-is and log it in the report
|
|
297
|
+
|
|
298
|
+
**Android system resource references** (`@android:color/*`, `@android:dimen/*`, `@android:string/*`, `@android:integer/*`):
|
|
299
|
+
|
|
300
|
+
These reference Android framework built-in resources that do NOT exist in HarmonyOS. They MUST be resolved to concrete values — never leave `@android:` references in the output. Use the following built-in lookup table for `@android:color/*`:
|
|
301
|
+
|
|
302
|
+
| Android System Color | Hex Value |
|
|
303
|
+
|---|---|
|
|
304
|
+
| `@android:color/white` | `#ffffffff` |
|
|
305
|
+
| `@android:color/black` | `#ff000000` |
|
|
306
|
+
| `@android:color/transparent` | `#00000000` |
|
|
307
|
+
| `@android:color/background_dark` | `#ff000000` |
|
|
308
|
+
| `@android:color/background_light` | `#ffffffff` |
|
|
309
|
+
| `@android:color/darker_gray` | `#ffaaaaaa` |
|
|
310
|
+
| `@android:color/holo_blue_bright` | `#ff00ddff` |
|
|
311
|
+
| `@android:color/holo_blue_dark` | `#ff0099cc` |
|
|
312
|
+
| `@android:color/holo_blue_light` | `#ff33b5e5` |
|
|
313
|
+
| `@android:color/holo_green_dark` | `#ff669900` |
|
|
314
|
+
| `@android:color/holo_green_light` | `#ff99cc00` |
|
|
315
|
+
| `@android:color/holo_orange_dark` | `#ffff8800` |
|
|
316
|
+
| `@android:color/holo_orange_light` | `#ffffbb33` |
|
|
317
|
+
| `@android:color/holo_purple` | `#ffaa66cc` |
|
|
318
|
+
| `@android:color/holo_red_dark` | `#ffcc0000` |
|
|
319
|
+
| `@android:color/holo_red_light` | `#ffff4444` |
|
|
320
|
+
| `@android:color/primary_text_dark` | `#ffffffff` |
|
|
321
|
+
| `@android:color/primary_text_light` | `#de000000` |
|
|
322
|
+
| `@android:color/secondary_text_dark` | `#b3ffffff` |
|
|
323
|
+
| `@android:color/secondary_text_light` | `#8a000000` |
|
|
324
|
+
| `@android:color/tab_indicator_text` | `#ff808080` |
|
|
325
|
+
| `@android:color/tertiary_text_dark` | `#80ffffff` |
|
|
326
|
+
| `@android:color/tertiary_text_light` | `#54000000` |
|
|
327
|
+
| `@android:color/widget_edittext_dark` | `#ff000000` |
|
|
328
|
+
|
|
329
|
+
For `@android:color/*` values not in this table: if converting from a decompiled APK, look up the color in the decompiled framework resources (`res/values/colors.xml` from the APK). Otherwise, log a warning and use `#ff000000` (black) as a safe fallback.
|
|
330
|
+
|
|
331
|
+
For `@android:dimen/*` system dimensions: use the following common values:
|
|
332
|
+
|
|
333
|
+
| Android System Dimen | Value |
|
|
334
|
+
|---|---|
|
|
335
|
+
| `@android:dimen/app_icon_size` | `48vp` |
|
|
336
|
+
| `@android:dimen/thumbnail_width` | `96vp` |
|
|
337
|
+
| `@android:dimen/thumbnail_height` | `96vp` |
|
|
338
|
+
| `@android:dimen/dialog_min_width_major` | `65%` |
|
|
339
|
+
| `@android:dimen/dialog_min_width_minor` | `95%` |
|
|
340
|
+
| `@android:dimen/notification_large_icon_width` | `64vp` |
|
|
341
|
+
| `@android:dimen/notification_large_icon_height` | `64vp` |
|
|
342
|
+
|
|
343
|
+
For any other `@android:type/*` not covered by the tables above, log a warning in the report and substitute a reasonable default value for the type (colors → `#ff000000`, dimens → `0vp`, integers → `0`, strings → `""`).
|
|
344
|
+
|
|
345
|
+
**Example — system color resolution:**
|
|
346
|
+
```json
|
|
347
|
+
// Before resolution:
|
|
348
|
+
{"name": "bg_default", "value": "@android:color/white"}
|
|
349
|
+
|
|
350
|
+
// After resolution:
|
|
351
|
+
{"name": "bg_default", "value": "#ffffffff"}
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
**Example — color reference resolution:**
|
|
355
|
+
```json
|
|
356
|
+
// Before resolution:
|
|
357
|
+
{"name": "primary_light", "value": "$color:primary"}
|
|
358
|
+
|
|
359
|
+
// After resolution (primary resolves to #ff6200EE):
|
|
360
|
+
{"name": "primary_light", "value": "#ff6200EE"}
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
**Example — dimension reference resolution:**
|
|
364
|
+
```json
|
|
365
|
+
// Before resolution:
|
|
366
|
+
{"name": "margin_double", "value": "$float:margin_base"}
|
|
367
|
+
|
|
368
|
+
// After resolution (margin_base resolves to "16vp"):
|
|
369
|
+
{"name": "margin_double", "value": "16vp"}
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
**In SVG files** (converted XML drawables):
|
|
373
|
+
- If a fill or stroke color was a resource reference, resolve it to the actual hex color during SVG generation
|
|
374
|
+
- If a dimension was a resource reference, resolve it to the actual numeric value
|
|
375
|
+
|
|
376
|
+
**In layered-image JSON files**:
|
|
377
|
+
- `@drawable/xxx` and `@mipmap/xxx` references → keep as `$media:xxx` (these are file references, not value references — the files themselves are converted)
|
|
378
|
+
- `@color/xxx` references → resolve to hex and generate solid-color PNG (as described in section 4.1.1)
|
|
379
|
+
|
|
380
|
+
**Fallback strategy for unresolvable references in element JSON files:**
|
|
381
|
+
|
|
382
|
+
After completing the reference resolution pass, scan all element JSON files for any remaining unresolved `$type:xxx` references. These MUST be replaced with concrete fallback values — leaving unresolved references in the output will cause HarmonyOS compilation errors.
|
|
383
|
+
|
|
384
|
+
- When the resource source is a **decompiled APK** (which contains the complete merged resource set), unresolved references indicate a bug in the resolution logic. Still apply fallbacks, but log prominently as errors.
|
|
385
|
+
- When the resource source is **source `res/`**, unresolved references are expected for library resources. Apply fallbacks and log as warnings.
|
|
386
|
+
|
|
387
|
+
**Fallback values by type:**
|
|
388
|
+
|
|
389
|
+
| Reference Type | Fallback Value | Notes |
|
|
390
|
+
|---|---|---|
|
|
391
|
+
| `$color:xxx` | `#ff000000` (black) | Safe default for any missing color |
|
|
392
|
+
| `$float:xxx` | `0vp` | Zero-dimension fallback |
|
|
393
|
+
| `$string:xxx` | `""` (empty string) | Empty string fallback |
|
|
394
|
+
| `$integer:xxx` | `0` | Zero integer fallback |
|
|
395
|
+
| `$boolean:xxx` | `false` | False boolean fallback |
|
|
396
|
+
|
|
397
|
+
**Resolution for cross-file references:**
|
|
398
|
+
- When building the lookup table (Step 5.1), ensure ALL qualifier directories are scanned, not just `base/`. Color references may chain across qualifier variants (e.g., `base/` defines `primary`, `dark/` overrides it). Use the `base/` variant as the canonical value for resolution.
|
|
399
|
+
- When a reference exists in a non-base qualifier but not in `base/`, include it in the lookup table with its qualifier noted.
|
|
400
|
+
|
|
401
|
+
**Example — fallback applied:**
|
|
402
|
+
```json
|
|
403
|
+
// Before fallback (unresolvable library color):
|
|
404
|
+
{"name": "design_fab_stroke_top_outer_color", "value": "$color:design_fab_stroke_top_outer_color"}
|
|
405
|
+
|
|
406
|
+
// After fallback:
|
|
407
|
+
{"name": "design_fab_stroke_top_outer_color", "value": "#ff000000"}
|
|
408
|
+
// Report logs: "WARNING: Unresolved $color:design_fab_stroke_top_outer_color — replaced with fallback #ff000000. Likely source: com.google.android.material:material"
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
#### 5.3 Verify All Dependencies Are Satisfied
|
|
412
|
+
|
|
413
|
+
After resolution, scan all converted resources for any remaining unresolved references:
|
|
414
|
+
|
|
415
|
+
1. **Converted resource dependencies**: check that every `$media:xxx`, `$color:xxx`, `$float:xxx`, etc. reference in converted files points to an existing resource in the HarmonyOS output
|
|
416
|
+
2. **Layout and menu file dependencies**: scan all `layout*/` and `menu/` files from the resource source for `@type/name` references. Even though layouts and menus won't be migrated as-is (ArkUI uses declarative UI), the resources they reference — strings, colors, drawables, dimensions — must exist in the converted output so the developer has everything needed when rebuilding the UI
|
|
417
|
+
3. Mark each dependency as **satisfied** or **unsatisfied**
|
|
418
|
+
4. **When using source `res/`**: unsatisfied dependencies are expected — they likely come from library resources. Parse `build.gradle` / `build.gradle.kts` to identify declared library dependencies (e.g., AndroidX, Material Components, third-party libraries). In the report, correlate unsatisfied references with likely library sources where possible (e.g., `@color/material_xxx` likely comes from Material Components library)
|
|
419
|
+
5. Use the dependency graph and reference locations to infer screen ownership for resources whenever possible. If a resource is referenced from multiple screens, record all of them or mark it `Common`; if it is app-wide (launcher icon, theme resource, app name), mark it `Global` or `Launcher` as appropriate.
|
|
420
|
+
|
|
421
|
+
### Step 6: Verify Completeness
|
|
422
|
+
|
|
423
|
+
After conversion and dependency resolution, verify the output:
|
|
424
|
+
|
|
425
|
+
1. Build a list of all resource files found in the resource source directory
|
|
426
|
+
2. For each, check if it was converted or marked as unmappable
|
|
427
|
+
3. For converted resources, verify the target file exists in the HarmonyOS project
|
|
428
|
+
4. For `values/*.xml` entries, verify each individual resource entry (string, color, dimen, etc.) appears in the corresponding JSON file
|
|
429
|
+
5. Flag any resources that were missed
|
|
430
|
+
6. Verify all dependencies from converted resources are satisfied (all references resolved to true values)
|
|
431
|
+
7. Verify all dependencies from layout and menu files are satisfied — any missing resources should appear in the Unsatisfied Dependencies section of the report
|
|
432
|
+
8. **Cross-validate with existing HarmonyOS UI code**: If the HarmonyOS output path already contains `.ets` source files (i.e., it's an existing project with UI code already converted), scan ALL `.ets` files for `$r('app.media.xxx')` resource references and cross-check against the converted `media/` resources:
|
|
433
|
+
a. For each `$r('app.media.xxx')` reference found in `.ets` files, verify that a corresponding file `xxx.*` (any extension: .png, .svg, .jpg, etc.) exists in the output `resources/base/media/` directory
|
|
434
|
+
b. For any referenced but missing media resource, **create a placeholder SVG** file: a simple 24x24 SVG with a colored rectangle and the resource name as text, placed in `base/media/`. This ensures the project compiles.
|
|
435
|
+
c. Log all placeholder-created resources prominently in the conversion report under a dedicated "Placeholder Resources Created" section, so the developer knows these need to be replaced with real assets
|
|
436
|
+
d. Also scan for `$r('app.string.xxx')`, `$r('app.color.xxx')`, `$r('app.float.xxx')` references and verify those exist in the corresponding element JSON files
|
|
437
|
+
9. Before finishing verification, ensure every Android resource inventory row and every mapping row has the required metadata fields from `references/resource-mapping-rules.md`. If some fields cannot be proven, populate them with the rule-defined fallback labels (`Unknown`, `Common`, `Global`, `N/A`) rather than leaving them blank.
|
|
438
|
+
|
|
439
|
+
**Placeholder SVG template** (for missing media resources):
|
|
440
|
+
```svg
|
|
441
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
|
442
|
+
<rect width="24" height="24" fill="#CCCCCC"/>
|
|
443
|
+
<text x="12" y="16" font-size="4" text-anchor="middle" fill="#666666">RESOURCE_NAME</text>
|
|
444
|
+
</svg>
|
|
445
|
+
```
|
|
446
|
+
Replace `RESOURCE_NAME` with the actual resource name (truncated if too long).
|
|
447
|
+
|
|
448
|
+
### Step 7: Generate Report
|
|
449
|
+
|
|
450
|
+
Output the standard conversion report with these sections:
|
|
451
|
+
|
|
452
|
+
```
|
|
453
|
+
# Android to HarmonyOS Resource Conversion Report
|
|
454
|
+
|
|
455
|
+
## Build Status
|
|
456
|
+
- Build attempted: Yes/No
|
|
457
|
+
- Build result: Success / Failed / Skipped
|
|
458
|
+
- Build error (if failed): <error summary>
|
|
459
|
+
- APK source: <"freshly built" / "cached previous build" / "none — using source res/">
|
|
460
|
+
- Resource source: <"decompiled APK (complete)" / "source res/ (may be missing library resources)">
|
|
461
|
+
- Resource source path: <path>
|
|
462
|
+
|
|
463
|
+
⚠️ **Note** (if source res/ was used): Resources were converted from the project's source `res/` directory because no APK was available. Library-provided resources (from Maven dependencies, AARs) are NOT included. References to library resources will appear as unsatisfied dependencies below. To get a complete conversion with all library resources, fix the build and re-run.
|
|
464
|
+
|
|
465
|
+
## Library Dependencies (from build.gradle)
|
|
466
|
+
Libraries declared in the project's build.gradle that may provide resources:
|
|
467
|
+
| Library | Group:Artifact | Likely Resource Prefixes |
|
|
468
|
+
|---|---|---|
|
|
469
|
+
| Material Components | com.google.android.material:material | @color/material_*, @dimen/material_*, @style/Widget.Material* |
|
|
470
|
+
| AndroidX AppCompat | androidx.appcompat:appcompat | @color/abc_*, @drawable/abc_* |
|
|
471
|
+
| ... | ... | ... |
|
|
472
|
+
|
|
473
|
+
(This section helps identify which unsatisfied dependencies come from which libraries.)
|
|
474
|
+
|
|
475
|
+
## Summary
|
|
476
|
+
- Resource source: <decompiled APK / source res/>
|
|
477
|
+
- Total Android resource files found: <count>
|
|
478
|
+
- Successfully converted: <count>
|
|
479
|
+
- Unmappable (no HarmonyOS equivalent): <count>
|
|
480
|
+
- Failed: <count>
|
|
481
|
+
- Resource references resolved: <count>
|
|
482
|
+
- Unresolved references (library resources missing): <count>
|
|
483
|
+
- Unresolved references (other reasons): <count>
|
|
484
|
+
|
|
485
|
+
## Conversion Details
|
|
486
|
+
|
|
487
|
+
### Successfully Converted Resources
|
|
488
|
+
| Android Source | HarmonyOS Target | Type | Notes |
|
|
489
|
+
|---|---|---|---|
|
|
490
|
+
| res/values/strings.xml | resources/base/element/string.json | values→element | 25 strings converted |
|
|
491
|
+
| res/drawable/icon.png | resources/base/media/icon.png | media copy | Direct copy |
|
|
492
|
+
| res/drawable-hdpi/bg.png | resources/ldpi/media/bg.png | qualified media | hdpi→ldpi |
|
|
493
|
+
| ... | ... | ... | ... |
|
|
494
|
+
|
|
495
|
+
### Qualifier Mappings Applied
|
|
496
|
+
| Android Qualifier Dir | HarmonyOS Qualifier Dir | Files Converted |
|
|
497
|
+
|---|---|---|
|
|
498
|
+
| drawable-hdpi | ldpi/media | 5 |
|
|
499
|
+
| values-ar | ar/element | 3 |
|
|
500
|
+
| ... | ... | ... |
|
|
501
|
+
|
|
502
|
+
### Resource Reference Resolution
|
|
503
|
+
References in converted resources that were resolved to their actual values.
|
|
504
|
+
|
|
505
|
+
| Resource File | Reference | Resolved Value | Resolution Chain |
|
|
506
|
+
|---|---|---|---|
|
|
507
|
+
| base/element/color.json → primary_light | $color:primary | #ff6200EE | @color/primary → @color/md_blue_500 → #6200EE |
|
|
508
|
+
| base/element/float.json → margin_double | $float:margin_base | 16vp | @dimen/margin_base → 16dp → 16vp |
|
|
509
|
+
| ... | ... | ... | ... |
|
|
510
|
+
|
|
511
|
+
### Layout & Menu Resource Dependencies
|
|
512
|
+
Dependencies from layout/menu files (not converted to HarmonyOS, but needed when rebuilding the UI in ArkUI).
|
|
513
|
+
|
|
514
|
+
| Source File (not converted) | Dependencies | All Satisfied? |
|
|
515
|
+
|---|---|---|
|
|
516
|
+
| layout/activity_main.xml | @string/app_name ✅, @drawable/bg_header ✅, @color/primary ✅ | Yes |
|
|
517
|
+
| layout/fragment_settings.xml | @string/settings_title ✅, @drawable/ic_back ❌ (library) | No |
|
|
518
|
+
| menu/main_menu.xml | @string/menu_share ✅, @drawable/ic_share ❌ (library) | No |
|
|
519
|
+
| ... | ... | ... |
|
|
520
|
+
|
|
521
|
+
### Unmappable Resources
|
|
522
|
+
| Android Source | Reason |
|
|
523
|
+
|---|---|
|
|
524
|
+
| res/layout/activity_main.xml | Layout XML has no HarmonyOS equivalent (use ArkUI) |
|
|
525
|
+
| res/drawable/ripple_effect.xml | XML drawable not supported |
|
|
526
|
+
| ... | ... |
|
|
527
|
+
|
|
528
|
+
### Unmapped Resources (Unsupported Qualifiers)
|
|
529
|
+
| Android Source Dir | Qualifier | Reason |
|
|
530
|
+
|---|---|---|
|
|
531
|
+
| res/values-sw600dp/ | sw600dp | No HarmonyOS equivalent — skipped |
|
|
532
|
+
| res/values-w480dp/ | w480dp | No HarmonyOS equivalent — skipped |
|
|
533
|
+
| ... | ... | ... |
|
|
534
|
+
|
|
535
|
+
### Unresolved References (Fallback Applied)
|
|
536
|
+
| Resource File | Original Reference | Fallback Value | Reason | Likely Source |
|
|
537
|
+
|---|---|---|---|---|
|
|
538
|
+
| drawable/bg_themed.xml | ?attr/colorSurface | N/A (kept as-is) | Theme attribute — cannot resolve statically | N/A |
|
|
539
|
+
| element/color.json → material_blue | @color/design_default_color_primary | #ff000000 | Library resource not in source res/ | com.google.android.material:material |
|
|
540
|
+
| ... | ... | ... | ... | ... |
|
|
541
|
+
|
|
542
|
+
### System Resources Resolved
|
|
543
|
+
| Resource File | System Reference | Resolved Value |
|
|
544
|
+
|---|---|---|
|
|
545
|
+
| element/color.json → bg_white | @android:color/white | #ffffffff |
|
|
546
|
+
| element/color.json → divider | @android:color/darker_gray | #ffaaaaaa |
|
|
547
|
+
| ... | ... | ... |
|
|
548
|
+
|
|
549
|
+
### Nine-Patch Files Renamed
|
|
550
|
+
| Original Name | Renamed To | Source Directory |
|
|
551
|
+
|---|---|---|
|
|
552
|
+
| abc_btn_default.9.png | abc_btn_default_9.png | drawable-mdpi |
|
|
553
|
+
| ... | ... | ... |
|
|
554
|
+
|
|
555
|
+
### Placeholder Resources Created
|
|
556
|
+
Media resources referenced in `.ets` UI code but not found in converted resources. Placeholder SVGs were created to allow compilation — these MUST be replaced with real assets.
|
|
557
|
+
| Resource Name | Referenced In | Placeholder File |
|
|
558
|
+
|---|---|---|
|
|
559
|
+
| ic_tab_home | pages/MainPage.ets | base/media/ic_tab_home.svg |
|
|
560
|
+
| ic_tab_profile | pages/MainPage.ets | base/media/ic_tab_profile.svg |
|
|
561
|
+
| ... | ... | ... |
|
|
562
|
+
|
|
563
|
+
### Failed Conversions
|
|
564
|
+
| Android Source | Error |
|
|
565
|
+
|---|---|
|
|
566
|
+
| ... | ... |
|
|
567
|
+
|
|
568
|
+
### Verification Results
|
|
569
|
+
- All resources accounted for: Yes/No
|
|
570
|
+
- Missing resources: <list if any>
|
|
571
|
+
- All references resolved: Yes/No
|
|
572
|
+
- Unresolved references: <count> (<count> due to missing library resources, <count> other)
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
### Step 8: Generate Resource Mapping Document
|
|
576
|
+
|
|
577
|
+
After the standard conversion report is written, generate a second markdown document at `resource_mapping_path`.
|
|
578
|
+
|
|
579
|
+
Read `references/resource-mapping-rules.md` and write the mapping markdown with these required sections:
|
|
580
|
+
|
|
581
|
+
1. **Metadata**
|
|
582
|
+
- Android project path
|
|
583
|
+
- HarmonyOS project output path
|
|
584
|
+
- Resource source
|
|
585
|
+
- Resource source path
|
|
586
|
+
- Build result
|
|
587
|
+
- Generation timestamp
|
|
588
|
+
|
|
589
|
+
2. **Android Resource Inventory**
|
|
590
|
+
- One row per Android resource item
|
|
591
|
+
- Required columns: Android Resource Path, Resource Name, Function, Screen(s), Source Category, Type Category, Status, Notes
|
|
592
|
+
|
|
593
|
+
3. **Android → HarmonyOS Mapping Details**
|
|
594
|
+
- One row per mapping record
|
|
595
|
+
- Required columns: Android Resource Path, Android Screen(s), Android Source Category, Android Type Category, HarmonyOS Target, Mapping Kind, Notes
|
|
596
|
+
|
|
597
|
+
4. **Unmapped / Unmappable / System / Remote Summary**
|
|
598
|
+
- Explicitly list resources with no direct HarmonyOS target, Android framework resources, library-only resources inferred from the APK or dependency graph, and runtime remote resources
|
|
599
|
+
|
|
600
|
+
5. **Quick Findings**
|
|
601
|
+
- Summarize important review findings such as launcher icons from `mipmap`, probable third-party library assets (`abc_*`, `mtrl_*`, `design_*`), and resources present only in the decompiled APK but not in source `res/`
|
|
602
|
+
|
|
603
|
+
**Hard requirements for the mapping markdown:**
|
|
604
|
+
- Never omit an Android resource silently
|
|
605
|
+
- For `values/*.xml`, inventory and mapping rows must be at entry granularity using `file_path#tag/name`
|
|
606
|
+
- Every mapping row must include the Android-side Screen(s), Source Category, and Type Category columns
|
|
607
|
+
- If one Android resource maps to multiple HarmonyOS outputs, emit multiple mapping rows
|
|
608
|
+
- If no HarmonyOS target exists, write `N/A` in the HarmonyOS Target column and explain why in Notes
|
|
609
|
+
|
|
610
|
+
|
|
611
|
+
## Important Notes
|
|
612
|
+
|
|
613
|
+
- Always read `references/conversion-rules.md` for the complete, detailed conversion rules before starting conversions. The tables above are summaries.
|
|
614
|
+
- Always read `references/resource-mapping-rules.md` before producing `resource_mapping_path`. It defines the inventory schema, mapping schema, screen attribution rules, source categorization rules, type categorization rules, and markdown output format.
|
|
615
|
+
- **Build is best-effort**: The APK build + decompilation is attempted first because the decompiled APK is the most complete resource source (it includes library dependencies). But if the build fails, conversion proceeds from source `res/` — a partial conversion with clear reporting is far more useful than no conversion at all.
|
|
616
|
+
- **XML drawable conversion is critical**: Android XML drawables (`<vector>`, `<shape>`, `<layer-list>`, `<selector>`) must be converted to SVG format, not skipped. HarmonyOS supports SVG in `media/`. Read `references/xml-drawable-to-svg-rules.md` for the detailed conversion rules for each drawable type.
|
|
617
|
+
- **Dependency analysis always runs**: Read `references/dependency-analysis-rules.md` for the complete dependency extraction patterns and reference formats. Even when converting from source `res/` with missing library resources, dependency analysis is essential — it tells the developer exactly which references are broken and why, so they can address them manually or fix the build.
|
|
618
|
+
- **APK decompilation**: The skill bundles `apktool_3.0.1.jar` in the `tools/` directory. Java must be available in the system PATH.
|
|
619
|
+
- When parsing Android XML resource files, handle XML namespaces, comments, and attributes correctly.
|
|
620
|
+
- For `values/` XML files, each `<resources>` element can contain multiple resource entries — extract ALL of them.
|
|
621
|
+
- When multiple Android value files contribute to the same HarmonyOS JSON file (e.g., both `strings.xml` and custom `app_strings.xml` both contain `<string>` entries), merge them into a single JSON file.
|
|
622
|
+
- Preserve resource names exactly as they appear in Android (they serve as identifiers).
|
|
623
|
+
- If an element JSON file (like `string.json`) already exists from the template, merge new entries into it rather than overwriting — but template defaults can be replaced if they conflict.
|