deveco_hmigbot 0.21.5

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.
Files changed (101) hide show
  1. package/LICENSE +26 -0
  2. package/README.md +50 -0
  3. package/agents/hmigbot-worker.md +61 -0
  4. package/agents/hmigbot.md +22 -0
  5. package/agents/workflow-subagent.md +55 -0
  6. package/commands/hmigbot.md +17 -0
  7. package/dist/index.js +1 -0
  8. package/manifest.json +19 -0
  9. package/package.json +29 -0
  10. package/skills/migrate-core/FILES.md +26 -0
  11. package/skills/migrate-core/SKILL.md +484 -0
  12. package/skills/migrate-core/references/README.md +64 -0
  13. package/skills/migrate-core/references/flow/arkts-vector-gate.md +55 -0
  14. package/skills/migrate-core/references/flow/build-error-patterns.md +52 -0
  15. package/skills/migrate-core/references/flow/conventions-template.md +244 -0
  16. package/skills/migrate-core/references/flow/navigation-migration.md +42 -0
  17. package/skills/migrate-core/references/flow/platform-api-guards.md +59 -0
  18. package/skills/migrate-core/references/flow/platform-model-gaps.md +43 -0
  19. package/skills/migrate-core/references/flow/resource-conversion.md +46 -0
  20. package/skills/migrate-core/references/flow/ui-layout-semantics.md +124 -0
  21. package/skills/migrate-core/references/flow/unit-breakdown.md +42 -0
  22. package/skills/migrate-core/references/host-capabilities.md +24 -0
  23. package/skills/migrate-core/references/topics/app-identity.md +214 -0
  24. package/skills/migrate-core/references/topics/env-doctor.md +245 -0
  25. package/skills/migrate-core/references/topics/i18n/README.md +458 -0
  26. package/skills/migrate-core/references/topics/i18n/references/code-examples.md +304 -0
  27. package/skills/migrate-core/references/topics/i18n/references/common-pitfalls.md +354 -0
  28. package/skills/migrate-core/references/topics/i18n/references/dynamic-language-switch.md +464 -0
  29. package/skills/migrate-core/references/topics/i18n/references/language-codes.md +104 -0
  30. package/skills/migrate-core/references/topics/icon-sizing.md +98 -0
  31. package/skills/migrate-core/references/topics/library-migration/README.md +234 -0
  32. package/skills/migrate-core/references/topics/library-migration/closed-source-sdk.md +128 -0
  33. package/skills/migrate-core/references/topics/library-migration/download-api-decision.md +84 -0
  34. package/skills/migrate-core/references/topics/library-migration/library-mapping-table.md +100 -0
  35. package/skills/migrate-core/references/topics/library-migration/napi-compile-guide.md +84 -0
  36. package/skills/migrate-core/references/topics/library-migration/ohpm-search-guide.md +73 -0
  37. package/skills/migrate-core/references/topics/library-migration/stdlib-mapping-table.md +34 -0
  38. package/skills/migrate-core/references/topics/resources/aar-decompile.md +25 -0
  39. package/skills/migrate-core/references/topics/resources/conversion-rules.md +625 -0
  40. package/skills/migrate-core/references/topics/resources/dependency-analysis-rules.md +328 -0
  41. package/skills/migrate-core/references/topics/resources/material-design-icons.md +173 -0
  42. package/skills/migrate-core/references/topics/resources/svg-fix-patterns.md +175 -0
  43. package/skills/migrate-core/references/topics/resources/xml-drawable-to-svg-rules.md +513 -0
  44. package/skills/migrate-core/references/topics/system-capabilities/README.md +331 -0
  45. package/skills/migrate-core/references/topics/system-capabilities/avplayer-guide.md +161 -0
  46. package/skills/migrate-core/references/topics/system-capabilities/background-tasks.md +403 -0
  47. package/skills/migrate-core/references/topics/system-capabilities/browser-intent.md +121 -0
  48. package/skills/migrate-core/references/topics/system-capabilities/camera-picker.md +118 -0
  49. package/skills/migrate-core/references/topics/system-capabilities/document-picker.md +246 -0
  50. package/skills/migrate-core/references/topics/system-capabilities/file-utils.md +131 -0
  51. package/skills/migrate-core/references/topics/system-capabilities/permission-helper.md +112 -0
  52. package/skills/migrate-core/references/topics/system-capabilities/photo-access-helper.md +208 -0
  53. package/skills/migrate-core/references/topics/system-capabilities/print-management.md +213 -0
  54. package/skills/migrate-core/references/topics/system-capabilities/share-panel.md +177 -0
  55. package/skills/migrate-core/references/topics/system-capabilities/system-settings.md +322 -0
  56. package/skills/migrate-core/references/topics/system-capabilities/telephony-dial.md +49 -0
  57. package/skills/migrate-core/references/topics/system-capabilities/video-playback.md +42 -0
  58. package/skills/migrate-core/references/topics/system-capabilities/webview-patterns.md +38 -0
  59. package/skills/migrate-core/references/topics/ui-alignment/README.md +344 -0
  60. package/skills/migrate-core/references/topics/ui-alignment/references/dark-mode.md +47 -0
  61. package/skills/migrate-core/references/topics/ui-alignment/references/layout-mapping.md +301 -0
  62. package/skills/migrate-core/references/topics/ui-alignment/references/visual-patterns.md +411 -0
  63. package/skills/migrate-core/scripts/closure/check-anchors.mjs +186 -0
  64. package/skills/migrate-core/scripts/closure/check-api-guards.mjs +175 -0
  65. package/skills/migrate-core/scripts/closure/check-consumers.mjs +301 -0
  66. package/skills/migrate-core/scripts/closure/check-permissions.mjs +165 -0
  67. package/skills/migrate-core/scripts/closure/check-resources.mjs +130 -0
  68. package/skills/migrate-core/scripts/closure/check-routes.mjs +527 -0
  69. package/skills/migrate-core/scripts/closure/check-safearea.mjs +122 -0
  70. package/skills/migrate-core/scripts/closure/check-stubs.mjs +69 -0
  71. package/skills/migrate-core/scripts/closure/closure-suite.mjs +256 -0
  72. package/skills/migrate-core/scripts/closure/idioms.json +105 -0
  73. package/skills/migrate-core/scripts/convert/convert-resources.mjs +437 -0
  74. package/skills/migrate-core/scripts/feasibility/feasibility.mjs +235 -0
  75. package/skills/migrate-core/scripts/feasibility/tables/cross-platform.json +11 -0
  76. package/skills/migrate-core/scripts/feasibility/tables/deprecated-api.json +10 -0
  77. package/skills/migrate-core/scripts/feasibility/tables/imported-arkts-core.json +425 -0
  78. package/skills/migrate-core/scripts/feasibility/tables/lib-equivalence.json +206 -0
  79. package/skills/migrate-core/scripts/feasibility/tables/system-capabilities.json +22 -0
  80. package/skills/migrate-core/scripts/front.mjs +107 -0
  81. package/skills/migrate-core/scripts/interface/ark-extract.mjs +172 -0
  82. package/skills/migrate-core/scripts/interface/interface.mjs +152 -0
  83. package/skills/migrate-core/scripts/ledger/ledger.mjs +383 -0
  84. package/skills/migrate-core/scripts/ledger/parse-cards.mjs +98 -0
  85. package/skills/migrate-core/scripts/lib/literals.mjs +37 -0
  86. package/skills/migrate-core/scripts/lib/scan.mjs +315 -0
  87. package/skills/migrate-core/scripts/smoke/align-sdk.mjs +118 -0
  88. package/skills/migrate-core/scripts/smoke/ensure-sign.mjs +53 -0
  89. package/skills/migrate-core/scripts/smoke/smoke.mjs +238 -0
  90. package/skills/migrate-core/scripts/smoke/verdict.mjs +31 -0
  91. package/skills/migrate-core/scripts/smoke/walk.mjs +480 -0
  92. package/skills/migrate-core/scripts/transpile/mapping.json +76 -0
  93. package/skills/migrate-core/scripts/transpile/transpile-layout.mjs +404 -0
  94. package/skills/migrate-core/scripts/vectors/run-arkts-vectors.mjs +107 -0
  95. package/skills/migrate-core/scripts/vectors/setup-arkts-test.mjs +90 -0
  96. package/skills/migrate-core/scripts/wire/extractors.mjs +258 -0
  97. package/skills/migrate-core/scripts/wire/wire-routes.mjs +507 -0
  98. package/skills/migrate-core/templates/acceptance.js +365 -0
  99. package/skills/migrate-core/templates/explore.js +86 -0
  100. package/skills/migrate-core/templates/implement.js +211 -0
  101. package/skills/migrate-core/templates/mig_slices.js +491 -0
@@ -0,0 +1,328 @@
1
+ # Android Resource Dependency Analysis Rules
2
+
3
+ This document defines how to extract, track, and resolve inter-resource dependencies during Android-to-HarmonyOS resource conversion. Dependency analysis runs regardless of resource source — whether from a decompiled APK (complete resource set) or from the project's source `res/` directory (potentially missing library resources). When working from source `res/`, more references will be unresolvable, but the analysis is still essential to identify exactly what's missing and why.
4
+
5
+ ## Table of Contents
6
+ 1. [Resource Reference Patterns](#resource-reference-patterns)
7
+ 2. [Building the Resource Value Lookup Table](#building-the-resource-value-lookup-table)
8
+ 3. [Resolving References to True Values](#resolving-references-to-true-values)
9
+ 4. [Where to Scan for Dependencies](#where-to-scan-for-dependencies)
10
+ 5. [Dependency Verification](#dependency-verification)
11
+ 6. [Handling Missing Library Resources](#handling-missing-library-resources)
12
+
13
+ ---
14
+
15
+ ## Resource Reference Patterns
16
+
17
+ Android resources reference each other using `@type/name` syntax. Extract these references from XML attribute values and text content.
18
+
19
+ ### Reference Regex Pattern
20
+
21
+ Use the following pattern to extract resource references from any XML content:
22
+
23
+ ```
24
+ @(color|drawable|mipmap|string|dimen|integer|bool|array|style|attr|id|layout|menu|anim|animator|raw|font|xml|plurals)/([a-zA-Z_][a-zA-Z0-9_]*)
25
+ ```
26
+
27
+ This captures:
28
+ - Group 1: resource type (`color`, `drawable`, etc.)
29
+ - Group 2: resource name
30
+
31
+ ### System Resource References
32
+
33
+ References prefixed with `@android:` (e.g., `@android:color/black`, `@android:drawable/ic_menu_close`) are Android framework resources provided by the OS. These do NOT need to be tracked as dependencies — they have no equivalent that needs to be migrated. Log them as "system resource reference" but do not flag them as unsatisfied.
34
+
35
+ ### Theme Attribute References
36
+
37
+ References using `?attr/name` or `?android:attr/name` are theme attribute references resolved at runtime. These **cannot** be statically resolved — they depend on which theme is applied at runtime. Log them as "unresolvable theme attribute" and keep the reference as-is in the converted output.
38
+
39
+ ### Reference Locations in XML
40
+
41
+ Resource references can appear in several places within Android XML files:
42
+
43
+ **1. XML attribute values:**
44
+ ```xml
45
+ <background android:drawable="@color/md_amber_700" />
46
+ <TextView android:text="@string/hello" android:textColor="@color/primary" />
47
+ <ImageView android:src="@drawable/icon" />
48
+ ```
49
+
50
+ **2. Style/theme item values:**
51
+ ```xml
52
+ <style name="AppTheme">
53
+ <item name="colorPrimary">@color/primary</item>
54
+ <item name="android:windowBackground">@drawable/bg_window</item>
55
+ </style>
56
+ ```
57
+
58
+ **3. Color state list references:**
59
+ ```xml
60
+ <selector>
61
+ <item android:color="@color/pressed_color" android:state_pressed="true" />
62
+ <item android:color="@color/default_color" />
63
+ </selector>
64
+ ```
65
+
66
+ **4. Drawable XML references:**
67
+ ```xml
68
+ <layer-list>
69
+ <item android:drawable="@drawable/bg_layer" />
70
+ </layer-list>
71
+
72
+ <adaptive-icon>
73
+ <background android:drawable="@color/ic_bg" />
74
+ <foreground android:drawable="@mipmap/ic_fg" />
75
+ </adaptive-icon>
76
+ ```
77
+
78
+ **5. Values XML cross-references (these are the primary targets for resolution):**
79
+ ```xml
80
+ <!-- colors.xml -->
81
+ <color name="primary_light">@color/primary</color>
82
+
83
+ <!-- dimens.xml -->
84
+ <color name="margin_double">@dimen/margin_base</color>
85
+ ```
86
+
87
+ ---
88
+
89
+ ## Building the Resource Value Lookup Table
90
+
91
+ Before resolving references, build a complete lookup table from the resource source directory (either decompiled `res/` or source `res/`). When using the decompiled APK, this table will be comprehensive. When using source `res/`, it will only contain app-defined resources — library resources will be absent, and references to them will be flagged during verification.
92
+
93
+ ### Value Resources
94
+
95
+ Parse all `values*/*.xml` files and build mappings:
96
+
97
+ ```
98
+ colors:
99
+ "primary" → "#FF6200EE"
100
+ "primary_light" → "@color/primary" # reference chain — will be resolved
101
+ "md_blue_500" → "#2196F3"
102
+
103
+ dimens:
104
+ "margin_base" → "16dp"
105
+ "margin_double" → "@dimen/margin_base" # reference chain
106
+
107
+ strings:
108
+ "app_name" → "My App"
109
+ "greeting" → "Hello, %1$s!"
110
+
111
+ integers:
112
+ "max_items" → "10"
113
+
114
+ bools:
115
+ "is_tablet" → "false"
116
+ ```
117
+
118
+ Include ALL qualifier variants (e.g., `values/colors.xml`, `values-night/colors.xml`, `values-ar/colors.xml`). Each qualifier variant gets its own entry in the lookup table.
119
+
120
+ ### File Resources
121
+
122
+ Record all drawable and mipmap files:
123
+
124
+ ```
125
+ drawables:
126
+ "icon" → "drawable/icon.png"
127
+ "bg_card" → "drawable/bg_card.xml" (shape)
128
+ "ic_arrow" → "drawable/ic_arrow.xml" (vector)
129
+
130
+ mipmaps:
131
+ "ic_launcher" → "mipmap-anydpi-v26/ic_launcher.xml" (adaptive-icon)
132
+ "ic_launcher_foreground" → "mipmap-xxxhdpi/ic_launcher_foreground.png"
133
+ ```
134
+
135
+ ---
136
+
137
+ ## Resolving References to True Values
138
+
139
+ The key step: walk through all resource values and replace references with actual concrete values.
140
+
141
+ ### Resolution Algorithm
142
+
143
+ ```
144
+ function resolve(type, name, qualifier, depth=0):
145
+ if depth > 5: return UNRESOLVABLE # prevent infinite loops
146
+ value = lookup_table[qualifier][type][name]
147
+ if value is a concrete value (hex color, number, string literal):
148
+ return value
149
+ if value matches @type/other_name:
150
+ return resolve(type, other_name, qualifier, depth+1)
151
+ if value matches ?attr/name:
152
+ return UNRESOLVABLE # theme attribute, cannot resolve statically
153
+ return value
154
+ ```
155
+
156
+ ### What Gets Resolved
157
+
158
+ **Value-to-value references** (primary targets):
159
+ - `@color/name` → resolved hex color (e.g., `@color/primary` → `#FF6200EE`)
160
+ - `@dimen/name` → resolved dimension value (e.g., `@dimen/margin_base` → `16dp`)
161
+ - `@string/name` → resolved string value
162
+ - `@integer/name` → resolved integer value
163
+ - `@bool/name` → resolved boolean value
164
+
165
+ **File references** (kept as HarmonyOS references, not resolved to values):
166
+ - `@drawable/name` → `$media:name` (the file itself is converted separately)
167
+ - `@mipmap/name` → `$media:name`
168
+
169
+ **Unresolvable references** (logged but kept as-is):
170
+ - `?attr/name` — theme attributes depend on runtime theme
171
+ - `@android:type/name` — system resources, provided by the platform
172
+ - `@style/name` — styles have no HarmonyOS equivalent
173
+
174
+ ### Resolution During Conversion
175
+
176
+ Resolution happens at conversion time, not as a separate pass. When converting a value from Android XML to HarmonyOS JSON:
177
+
178
+ 1. Parse the XML value
179
+ 2. If it's a concrete value (hex color, number, string), convert directly using format rules
180
+ 3. If it's a resource reference (`@type/name`):
181
+ a. Look up in the lookup table
182
+ b. Follow the chain to the concrete value
183
+ c. Convert the concrete value using format rules
184
+ d. Use the resolved concrete value in the HarmonyOS JSON output
185
+ 4. If the reference can't be resolved, use HarmonyOS reference syntax (`$color:name`, `$float:name`, etc.) and log it
186
+
187
+ ### Example: Full Resolution Chain
188
+
189
+ Android `values/colors.xml`:
190
+ ```xml
191
+ <color name="app_background">@color/surface_color</color>
192
+ <color name="surface_color">@color/md_grey_50</color>
193
+ <color name="md_grey_50">#FAFAFA</color>
194
+ ```
195
+
196
+ Resolution:
197
+ - `app_background` → `@color/surface_color` → `@color/md_grey_50` → `#FAFAFA`
198
+
199
+ HarmonyOS `color.json` output:
200
+ ```json
201
+ {
202
+ "color": [
203
+ {"name": "app_background", "value": "#ffFAFAFA"},
204
+ {"name": "surface_color", "value": "#ffFAFAFA"},
205
+ {"name": "md_grey_50", "value": "#ffFAFAFA"}
206
+ ]
207
+ }
208
+ ```
209
+
210
+ All three resolve to the same concrete value. The `#ffFAFAFA` format is after applying the `#RRGGBB` → `#ffRRGGBB` color format conversion.
211
+
212
+ ---
213
+
214
+ ## Where to Scan for Dependencies
215
+
216
+ Scan ALL resource files from the resource source directory for dependencies, organized by priority:
217
+
218
+ ### High Priority (converted resources — broken dependencies cause direct errors)
219
+
220
+ | File Type | Typical Location | Why It Matters |
221
+ |---|---|---|
222
+ | Adaptive icon XML | `mipmap-anydpi-v26/*.xml` | References colors, drawables, mipmaps for icon layers |
223
+ | Vector drawables | `drawable/*.xml` (root: `<vector>`) | May reference colors via theme attrs |
224
+ | Shape drawables | `drawable/*.xml` (root: `<shape>`) | May reference colors, dimens |
225
+ | Layer-list drawables | `drawable/*.xml` (root: `<layer-list>`) | References other drawables |
226
+ | Selector drawables | `drawable/*.xml` (root: `<selector>`) | References other drawables for states |
227
+ | Color state lists | `color/*.xml` | References other colors |
228
+ | Values XML | `values*/*.xml` | Cross-references between value types |
229
+
230
+ ### Required — Layout and Menu (not converted, but dependencies must be verified)
231
+
232
+ Layout and menu files are **not** converted to HarmonyOS (they use ArkUI instead), but the resources they reference — strings, colors, drawables, dimensions — **must** be present in the converted output so the developer has everything needed when rebuilding the UI.
233
+
234
+ | File Type | Typical Location | Why It Matters |
235
+ |---|---|---|
236
+ | Layout XML | `layout*/*.xml` | References strings, colors, drawables, dimens used by every UI component |
237
+ | Menu XML | `menu/*.xml` | References strings and drawables for action bar / navigation items |
238
+
239
+ ### Skip (no meaningful dependencies)
240
+
241
+ - Raw files (`raw/`)
242
+ - Font files (`font/`) — unless font XML family definitions reference other fonts
243
+ - Image files (PNG, JPG, WEBP, etc.) — binary files, no references
244
+
245
+ ---
246
+
247
+ ## Dependency Verification
248
+
249
+ After conversion with reference resolution, verify that the output is self-consistent:
250
+
251
+ ### Check by Resource Type
252
+
253
+ | Dependency Type | Where to Check in HarmonyOS Output |
254
+ |---|---|
255
+ | `@color/name` | Should be resolved to hex in `*/element/color.json`. If not resolved, check `name` exists. |
256
+ | `@drawable/name` | Look for `name.*` (any extension: .png, .svg, .jpg, etc.) in `*/media/` |
257
+ | `@mipmap/name` | Same as drawable — mipmaps go to `media/` in HarmonyOS |
258
+ | `@string/name` | Should be resolved to literal in `*/element/string.json`. If not resolved, check `name` exists. |
259
+ | `@dimen/name` | Should be resolved to value in `*/element/float.json`. If not resolved, check `name` exists. |
260
+ | `@integer/name` | Look for `name` in `*/element/integer.json` |
261
+ | `@bool/name` | Look for `name` in `*/element/boolean.json` |
262
+ | `@array/name` | Look for `name` in `*/element/strarray.json` or `*/element/intarray.json` |
263
+ | `@plurals/name` | Look for `name` in `*/element/plural.json` |
264
+ | `@style/name` | Mark as "unmappable type" (styles have no HarmonyOS equivalent) |
265
+ | `@attr/name` | Mark as "unmappable type" |
266
+ | `@layout/name` | Mark as "not applicable" (layouts aren't converted) |
267
+ | `@id/name` | Mark as "not applicable" (IDs are code-level concerns) |
268
+
269
+ ### Qualifier Coverage Check
270
+
271
+ When a dependency is satisfied, also verify qualifier coverage. If the dependent resource exists in multiple qualifier directories (e.g., `base`, `dark`, `ldpi`), the dependency should ideally exist in matching qualifier directories. Flag cases where a dependency exists in `base` but the dependent resource also has `dark` or density-qualified variants — the dependency may need those variants too.
272
+
273
+ ---
274
+
275
+ ## Handling Missing Library Resources
276
+
277
+ When converting from source `res/` (because the APK build failed or no APK was available), library-provided resources will be absent from the lookup table. This section describes how to handle these gaps gracefully.
278
+
279
+ ### Identifying Library Resources
280
+
281
+ Many common Android libraries define resources with recognizable naming patterns. Use these heuristics to correlate unsatisfied dependencies with likely library sources:
282
+
283
+ | Library | Common Resource Prefixes |
284
+ |---|---|
285
+ | Material Components (`com.google.android.material`) | `material_*`, `design_*`, `mtrl_*`, `Widget.Material*`, `Theme.Material*` |
286
+ | AndroidX AppCompat (`androidx.appcompat`) | `abc_*`, `Widget.AppCompat.*` |
287
+ | AndroidX Core (`androidx.core`) | `notification_*`, `compat_*` |
288
+ | AndroidX ConstraintLayout | `constraint_*` |
289
+ | Google Play Services | `common_google_*` |
290
+
291
+ ### Extracting Library Dependencies from build.gradle
292
+
293
+ Parse `build.gradle` or `build.gradle.kts` to identify declared library dependencies:
294
+
295
+ ```groovy
296
+ // build.gradle
297
+ dependencies {
298
+ implementation 'com.google.android.material:material:1.9.0'
299
+ implementation 'androidx.appcompat:appcompat:1.6.1'
300
+ implementation 'androidx.core:core-ktx:1.12.0'
301
+ }
302
+ ```
303
+
304
+ Extract the group:artifact for each dependency. In the conversion report, list these libraries with their likely resource prefixes so the developer knows which libraries contribute which missing resources.
305
+
306
+ ### Resolution Behavior for Missing Resources
307
+
308
+ When a reference cannot be resolved because the target resource is not in the lookup table:
309
+
310
+ 1. **Keep the HarmonyOS reference syntax** (`$color:name`, `$float:name`, `$media:name`, etc.) in the converted output — this makes the reference visible and searchable
311
+ 2. **Log it as an unsatisfied dependency** with:
312
+ - The reference (`@color/design_default_color_primary`)
313
+ - The source file where it was found
314
+ - The likely library source (if identifiable from naming patterns)
315
+ - The reason: "Library resource not available in source res/"
316
+ 3. **Do NOT substitute a default or placeholder value** — keeping the reference intact is more useful because:
317
+ - The developer can see exactly what's missing
318
+ - If the build is later fixed and resources re-converted from the APK, the output will be correct
319
+ - The reference name itself carries meaning for the developer
320
+
321
+ ### Categorizing Unresolved References
322
+
323
+ In the report, separate unresolved references into categories:
324
+
325
+ 1. **Missing library resources** — references to resources that likely come from declared library dependencies. These are expected when converting from source `res/`.
326
+ 2. **Theme attributes** (`?attr/name`) — cannot be statically resolved regardless of resource source.
327
+ 3. **System resources** (`@android:type/name`) — Android framework resources, not migrated.
328
+ 4. **Truly missing** — references that don't match any known library pattern and aren't in the lookup table. These may indicate a project misconfiguration or an undeclared dependency.
@@ -0,0 +1,173 @@
1
+ # Material Design Icon Download and Integration
2
+
3
+ When Android source code uses Material Design `imageVector` (such as `Icons.Outlined.Home`) to reference icons, you need to download the corresponding SVG from Google Fonts and integrate it into the HarmonyOS project.
4
+
5
+ ---
6
+
7
+ ## Complete Workflow
8
+
9
+ ### 1. Identify Icon References in Android Source Code
10
+
11
+ Search for icon definition files in the Android source code (usually enum classes or sealed classes) to identify two types of icons:
12
+
13
+ | Reference Type | Example | Source |
14
+ |---------------|---------|--------|
15
+ | `imageVector = Icons.Outlined.Xxx` | `Icons.Outlined.Share` | Material Design icon library, download from Google Fonts |
16
+ | `iconResId = R.drawable.xxx` | `R.drawable.ic_touch_enabled` | Project custom drawable, extract from Android `res/drawable/` |
17
+
18
+ **Typical Source Code Example** (Kotlin sealed class):
19
+
20
+ ```kotlin
21
+ data object Share : ToolbarAction(
22
+ title = R.string.share,
23
+ iconResId = R.drawable.ic_share, // Custom icon
24
+ imageVector = Icons.Outlined.Share, // Material Design icon
25
+ )
26
+ ```
27
+
28
+ When both `iconResId` and `imageVector` exist, **prefer the Material Design icon corresponding to `imageVector`** (more standardized, clearer).
29
+
30
+ ### 2. Map Icon Names
31
+
32
+ Convert `Icons.Outlined.Xxx` camelCase names from Kotlin to snake_case used by Google Fonts:
33
+
34
+ | Kotlin Name | snake_case Name | Download File Name |
35
+ |-------------|-----------------|-------------------|
36
+ | `Icons.Outlined.Share` | `share` | `md_share.svg` |
37
+ | `Icons.Outlined.AddHome` | `add_home` | `md_add_home.svg` |
38
+ | `Icons.Outlined.EditNote` | `edit_note` | `md_edit_note.svg` |
39
+ | `Icons.Outlined.ChromeReaderMode` | `chrome_reader_mode` | `md_chrome_reader_mode.svg` |
40
+ | `Icons.Outlined.LibraryBooks` | `library_books` | `md_library_books.svg` |
41
+
42
+ **Conversion Rule**: camelCase → lowercase + underscore separation (`AddHome` → `add_home`).
43
+
44
+ ### 3. Download SVG
45
+
46
+ **Download source**: https://fonts.google.com/icons?icon.size=24&icon.color=%231f1f1f
47
+
48
+ **Manual download method**:
49
+ 1. Open the Google Fonts Icons webpage above
50
+ 2. Search for icon name (e.g., `share`, `add_home`)
51
+ 3. Select **Outlined** style (corresponds to `Icons.Outlined`)
52
+ 4. Click to download SVG, choose 24px size, color `#1f1f1f` (dark black)
53
+
54
+ **Download URL pattern** (can be used for batch download scripts):
55
+ ```
56
+ https://fonts.gstatic.com/s/i/short-term/release/materialsymbolsoutlined/{icon_name}/default/24px.svg
57
+ ```
58
+
59
+ Example:
60
+ ```
61
+ https://fonts.gstatic.com/s/i/short-term/release/materialsymbolsoutlined/share/default/24px.svg
62
+ https://fonts.gstatic.com/s/i/short-term/release/materialsymbolsoutlined/add_home/default/24px.svg
63
+ ```
64
+
65
+ **Note**:
66
+ - The SVG downloaded from this URL has `fill="#000000"` (pure black)
67
+ - Downloaded SVG size is `viewBox="0 -960 960 960"` (Google standard Material Symbols coordinate system), renders correctly in HarmonyOS
68
+ - If an icon name doesn't exist in `materialsymbolsoutlined`, try `materialsymbolsrounded` or `materialsymbolssharp`
69
+
70
+ ### 4. Rename and Store
71
+
72
+ **Naming rule**: Add `md_` prefix + snake_case name uniformly
73
+
74
+ ```
75
+ Downloaded share.svg → md_share.svg
76
+ Downloaded add_home.svg → md_add_home.svg
77
+ ```
78
+
79
+ **Storage location**: `entry/src/main/resources/base/media/`
80
+
81
+ **Key constraints**:
82
+ - `media/` directory **does not support subdirectories** (e.g., `media/icons/` will cause `CompileResource` error "invalid path, not a file")
83
+ - File names only allow lowercase letters, numbers, underscores
84
+ - All icon files must be placed directly at the root level of `media/` directory
85
+
86
+ ### 5. Reference in ArkTS
87
+
88
+ ```typescript
89
+ // Reference method: $r('app.media.filename_without_extension')
90
+ Image($r('app.media.md_share'))
91
+ Image($r('app.media.md_add_home'))
92
+ ```
93
+
94
+ Typical icon mapping function pattern:
95
+
96
+ ```typescript
97
+ private getIconResource(action: string): Resource {
98
+ switch (action) {
99
+ case 'share':
100
+ return $r('app.media.md_share')
101
+ case 'add_home':
102
+ return $r('app.media.md_add_home')
103
+ case 'settings':
104
+ return $r('app.media.md_settings')
105
+ default:
106
+ return $r('app.media.icon_default')
107
+ }
108
+ }
109
+ ```
110
+
111
+ ---
112
+
113
+ ## Batch Download Script Example
114
+
115
+ Python script for batch downloading multiple icons:
116
+
117
+ ```python
118
+ import urllib.request
119
+ import os
120
+
121
+ icons = [
122
+ 'share', 'add_home', 'edit_note', 'logout', 'bookmark_add',
123
+ 'add_link', 'apps', 'copy_all', 'library_books', 'pdf',
124
+ 'download', 'rule_settings', 'settings', 'chrome_reader_mode',
125
+ 'record_voice_over', 'invert_colors', 'format_size', 'view_column',
126
+ 'chat', 'cancel_presentation', 'cloud_upload', 'bookmarks'
127
+ ]
128
+
129
+ output_dir = 'material_icons_svg'
130
+ os.makedirs(output_dir, exist_ok=True)
131
+
132
+ base_url = 'https://fonts.gstatic.com/s/i/short-term/release/materialsymbolsoutlined/{}/default/24px.svg'
133
+
134
+ for icon in icons:
135
+ url = base_url.format(icon)
136
+ out_path = os.path.join(output_dir, f'md_{icon}.svg')
137
+ try:
138
+ urllib.request.urlretrieve(url, out_path)
139
+ print(f'OK: {icon}')
140
+ except Exception as e:
141
+ print(f'FAIL: {icon} - {e}')
142
+ ```
143
+
144
+ ---
145
+
146
+ ## Common Icon Mapping Reference
147
+
148
+ Typical Material Design icon mappings for Android toolbar/menu items:
149
+
150
+ | Kotlin imageVector | snake_case Name | Download SVG | HarmonyOS Reference |
151
+ |-------------------|-----------------|-------------|---------------------|
152
+ | `Icons.Outlined.Share` | `share` | `md_share.svg` | `$r('app.media.md_share')` |
153
+ | `Icons.Outlined.Settings` | `settings` | `md_settings.svg` | `$r('app.media.md_settings')` |
154
+ | `Icons.Outlined.Home` | `home` | `md_home.svg` | `$r('app.media.md_home')` |
155
+ | `Icons.Outlined.Add` | `add` | `md_add.svg` | `$r('app.media.md_add')` |
156
+ | `Icons.Outlined.Edit` | `edit` | `md_edit.svg` | `$r('app.media.md_edit')` |
157
+ | `Icons.Outlined.Delete` | `delete` | `md_delete.svg` | `$r('app.media.md_delete')` |
158
+ | `Icons.Outlined.Search` | `search` | `md_search.svg` | `$r('app.media.md_search')` |
159
+ | `Icons.Outlined.ArrowBack` | `arrow_back` | `md_arrow_back.svg` | `$r('app.media.md_arrow_back')` |
160
+ | `Icons.Outlined.Bookmark` | `bookmark` | `md_bookmark.svg` | `$r('app.media.md_bookmark')` |
161
+ | `Icons.Outlined.BookmarkAdd` | `bookmark_add` | `md_bookmark_add.svg` | `$r('app.media.md_bookmark_add')` |
162
+ | `Icons.Outlined.Favorite` | `favorite` | `md_favorite.svg` | `$r('app.media.md_favorite')` |
163
+ | `Icons.Outlined.Share` | `share` | `md_share.svg` | `$r('app.media.md_share')` |
164
+ | `Icons.Outlined.Download` | `download` | `md_download.svg` | `$r('app.media.md_download')` |
165
+ | `Icons.Outlined.Upload` | `upload` | `md_upload.svg` | `$r('app.media.md_upload')` |
166
+ | `Icons.Outlined.Refresh` | `refresh` | `md_refresh.svg` | `$r('app.media.md_refresh')` |
167
+ | `Icons.Outlined.Menu` | `menu` | `md_menu.svg` | `$r('app.media.md_menu')` |
168
+ | `Icons.Outlined.MoreVert` | `more_vert` | `md_more_vert.svg` | `$r('app.media.md_more_vert')` |
169
+ | `Icons.Outlined.Close` | `close` | `md_close.svg` | `$r('app.media.md_close')` |
170
+ | `Icons.Outlined.Check` | `check` | `md_check.svg` | `$r('app.media.md_check')` |
171
+ | `Icons.Outlined.Visibility` | `visibility` | `md_visibility.svg` | `$r('app.media.md_visibility')` |
172
+
173
+ Note: `Icons.AutoMirrored.Outlined.*` variants use the same icon name as their non-mirrored counterparts (e.g., `Icons.AutoMirrored.Outlined.ArrowBack` → `arrow_back`).
@@ -0,0 +1,175 @@
1
+ # SVG Display Issue Fix Patterns
2
+
3
+ Common display abnormalities and fixes when migrating SVG/Vector Drawables from Android projects or manually creating SVGs.
4
+
5
+ ---
6
+
7
+ ## Issue 1: viewBox Does Not Match Path Coordinates
8
+
9
+ ### Symptoms
10
+ Icon does not display at all, or only shows a blank area.
11
+
12
+ ### Cause
13
+ The coordinate range defined by `viewBox` does not match the coordinate data in the `d` attribute of `<path>`.
14
+
15
+ For example: path data is based on a 512×512 coordinate system (coordinate values range from 85 to 448), but `viewBox` is set to `0 0 24 24`, causing all paths to exceed the visible area.
16
+
17
+ ### Fix
18
+
19
+ **Option A: Adjust viewBox to Match Path Coordinates (Recommended for Simple Cases)**
20
+ ```xml
21
+ <!-- Wrong: viewBox too small -->
22
+ <svg viewBox="0 0 24 24">
23
+ <path d="M101.51,411.23 Q85.21,395.05 ..." /> <!-- coordinates far exceed 24 -->
24
+ </svg>
25
+
26
+ <!-- Fixed: viewBox matches coordinate system, use width/height to control render size -->
27
+ <svg width="24" height="24" viewBox="0 0 512 512">
28
+ <path d="M101.51,411.23 Q85.21,395.05 ..." />
29
+ </svg>
30
+ ```
31
+
32
+ > Note: `viewBox` defines the path coordinate space, while `width`/`height` define the render size. They are independent.
33
+
34
+ **Option B: Scale Path Coordinates Proportionally (Recommended for Standardization)**
35
+
36
+ Scale all values in the path proportionally to the target coordinate system. For example, scaling from 512 to 24:
37
+
38
+ ```python
39
+ import re
40
+
41
+ scale = 24.0 / 512.0 # 0.046875
42
+
43
+ def scale_number(match):
44
+ num = float(match.group(0))
45
+ scaled = round(num * scale, 2)
46
+ return '{:.2f}'.format(scaled).rstrip('0').rstrip('.')
47
+
48
+ path_data = "M101.51,411.23Q85.21,395.05 85.22,371.75..."
49
+ result = re.sub(r'[0-9]+\.?[0-9]*', scale_number, path_data)
50
+ ```
51
+
52
+ After scaling, you can use the standard `viewBox="0 0 24 24"`, consistent with other Material Design icons.
53
+
54
+ ---
55
+
56
+ ## Issue 2: Android Vector Drawable Syntax Remnants
57
+
58
+ ### Symptoms
59
+ The SVG file contains Android-specific XML attributes that standard SVG renderers cannot parse.
60
+
61
+ ### Common Remnant Syntax
62
+
63
+ | Android Syntax | Standard SVG Equivalent |
64
+ |---------------|----------------------|
65
+ | `<group android:translateX="24" android:rotation="90">` | `<g transform="translate(24,0) rotate(90)">` |
66
+ | `android:fillColor="#FF000000"` | `fill="#000000"` |
67
+ | `android:pathData="..."` | `d="..."` |
68
+ | `android:viewportWidth="24"` | Part of `viewBox="0 0 24 24"` |
69
+ | `<vector>` root element | `<svg>` root element |
70
+ | `<clip-path android:pathData="..."/>` | `<defs><clipPath id="..."><path d="..."/></clipPath></defs>` |
71
+
72
+ ### Fix
73
+
74
+ Fully convert Android `<group>` transform attributes to SVG `transform`:
75
+
76
+ ```xml
77
+ <!-- Android Vector Drawable -->
78
+ <group
79
+ android:translateX="24"
80
+ android:translateY="0"
81
+ android:rotation="90"
82
+ android:pivotX="12"
83
+ android:pivotY="12"
84
+ android:scaleX="1.5"
85
+ android:scaleY="1.5">
86
+ <path android:pathData="M18,12l4,-4..." android:fillColor="#FFFFFF"/>
87
+ </group>
88
+
89
+ <!-- Converted to Standard SVG -->
90
+ <g transform="translate(24,0) rotate(90,12,12) scale(1.5,1.5)">
91
+ <path d="M18,12l4,-4..." fill="#FFFFFF"/>
92
+ </g>
93
+ ```
94
+
95
+ Transform order: `translate` → `rotate` (with pivot point) → `scale`
96
+
97
+ ---
98
+
99
+ ## Issue 3: Fill Color is White Causing Invisible Icon
100
+
101
+ ### Symptoms
102
+ SVG file exists and path is correct, but icon does not display (invisible on white background).
103
+
104
+ ### Cause
105
+ The original Android drawable's `fillColor` is `#FFFFFF` (white), which is invisible on a white background. Common for icons designed to appear on dark ActionBars.
106
+
107
+ ### Fix
108
+
109
+ Change `fill="#FFFFFF"` to `fill="#000000"` (black), or choose a suitable color based on UI needs:
110
+
111
+ ```xml
112
+ <!-- Before fix: white fill invisible on white background -->
113
+ <path fill="#FFFFFF" d="M18,12l4,-4..."/>
114
+
115
+ <!-- After fix -->
116
+ <path fill="#000000" d="M18,12l4,-4..."/>
117
+ ```
118
+
119
+ ---
120
+
121
+ ## Issue 4: Google Material Symbols Coordinate System
122
+
123
+ ### Description
124
+ Material Symbols SVGs downloaded from Google Fonts use a special coordinate system:
125
+
126
+ ```xml
127
+ <svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#000000">
128
+ <path d="M200-120q-33 0-56.5-23.5T120-200v-560..."/>
129
+ </svg>
130
+ ```
131
+
132
+ - `viewBox="0 -960 960 960"` — Y-axis starts at -960 (positive is upward)
133
+ - Many negative values in path coordinates are normal
134
+ - This format renders correctly in HarmonyOS, **no additional conversion needed**
135
+
136
+ ---
137
+
138
+ ## Issue 5: HarmonyOS media Directory Does Not Support Subdirectories
139
+
140
+ ### Symptoms
141
+ Compilation error: `CompileResource` error "invalid path, not a file"
142
+
143
+ ### Cause
144
+ Created subdirectories under `resources/base/media/` (e.g., `media/icons/`, `media/md/`).
145
+
146
+ ### Fix
147
+
148
+ Move all files from subdirectories to the `media/` root directory, using file name prefixes to distinguish sources:
149
+
150
+ ```bash
151
+ # Wrong: using subdirectories
152
+ media/
153
+ md/
154
+ share.svg
155
+ home.svg
156
+
157
+ # Correct: flat storage with prefixes
158
+ media/
159
+ md_share.svg
160
+ md_home.svg
161
+ ic_custom_icon.svg
162
+ ```
163
+
164
+ ---
165
+
166
+ ## Quick Diagnosis Checklist
167
+
168
+ When SVG icon does not display, check in order:
169
+
170
+ 1. **File exists?** — Confirm the file exists under `entry/src/main/resources/base/media/`
171
+ 2. **Reference correct?** — `$r('app.media.filename_without_extension')`, filename is case-sensitive
172
+ 3. **viewBox matches?** — `viewBox` coordinate range must cover path data coordinate values
173
+ 4. **Syntax standard?** — No `android:` namespace attributes, root element is `<svg>` not `<vector>`
174
+ 5. **Fill color visible?** — `fill` is not `#FFFFFF` (invisible on white background)
175
+ 6. **No subdirectories?** — SVG files are directly under `media/` root directory