# ICU version upgrade Upgrade the ICU on Android to the new upstream version. The new upstream versions can be found at https://github.com/unicode-org/icu/releases. The below contains the steps and commands in order to upgrade the ICU version in the AOSP. # Prerequisites 1. Install the prerequisite tools * See http://site.icu-project.org/repository * [git-lts](https://git-lfs.github.com/) has to be installed to pull binaries correctly from the github. * [git-filter-repo](https://github.com/newren/git-filter-repo) for rewriting the `Change-Id` later. 2. Generate a github read-access token and setup a local ~/.m2/setting.xml * See http://cldr.unicode.org/development/maven. This is required to download the prebuilt ICU to break the circular dependency between CLDR and icu. 3. Check out goog/main * http://go/repo-init/git_main # Branch Structure 1. `external/icu` project in the AOSP, * We **rebase** Android-specific patches on the `icu-staging` branch. Then we merge into `goog/main` later. 2. `external/cldr` project * We use the **`goog/upstream-release-cldr** as the mirror of the upstream release branch. We don’t modify this branch with Android patches, but merge this branch into goog/main where the Android patches are located. # Verifying the cleanliness 1. Build the clean source of AOSP ```shell source build/envsetup.sh lunch cf_x86_64_phone-trunk_staging-userdebug m ``` The build should succeed. Otherwise, your local repo may be broken. Please consider to re-sync. 2. Verify that the generated artifacts are clean * If you re-run the generation scripts and it causes new changes, some patches are missing in the sources, e.g. `icu4j/` and `icu4c` or `external/cldr`. * The scripts include ```shell external/icu/tools/updatecldrdata.py external/icu/tools/updateicudata.py system/timezone/update-tzdata.py external/icu/tools/srcgen/generate_android_icu4j.sh external/icu/tools/icu4c_srcgen/generate_libandroidicu.py external/icu/tools/icu4c_srcgen/generate_ndk.py ``` # Steps 1. Configure the versions and temp directory * Customize the following environment variables. The following example targets the ICU 76.1 and CLDR 46.0 version. ```shell export ICU_VERSION=76 export ICU_MINOR_VERSION=1 export CLDR_VERSION=46 export ICU_UPGRADE_BUG=1234567890 # buganizer bug ``` * Set the path where you want to store the upstream ICU and CLDR sources ```shell export UPSTREAM_CLDR_GIT= export UPSTREAM_ICU_GIT= ``` * Initialize empty directories to store upstream sources if the above directories needs to be created. ```shell mkdir -p ${UPSTREAM_CLDR_GIT} mkdir -p ${UPSTREAM_ICU_GIT} ``` 2. Copy the CLDR sources into the `upstream-release-cldr` branch 2a. Copy sources ```shell export CLDR_UPSTREAM_BRANCH=release-${CLDR_VERSION} cd ${ANDROID_BUILD_TOP}/external/cldr git fetch goog upstream-release-cldr git branch ${CLDR_UPSTREAM_BRANCH} --track goog/upstream-release-cldr git checkout ${CLDR_UPSTREAM_BRANCH} git clone https://github.com/unicode-org/cldr.git ${UPSTREAM_CLDR_GIT} git --git-dir=${UPSTREAM_CLDR_GIT}/.git --work-tree=${UPSTREAM_CLDR_GIT} fetch git --git-dir=${UPSTREAM_CLDR_GIT}/.git --work-tree=${UPSTREAM_CLDR_GIT} checkout ${CLDR_UPSTREAM_BRANCH} rm -rf * cp -r ${UPSTREAM_CLDR_GIT}/* . git clean -dfX # Remove ignored files git add -A git commit -F- <~1.. ``` * If any cherry-picks causes conflicts, please resolve them carefully. * If the patch and a upstream commit resolves the same issue, or the patch has been upstreamed, the patch can be discarded. 4b. Cherry-pick theq patches since the ICU upgrade * Find the patches with this query. * AOSP gerrit: https://r.android.com/q/%2522Android+patch%2522+project:platform/external/icu+status:merged+-owner:automerger+-owner:android-build-coastguard-worker%2540google.com+branch:main * Internal gerrit: https://googleplex-android-review.git.corp.google.com/q/%2522Android+patch%2522+project:platform/external/icu+status:merged+-owner:automerger+-owner:android-build-coastguard-worker%2540google.com+branch:main 4c. Reset `Change-Id` in the cherry-picked CLs * ```shell THE_COPY_COMMIT=$(git log --pretty=format:'%h' -n 1 --grep "Copy ICU ${UPSTREAM_RELEASE_TAG} into goog/${ICU_BRANCH}") git filter-branch -f --msg-filter 'sed "s/Change-Id: .*//g"' ${THE_COPY_COMMIT}..HEAD git rebase -i ${THE_COPY_COMMIT} # It should open vim # Replace pick with reword in vim `%s/pick /reword /g` # Close all commit message edits with :wq in vim # It triggers the git-hook to generate a Change-Id. # TODO: Find a better way to generate Change-Id ``` 5. Regenerate and commit the artifacts 5a. Update icu source data files ```shell croot external/icu tools/updatecldrdata.py && \ git add -A && \ git commit -F- < libs/androidfw/LocaleDataLookup.cpp git commit -a -F- < libs/androidfw/LocaleDataLookup.cpp Bug: ${ICU_UPGRADE_BUG} Test: atest libandroidfw_tests FrameworksCoreTests:android.text.format EOF ``` 6. Build and run test 6a. Build by `m droid cts` 6b. Run the device tests by `atest CtsIcu4cTestCases CtsIcuTestCases CtsLibcoreTestCases CtsLibcoreOjTestCases CtsBionicTestCases CtsTextTestCases minikin_tests -- --abi x86_64 # the primary ABI` * If running `CtsIcu4cTestCases` causes a native crash, e.g. `exit code 137`, check `adb logcat` for native crash dump. * If the native crash dump isn't found, try to run the following shell command before checking the logcat again. * ```shell m CtsIcu4cTestCases && \ adb push out/soong/.intermediates/external/icu/icu4c/source/test/intltest/intltest64/android_x86_64_silvermont/intltest64 /data/local/tmp/intltest && \ # replace android_x86_64_silvermont if you are not using cuttlefish. adb push out/host/linux-x86/testcases/CtsIcu4cTestCases/icu4c_test_data.zip /data/local/tmp/icu4c_test_data.zip && \ adb shell unzip -o -d /data/local/tmp/ /data/local/tmp/icu4c_test_data.zip && \ adb shell chmod a+x /data/local/tmp/intltest && \ adb shell /data/local/tmp/intltest -w -x /data/local/tmp/intltest_res.xml ``` 6c. [No longer needed] Run the host-side test by * ICU4J host-side test `ant check` * ICU4C host-side test `make CINTLTST_OPTS=-w INTLTEST_OPTS=-w check` (Currently, it has some failing tests. No of failures?) 6d. If libcore/ tests are changed, verify the change * To verify the test change in ART MTS, run `m mts && mts-tradefed run mts-art` on Android S. * To verify the test change on LUCI bot, run `art/tools/run-libcore-tests.sh --mode=host`, because LUCI uses older ICU versions. 7. Upload the CLs to gerrit for code reviews from `goog/icu-staging` in `external/icu` and `goog/upstream-release-cldr` in `external/cldr` ```shell repo upload --cbr -o nokeycheck -o uploadvalidator~skip --no-verify . ``` 8. Merge `goog/icu*` branch to goog/main ```shell cd $ANDROID_BUILD_TOP/external/icu repo start icu${ICU_VERSION}-main . git merge --no-ff icu-staging -m " Merge branch goog/icu-staging into goog/main Bug: ${ICU_UPGRADE_BUG} Test: atest CtsIcu4cTestCases CtsIcuTestCases CtsLibcoreTestCases CtsLibcoreOjTestCases CtsBionicTestCases CtsTextTestCases minikin_tests " ``` 9. Update the version numbers in the METADATA 9a. Update the external/icu/METADATA in `git_main` 9b. Update version and upgrade date in external/cldr/METADATA 9c. `git commit` the file change 10. Upload and submit changes from external/icu, external/cldr, libcore, frameworks/base, system/timezone 10a. `repo upload --cbr -o uploadvalidator~skip --no-verify .` 10b. Code review the diff in `android_icu4j/src/main/tests/android/icu/extratest/expected_transliteration_id_list.txt` * If a transliteration id is removed from the list, it may introduce app compatibility issues if the app depends on them. However, app has been warned to check the availability before invoking them. https://developer.android.com/reference/android/icu/text/Transliterator#getAvailableIDs() 11. After submitting all the CLs to goog/main, expose the new stable ICU4J APIs to Android SDK ```shell rm tools/srcgen/allowlisted-public-api.txt ./tools/srcgen/generate_android_icu4j.sh # Modify Icu4jTransform.java to allowlist more classes if needed. Check the error message for the details m update-api droid git commit -a -F- < just landed Android AOSP. https://googleplex-android.googlesource.com/platform/external/icu/+/main/METADATA Note: - Contains bug fixes / build changes with a small set of API methods added. - Unicode stays at version 16, and no new version has been published yet. ``` ## Historic version of this doc http://g3doc/third_party/icu/g3doc/update/android