CEC: Process new options for CEC/MHL HAL

1) Inform MHL HAL of OPTION_MHL_SERVICE_CONTROL at system
ready/standby event.

2) Call OPTION_CEC_SET_LANGUAGE with current system language info
for HAL to be able to respond to <Get Menu Language> while in standby
mode.

Bug: 19054079
Change-Id: I92c9f392a94f70e11157d20a33163ef2d8bc832f
diff --git a/services/core/java/com/android/server/hdmi/Constants.java b/services/core/java/com/android/server/hdmi/Constants.java
index f6d4efd..0c86aed 100644
--- a/services/core/java/com/android/server/hdmi/Constants.java
+++ b/services/core/java/com/android/server/hdmi/Constants.java
@@ -230,13 +230,17 @@
     static final int OPTION_CEC_ENABLE = 2;
 
     // If set to disabled, system service yields control of CEC to sub-microcontroller.
-    // If enabled, it take the control back.
+    // If enabled, it takes the control back.
     static final int OPTION_CEC_SERVICE_CONTROL = 3;
 
     // Put other devices to standby when TV goes to standby. enabled by default.
     // If set to disabled, TV doesn't send <Standby> to other devices.
     static final int OPTION_CEC_AUTO_DEVICE_OFF = 4;
 
+    // Passes the language used in the system when updated. The value to use is the 3 byte
+    // code as defined in ISO/FDIS 639-2.
+    static final int OPTION_CEC_SET_LANGUAGE = 5;
+
     // If set to disabled, TV does not switch ports when mobile device is connected.
     static final int OPTION_MHL_INPUT_SWITCHING = 101;
 
@@ -246,6 +250,10 @@
     // If set to disabled, all MHL commands are discarded.
     static final int OPTION_MHL_ENABLE = 103;
 
+    // If set to disabled, system service yields control of MHL to sub-microcontroller.
+    // If enabled, it takes the control back.
+    static final int OPTION_MHL_SERVICE_CONTROL = 104;
+
     static final int DISABLED = 0;
     static final int ENABLED = 1;
 
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 2e7f0a5..fa8ab59 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -23,9 +23,11 @@
 import static com.android.server.hdmi.Constants.OPTION_CEC_AUTO_WAKEUP;
 import static com.android.server.hdmi.Constants.OPTION_CEC_ENABLE;
 import static com.android.server.hdmi.Constants.OPTION_CEC_SERVICE_CONTROL;
+import static com.android.server.hdmi.Constants.OPTION_CEC_SET_LANGUAGE;
 import static com.android.server.hdmi.Constants.OPTION_MHL_ENABLE;
 import static com.android.server.hdmi.Constants.OPTION_MHL_INPUT_SWITCHING;
 import static com.android.server.hdmi.Constants.OPTION_MHL_POWER_CHARGE;
+import static com.android.server.hdmi.Constants.OPTION_MHL_SERVICE_CONTROL;
 
 import android.annotation.Nullable;
 import android.content.BroadcastReceiver;
@@ -412,6 +414,7 @@
             // Register ContentObserver to monitor the settings change.
             registerContentObserver();
         }
+        mMhlController.setOption(OPTION_MHL_SERVICE_CONTROL, ENABLED);
     }
 
     @Override
@@ -539,6 +542,7 @@
     private void initializeCec(int initiatedBy) {
         mAddressAllocated = false;
         mCecController.setOption(OPTION_CEC_SERVICE_CONTROL, ENABLED);
+        mCecController.setOption(OPTION_CEC_SET_LANGUAGE, HdmiUtils.languageToInt(mLanguage));
         initializeLocalDevices(initiatedBy);
     }
 
@@ -2021,6 +2025,7 @@
 
         if (isTvDeviceEnabled()) {
             tv().broadcastMenuLanguage(language);
+            mCecController.setOption(OPTION_CEC_SET_LANGUAGE, HdmiUtils.languageToInt(language));
         }
     }
 
@@ -2065,6 +2070,7 @@
         mStandbyMessageReceived = false;
         mAddressAllocated = false;
         mCecController.setOption(OPTION_CEC_SERVICE_CONTROL, DISABLED);
+        mMhlController.setOption(OPTION_MHL_SERVICE_CONTROL, DISABLED);
     }
 
     private void addVendorCommandListener(IHdmiVendorCommandListener listener, int deviceType) {
diff --git a/services/core/java/com/android/server/hdmi/HdmiUtils.java b/services/core/java/com/android/server/hdmi/HdmiUtils.java
index 22a519b..9aa9290 100644
--- a/services/core/java/com/android/server/hdmi/HdmiUtils.java
+++ b/services/core/java/com/android/server/hdmi/HdmiUtils.java
@@ -292,4 +292,17 @@
                 info.getVendorId(), info.getDisplayName(), newPowerStatus);
     }
 
+    /**
+     * Convert 3 byte-long language code in string to integer representation.
+     * English(eng), for example, is converted to 0x656e67.
+     *
+     * @param language language code in string
+     * @return language code in integer representation
+     */
+    static int languageToInt(String language) {
+        String normalized = language.toLowerCase();
+        return ((normalized.charAt(0) & 0xFF) << 16)
+                | ((normalized.charAt(1) & 0xFF) << 8)
+                | (normalized.charAt(2) & 0xFF);
+    }
 }