1# Power-off Charging Animation Customization
2
3## Overview
4
5### Introduction
6
7By default, the OpenHarmony provides the animation that displays information such as the battery level during power-off charging. However, some vendors may expect to use custom power-off charging animations for their products. To address this requirement, OpenHarmony provides the function of customizing power-off charging animations.
8
9### Constraints
10
11
12The configuration path for battery level customization is subject to the [configuration policy](https://gitee.com/openharmony/customization_config_policy). In this development guide, `/vendor` is used as an example of the configuration path. During actual development, you need to modify the customization path based on the product configuration policy.
13
14## How to Develop
15
16### Setting Up the Environment
17
18**Hardware requirements:**
19
20Development board running the standard system, for example, the DAYU200 or Hi3516D V300 open source suite.
21
22**Environment requirements:**
23
24For details about the requirements on the Linux environment, see [Quick Start](../quick-start/quickstart-overview.md).
25
26### Getting Started with Development
27
28The following uses [DAYU200](https://gitee.com/openharmony/vendor_hihope/tree/master/rk3568) as an example to illustrate power-off charging animation customization.
29
301. Create the `animation` folder in the product directory [/vendor/hihope/rk3568](https://gitee.com/openharmony/vendor_hihope/tree/master/rk3568).
31
322. Create a target folder by referring to the [default folder of power-off charging animation configuration](https://gitee.com/openharmony/powermgr_battery_manager/tree/master/charger/sa_profile), and install it in `//vendor/hihope/rk3568/animation`. The content is as follows:
33
34    ```text
35    profile
36    ├── BUILD.gn
37    ├── animation.json
38    ```
39
403. Create the `resources` folder by referring to [default folder of power-off charging animation image resources](https://gitee.com/openharmony/powermgr_battery_manager/tree/master/charger/resources) to store the images that form the animation, and install the folder in `//vendor/hihope/rk3568/animation`. The content is as follows:
41
42    ```text
43    animation
44    ├── resources
45    ├── profile
46    ```
47
484. Write the `BUILD.gn` file by referring to the [BUILD.gn](https://gitee.com/openharmony/powermgr_battery_manager/blob/master/charger/resources/BUILD.gn) in the default folder of power-off charging animation configuration, and put it to the `//vendor/hihope/rk3568/animation/resource` directory. The configuration is as follows:
49    ```gn
50    import("//build/ohos.gni")
51
52    ohos_prebuilt_etc("resources_config0") {
53        source = "loop00000.png"                                        # Image resource
54        relative_install_dir = "poweroff_charger_animation/resources"
55        install_images = [ chipset_base_dir ]                           # Required configuration for installing the resources folder in the vendor directory.
56        part_name = "product_rk3568"
57    }
58    ```
59
605. Write the custom **animation.json** file by referring to the [animation.json](https://gitee.com/openharmony/powermgr_battery_manager/blob/master/charger/sa_profile/animation.json) file in the default folder of power-off charging animation image resources.  The configuration is as follows:
61
62    ```json
63    {
64        "animation": {
65            "components": [
66                {
67                    "type": "UIImageView",
68                    "id": "Charging_Animation_Image",
69                    "x": 200,
70                    "y": 480,
71                    "w": 400,
72                    "h": 400,
73                    "resPath": "/system/etc/charger/resources/",
74                    "imgCnt": 62,
75                    "updInterval": 60,
76                    "filePrefix": "loop"
77                },
78                {
79                    "type": "UILabel",
80                    "id": "Charging_Percent_Label",
81                    "text": "",
82                    "x": 326,
83                    "y": 616,
84                    "w": 68,
85                    "h": 48,
86                    "fontSize": 32,
87                    "fontColor": "#ffffffe6",
88                    "bgColor": "#00000000"
89                    "align": "center"
90                }
91            ]
92        },
93        "lackpowerChargingPrompt": {
94            "components": [
95                {
96                    "type": "UILabel",
97                    "id": "LackPower_Charging_Label",
98                    "text": "Low battery level",
99                    "x": 229,
100                    "y": 1037,
101                    "w": 250,
102                    "h": 45,
103                    "fontSize": 42,
104                    "fontColor": "#ff0000ff",
105                    "bgColor": "#00000000",
106                    "align": "center"
107                }
108            ]
109        },
110        "lackpowerNotChargingPrompt": {
111            "components": [
112                {
113                    "type": "UILabel",
114                    "id": "LackPower_Not_Charging_Label",
115                    "text": "Low battery level. Please connect the power supply.",
116                    "x": 110,
117                    "y": 1037,
118                    "w": 500,
119                    "h": 45,
120                    "fontSize": 42,
121                    "fontColor": "#ff0000ff",
122                    "bgColor": "#00000000",
123                    "align": "center"
124                }
125            ]
126        }
127    }
128    ```
129
130    **Table 1** Description of the power-off charging animation configuration
131    | Item| Description|
132    | -------- | -------- |
133    | animation | Animation configuration.|
134    | lackpowerChargingPrompt| Prompt for the **Charging** state in the low battery level.|
135    | lackpowerNotChargingPrompt | Prompt for the **Not charging** state in the low battery level.|
136    | components | Component set.|
137    | type | Component type.|
138    | id | Component ID.|
139    | text | Text content of a component.|
140    | x | X coordinate of the component.|
141    | y | Y coordinate of the component.|
142    | w | Component width, in pixels.|
143    | h | Component height, in pixels.|
144    | fontSize | Font size of the text.|
145    | fontColor | Font color of the text.|
146    | align | Text alignment mode.|
147    | imgCnt | Number of images.|
148    | updInterval | Image updating interval, in ms.|
149    | filePrefix | Prefix of an image file name.|
150    | resPath | Resource file path of the component.|
151
152
153
1546. Write the `BUILD.gn` file by referring to the [BUILD.gn](https://gitee.com/openharmony/powermgr_battery_manager/blob/master/charger/sa_profile/BUILD.gn) file in the default folder of power-off charging animation configuration to pack the `animation_config.json` file to the `//vendor/etc/charger` directory. The configuration is as follows:
155
156    ```gn
157    import("//build/ohos.gni")
158
159    ohos_prebuilt_etc("animation_config") {
160        source = "animation.json"             # Reference build/ohos.gni.
161        relative_install_dir = "animation/resources"
162        install_images = [ chipset_base_dir ] # Required configuration for installing the battery_config.json file in the vendor directory.
163        part_name = "product_rk3568"          # Set part_name to product_rk3568 for subsequent build.
164    }
165    ```
166
1677. Add the build target to `module_list` in [ohos.build](https://gitee.com/openharmony/vendor_hihope/blob/master/rk3568/ohos.build) in the `/vendor/hihope/rk3568` directory. For example:
168
169    ```json
170    {
171    "parts": {
172        "product_rk3568": {
173        "module_list": [
174            "//vendor/hihope/rk3568/default_app_config:default_app_config",
175            "//vendor/hihope/rk3568/image_conf:custom_image_conf",
176            "//vendor/hihope/rk3568/preinstall-config:preinstall-config",
177            "//vendor/hihope/rk3568/resourceschedule:resourceschedule",
178            "//vendor/hihope/rk3568/etc:product_etc_conf",
179            "//vendor/hihope/rk3568/battery/profile:battery_config",
180            "//vendor/hihope/rk3568/animation/profile:animation_config", # Add the configuration for building of animation_config.
181            "//vendor/hihope/rk3568/animation/resource/resources_config" # Add the configuration for building of image resources.
182        ]
183        }
184    },
185    "subsystem": "product_hihope"
186    }
187    ```
188    In the preceding code, `//vendor/hihope/rk3568/animation/` is the folder path, `profile` is the folder name, and `animation_config` is the build target.
189
1908. Build the customized version by referring to [Quick Start](../quick-start/quickstart-overview.md).
191
192    ```shell
193    ./build.sh --product-name rk3568 --ccache
194    ```
195
1969. Burn the customized version to the DAYU200 development board.
197
198### Debugging and Verification
1991. Modify the code configuration.
200    Code path: `base/startup/init/services/init/init_config.c`
201    Function: `ReadConfig`
202    Before the modification:
203    ```c
204    void ReadConfig(void)
205    {
206        // parse cfg
207        char buffer[32] = {0}; // 32 reason max leb
208        uint32_t len = sizeof(buffer);
209        SystemReadParam("ohos.boot.mode", buffer, &len);
210        INIT_LOGI("ohos.boot.mode %s", buffer);
211        if (strcmp(buffer, "charger_mode") == 0) {
212            // Execute this branch process for product customization.
213            ParseInitCfg(INIT_CONFIGURATION_FILE, NULL);
214            ReadFileInDir(OTHER_CHARGE_PATH, ".cfg", ParseInitCfg, NULL);
215            ParseInitCfgByPriority();
216        } else if (strcmp(buffer, "charger") == 0) {
217            ParseInitCfg(INIT_CONFIGURATION_FILE, NULL);
218            ReadFileInDir(OTHER_CHARGE_PATH, ".cfg", ParseInitCfg, NULL);
219        } else if (InUpdaterMode() == 0) {
220            ParseInitCfg(INIT_CONFIGURATION_FILE, NULL);
221            ParseInitCfgByPriority();
222        } else {
223            ReadFileInDir("/etc", ".cfg", ParseInitCfg, NULL);
224        }
225    }
226    ```
227    After the modification:
228    ```c
229    void ReadConfig(void)
230    {
231        // parse cfg
232        char buffer[32] = {0}; // 32 reason max leb
233        uint32_t len = sizeof(buffer);
234        SystemReadParam("ohos.boot.mode", buffer, &len);
235        INIT_LOGI("ohos.boot.mode %s", buffer);
236        ParseInitCfg(INIT_CONFIGURATION_FILE, NULL);
237        ReadFileInDir(OTHER_CHARGE_PATH, ".cfg", ParseInitCfg, NULL);
238        ParseInitCfgByPriority();
239    }
240    ```
241
2422. Use the hdc tool to run the following commands to force the development board to enter the power-off charging state.
243    ```shell
244    hdc shell
245    reboot charge
246    ```
247
248    ![animation_initial_power](figures/animation_initial_power.jpg)
249
2503. Go to the custom battery level configuration directory. The path of DAYU200 is used as an example.
251    ```shell
252    cd /data/service/el0/battery/battery
253    ```
254
2554. Change the battery power, and observe the number change on the charging animation.
256    ```shell
257    cat capacity
258    ```
259    Change the current battery power to **3**.
260    ```shell
261    echo 3 > capacity
262    ```
263    ![animation_charing_power](figures/animation_charing_power.jpg)
264
2655. Switch to the **Not charging** state. The device is powered off.
266    ```shell
267    echo Not charging > status
268    ```
269
2706. Change the charging status when the battery level is extremely low (1% by default). This can trigger the mapping animation or device shutdown.
271
272    1. Go to the custom battery level configuration directory.
273    ```shell
274    cd /data/service/el0/battery/battery
275    cat capacity
276    ```
277    2. Change the current battery power to **1**.
278    ```shell
279    echo 1 > capacity
280    ```
281    3. Check the charging status.
282    ```shell
283    cat status
284    ```
285    The current status is **Charging**.
286
287    ![animation_low_power](figures/animation_low_power.jpg)
288
289    4. Switch to the **Not charging** state.
290    ```shell
291    echo Not charging > status
292    ```
293    ![animation_low_power2](figures/animation_low_power2.jpg)
294
2957. Test the power-off animation customization function by changing related images. The procedure is the same as that described above.
296
297    1. Initial state
298
299    ![animation_charging_power2](figures/animation_charging_power2.jpg)
300
301    2. %3 battery power
302
303    ![animation_initial_power2](figures/animation_initial_power2.jpg)
304
305    3. 1% battery power, **Charging** state
306
307    ![animation_low_power](figures/animation_low_power.jpg)
308
309    4. 1% battery power, **Not charging** state
310
311    ![animation_low_power2](figures/animation_low_power2.jpg)
312
313    5. When the battery level is higher than 1%, the system switches to the **Not charging** state.
314    ```shell
315    echo 3 > capacity
316    echo Not charging > status
317    ```
318
319
320
321## Reference
322During development, you can refer to the [default power-off animation configuration](https://gitee.com/openharmony/powermgr_battery_manager/blob/master/charger/sa_profile/animation.json), as shown below:
323
324
325```json
326{
327        "animation": {
328            "components": [
329                {
330                    "type": "UIImageView",
331                    "id": "Charging_Animation_Image",
332                    "x": 180,
333                    "y": 410,
334                    "w": 400,
335                    "h": 400,
336                    "resPath": "/system/etc/charger/resources/",
337                    "imgCnt": 62,
338                    "updInterval": 60,
339                    "filePrefix": "loop"
340                },
341                {
342                    "type": "UILabel",
343                    "id": "Charging_Percent_Label",
344                    "text": "",
345                    "x": 365,
346                    "y": 580,
347                    "w": 65,
348                    "h": 43,
349                    "fontSize": 32,
350                    "fontColor": "#ffffffe6",
351                    "bgColor": "#00000000",
352                    "align": "center"
353                }
354            ],
355        },
356        "lackpowerChargingPrompt": {
357            "components": [
358                {
359                    "type": "UILabel",
360                    "id": "LackPower_Charging_Label",
361                    "text": "Low battery level",
362                    "x": 229,
363                    "y": 1037,
364                    "w": 250,
365                    "h": 45,
366                    "fontSize": 42,
367                    "fontColor": "#ff0000ff",
368                    "bgColor": "#00000000",
369                    "align": "center"
370                }
371            ]
372        },
373        "lackpowerNotChargingPrompt": {
374            "components": [
375                {
376                    "type": "UILabel",
377                    "id": "LackPower_Not_Charging_Label",
378                    "text": "Low battery level. Please connect the power supply.",
379                    "x": 110,
380                    "y": 1037,
381                    "w": 500,
382                    "h": 45,
383                    "fontSize": 42,
384                    "fontColor": "#ff0000ff",
385                    "bgColor": "#00000000",
386                    "align": "center"
387                }
388            ]
389        }
390    }
391```
392
393Packing path: /system/etc/charger/resource
394