Merge "CEC: Add implementation of SYSTEM_CEC_CONTROL option to default HdmiCec" am: 3f3e91faa9

Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/1772433

Change-Id: I64955334a2fc9af282a5252d0bbfe2baf1c600d0
diff --git a/tv/cec/1.0/default/HdmiCecDefault.cpp b/tv/cec/1.0/default/HdmiCecDefault.cpp
index 18abcad..ad89312 100644
--- a/tv/cec/1.0/default/HdmiCecDefault.cpp
+++ b/tv/cec/1.0/default/HdmiCecDefault.cpp
@@ -42,6 +42,7 @@
     mExitFd = -1;
     mCecEnabled = false;
     mWakeupEnabled = false;
+    mCecControlEnabled = false;
     mCallback = nullptr;
 }
 
@@ -242,7 +243,9 @@
             LOG(DEBUG) << "setOption: WAKEUP: " << value;
             mWakeupEnabled = value;
             break;
-        default:
+        case OptionKey::SYSTEM_CEC_CONTROL:
+            LOG(DEBUG) << "setOption: SYSTEM_CEC_CONTROL: " << value;
+            mCecControlEnabled = value;
             break;
     }
     return Void();
@@ -311,6 +314,7 @@
 
     mCecEnabled = true;
     mWakeupEnabled = true;
+    mCecControlEnabled = true;
     return Result::SUCCESS;
 }
 
@@ -330,6 +334,7 @@
     }
     mCecEnabled = false;
     mWakeupEnabled = false;
+    mCecControlEnabled = false;
     setCallback(nullptr);
     return Void();
 }
@@ -404,6 +409,11 @@
                 continue;
             }
 
+            if (!mCecControlEnabled && !isTransferableInSleep(msg)) {
+                LOG(DEBUG) << "Filter message in standby mode";
+                continue;
+            }
+
             if (mCallback != nullptr) {
                 size_t length = std::min(msg.len - 1, (uint32_t)MaxLength::MESSAGE_BODY);
                 CecMessage cecMessage{
@@ -437,6 +447,48 @@
     }
 }
 
+bool HdmiCecDefault::isTransferableInSleep(cec_msg message) {
+    int opcode = getOpcode(message);
+    switch (opcode) {
+        case CEC_MESSAGE_ABORT:
+        case CEC_MESSAGE_DEVICE_VENDOR_ID:
+        case CEC_MESSAGE_GET_CEC_VERSION:
+        case CEC_MESSAGE_GET_MENU_LANGUAGE:
+        case CEC_MESSAGE_GIVE_DEVICE_POWER_STATUS:
+        case CEC_MESSAGE_GIVE_DEVICE_VENDOR_ID:
+        case CEC_MESSAGE_GIVE_OSD_NAME:
+        case CEC_MESSAGE_GIVE_PHYSICAL_ADDRESS:
+        case CEC_MESSAGE_REPORT_PHYSICAL_ADDRESS:
+        case CEC_MESSAGE_REPORT_POWER_STATUS:
+        case CEC_MESSAGE_SET_OSD_NAME:
+        case CEC_MESSAGE_DECK_CONTROL:
+        case CEC_MESSAGE_PLAY:
+        case CEC_MESSAGE_IMAGE_VIEW_ON:
+        case CEC_MESSAGE_TEXT_VIEW_ON:
+        case CEC_MESSAGE_SYSTEM_AUDIO_MODE_REQUEST:
+            return true;
+        case CEC_MESSAGE_USER_CONTROL_PRESSED:
+            return isPowerUICommand(message);
+        default:
+            return false;
+    }
+}
+
+int HdmiCecDefault::getFirstParam(cec_msg message) {
+    return static_cast<uint8_t>(message.msg[2]);
+}
+
+bool HdmiCecDefault::isPowerUICommand(cec_msg message) {
+    int uiCommand = getFirstParam(message);
+    switch (uiCommand) {
+        case CEC_OP_UI_CMD_POWER:
+        case CEC_OP_UI_CMD_DEVICE_ROOT_MENU:
+        case CEC_OP_UI_CMD_POWER_ON_FUNCTION:
+            return true;
+        default:
+            return false;
+    }
+}
 }  // namespace implementation
 }  // namespace V1_0
 }  // namespace cec
diff --git a/tv/cec/1.0/default/HdmiCecDefault.h b/tv/cec/1.0/default/HdmiCecDefault.h
index 6b850ac..81229d3 100644
--- a/tv/cec/1.0/default/HdmiCecDefault.h
+++ b/tv/cec/1.0/default/HdmiCecDefault.h
@@ -56,7 +56,10 @@
   private:
     void event_thread();
     static int getOpcode(cec_msg message);
+    static int getFirstParam(cec_msg message);
     static bool isWakeupMessage(cec_msg message);
+    static bool isTransferableInSleep(cec_msg message);
+    static bool isPowerUICommand(cec_msg message);
 
     thread mEventThread;
 
@@ -67,6 +70,13 @@
      * <Text View On>. True by default after initialization.
      */
     bool mWakeupEnabled;
+    /*
+     * Updated when system goes into or comes out of standby mode.
+     * When set to true, Android system is handling CEC commands.
+     * When set to false, microprocessor is handling CEC commands.
+     * True by default after initialization.
+     */
+    bool mCecControlEnabled;
     sp<IHdmiCecCallback> mCallback;
 
     int mCecFd;