Initialize cec menu language correctly.
Change-Id: I777af17c0351df8610ad7198ce06b1e92e7e7666
Bug: 149098143
Test: atest HdmiControlServiceStaticTest HdmiControlServiceTest
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 7c2ec78..d9e3025 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -105,32 +105,57 @@
*/
public class HdmiControlService extends SystemService {
private static final String TAG = "HdmiControlService";
- private final Locale HONG_KONG = new Locale("zh", "HK");
- private final Locale MACAU = new Locale("zh", "MO");
+ private static final Locale HONG_KONG = new Locale("zh", "HK");
+ private static final Locale MACAU = new Locale("zh", "MO");
- private static final Map<String, String> mTerminologyToBibliographicMap;
- static {
- mTerminologyToBibliographicMap = new HashMap<>();
+ private static final Map<String, String> sTerminologyToBibliographicMap =
+ createsTerminologyToBibliographicMap();
+
+ private static Map<String, String> createsTerminologyToBibliographicMap() {
+ Map<String, String> temp = new HashMap<>();
// NOTE: (TERMINOLOGY_CODE, BIBLIOGRAPHIC_CODE)
- mTerminologyToBibliographicMap.put("sqi", "alb"); // Albanian
- mTerminologyToBibliographicMap.put("hye", "arm"); // Armenian
- mTerminologyToBibliographicMap.put("eus", "baq"); // Basque
- mTerminologyToBibliographicMap.put("mya", "bur"); // Burmese
- mTerminologyToBibliographicMap.put("ces", "cze"); // Czech
- mTerminologyToBibliographicMap.put("nld", "dut"); // Dutch
- mTerminologyToBibliographicMap.put("kat", "geo"); // Georgian
- mTerminologyToBibliographicMap.put("deu", "ger"); // German
- mTerminologyToBibliographicMap.put("ell", "gre"); // Greek
- mTerminologyToBibliographicMap.put("fra", "fre"); // French
- mTerminologyToBibliographicMap.put("isl", "ice"); // Icelandic
- mTerminologyToBibliographicMap.put("mkd", "mac"); // Macedonian
- mTerminologyToBibliographicMap.put("mri", "mao"); // Maori
- mTerminologyToBibliographicMap.put("msa", "may"); // Malay
- mTerminologyToBibliographicMap.put("fas", "per"); // Persian
- mTerminologyToBibliographicMap.put("ron", "rum"); // Romanian
- mTerminologyToBibliographicMap.put("slk", "slo"); // Slovak
- mTerminologyToBibliographicMap.put("bod", "tib"); // Tibetan
- mTerminologyToBibliographicMap.put("cym", "wel"); // Welsh
+ temp.put("sqi", "alb"); // Albanian
+ temp.put("hye", "arm"); // Armenian
+ temp.put("eus", "baq"); // Basque
+ temp.put("mya", "bur"); // Burmese
+ temp.put("ces", "cze"); // Czech
+ temp.put("nld", "dut"); // Dutch
+ temp.put("kat", "geo"); // Georgian
+ temp.put("deu", "ger"); // German
+ temp.put("ell", "gre"); // Greek
+ temp.put("fra", "fre"); // French
+ temp.put("isl", "ice"); // Icelandic
+ temp.put("mkd", "mac"); // Macedonian
+ temp.put("mri", "mao"); // Maori
+ temp.put("msa", "may"); // Malay
+ temp.put("fas", "per"); // Persian
+ temp.put("ron", "rum"); // Romanian
+ temp.put("slk", "slo"); // Slovak
+ temp.put("bod", "tib"); // Tibetan
+ temp.put("cym", "wel"); // Welsh
+ return Collections.unmodifiableMap(temp);
+ }
+
+ @VisibleForTesting static String localeToMenuLanguage(Locale locale) {
+ if (locale.equals(Locale.TAIWAN) || locale.equals(HONG_KONG) || locale.equals(MACAU)) {
+ // Android always returns "zho" for all Chinese variants.
+ // Use "bibliographic" code defined in CEC639-2 for traditional
+ // Chinese used in Taiwan/Hong Kong/Macau.
+ return "chi";
+ } else {
+ String language = locale.getISO3Language();
+
+ // locale.getISO3Language() returns terminology code and need to
+ // send it as bibliographic code instead since the Bibliographic
+ // codes of ISO/FDIS 639-2 shall be used.
+ // NOTE: Chinese also has terminology/bibliographic code "zho" and "chi"
+ // But, as it depends on the locale, is not handled here.
+ if (sTerminologyToBibliographicMap.containsKey(language)) {
+ language = sTerminologyToBibliographicMap.get(language);
+ }
+
+ return language;
+ }
}
static final String PERMISSION = "android.permission.HDMI_CEC";
@@ -208,8 +233,8 @@
}
break;
case Intent.ACTION_CONFIGURATION_CHANGED:
- String language = getMenuLanguage();
- if (!mLanguage.equals(language)) {
+ String language = HdmiControlService.localeToMenuLanguage(Locale.getDefault());
+ if (!mMenuLanguage.equals(language)) {
onLanguageChanged(language);
}
break;
@@ -221,28 +246,6 @@
}
}
- private String getMenuLanguage() {
- Locale locale = Locale.getDefault();
- if (locale.equals(Locale.TAIWAN) || locale.equals(HONG_KONG) || locale.equals(MACAU)) {
- // Android always returns "zho" for all Chinese variants.
- // Use "bibliographic" code defined in CEC639-2 for traditional
- // Chinese used in Taiwan/Hong Kong/Macau.
- return "chi";
- } else {
- String language = locale.getISO3Language();
-
- // locale.getISO3Language() returns terminology code and need to
- // send it as bibliographic code instead since the Bibliographic
- // codes of ISO/FDIS 639-2 shall be used.
- // NOTE: Chinese also has terminology/bibliographic code "zho" and "chi"
- // But, as it depends on the locale, is not handled here.
- if (mTerminologyToBibliographicMap.containsKey(language)) {
- language = mTerminologyToBibliographicMap.get(language);
- }
-
- return language;
- }
- }
}
// A thread to handle synchronous IO of CEC and MHL control service.
@@ -339,7 +342,7 @@
private int mPowerStatus = HdmiControlManager.POWER_STATUS_STANDBY;
@ServiceThreadOnly
- private String mLanguage = Locale.getDefault().getISO3Language();
+ private String mMenuLanguage = localeToMenuLanguage(Locale.getDefault());
@ServiceThreadOnly
private boolean mStandbyMessageReceived = false;
@@ -759,7 +762,7 @@
private void initializeCec(int initiatedBy) {
mAddressAllocated = false;
mCecController.setOption(OptionKey.SYSTEM_CEC_CONTROL, true);
- mCecController.setLanguage(mLanguage);
+ mCecController.setLanguage(mMenuLanguage);
initializeLocalDevices(initiatedBy);
}
@@ -2818,7 +2821,7 @@
@ServiceThreadOnly
private void onLanguageChanged(String language) {
assertRunOnServiceThread();
- mLanguage = language;
+ mMenuLanguage = language;
if (isTvDeviceEnabled()) {
tv().broadcastMenuLanguage(language);
@@ -2826,10 +2829,19 @@
}
}
+ /**
+ * Gets the CEC menu language.
+ *
+ * <p>This is the ISO/FDIS 639-2 3 letter language code sent in the CEC message @{code <Set Menu
+ * Language>}.
+ * See HDMI 1.4b section CEC 13.6.2
+ *
+ * @see {@link Locale#getISO3Language()}
+ */
@ServiceThreadOnly
String getLanguage() {
assertRunOnServiceThread();
- return mLanguage;
+ return mMenuLanguage;
}
private void disableDevices(PendingActionClearedCallback callback) {
@@ -2838,7 +2850,6 @@
device.disableDevice(mStandbyMessageReceived, callback);
}
}
-
mMhlController.clearAllLocalDevices();
}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceStaticTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceStaticTest.java
new file mode 100644
index 0000000..607cd81
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceStaticTest.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.hdmi;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.util.Locale;
+
+/**
+ * Tests for static methods of {@link HdmiControlService} class.
+ */
+@SmallTest
+@RunWith(JUnit4.class)
+public class HdmiControlServiceStaticTest {
+
+ @Test
+ public void localToMenuLanguage_english() {
+ assertThat(HdmiControlService.localeToMenuLanguage(Locale.ENGLISH)).isEqualTo("eng");
+ }
+
+ @Test
+ public void localToMenuLanguage_german() {
+ assertThat(HdmiControlService.localeToMenuLanguage(Locale.GERMAN)).isEqualTo("ger");
+ }
+
+ @Test
+ public void localToMenuLanguage_taiwan() {
+ assertThat(HdmiControlService.localeToMenuLanguage(Locale.TAIWAN)).isEqualTo("chi");
+ }
+
+ @Test
+ public void localToMenuLanguage_macau() {
+ assertThat(HdmiControlService.localeToMenuLanguage(new Locale("zh", "MO"))).isEqualTo(
+ "chi");
+ }
+
+ @Test
+ public void localToMenuLanguage_hongkong() {
+ assertThat(HdmiControlService.localeToMenuLanguage(new Locale("zh", "HK"))).isEqualTo(
+ "chi");
+ }
+
+ @Test
+ public void localToMenuLanguage_chinese() {
+ assertThat(HdmiControlService.localeToMenuLanguage(Locale.CHINESE)).isEqualTo("zho");
+ }
+
+}