Merge "Fix missing invocation of HdmiControlStatusListener" into sc-dev
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 2ed160a..a086bda 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -2580,7 +2580,8 @@
         return null;
     }
 
-    private void addHdmiControlStatusChangeListener(
+    @VisibleForTesting
+    void addHdmiControlStatusChangeListener(
             final IHdmiControlStatusChangeListener listener) {
         final HdmiControlStatusChangeListenerRecord record =
                 new HdmiControlStatusChangeListenerRecord(listener);
@@ -2916,13 +2917,17 @@
                     } else {
                         mIsCecAvailable = true;
                     }
+                    if (!listeners.isEmpty()) {
+                        invokeHdmiControlStatusChangeListenerLocked(listeners,
+                                isEnabled, mIsCecAvailable);
+                    }
                 }
             });
         } else {
             mIsCecAvailable = false;
-        }
-        if (!listeners.isEmpty()) {
-            invokeHdmiControlStatusChangeListenerLocked(listeners, isEnabled, mIsCecAvailable);
+            if (!listeners.isEmpty()) {
+                invokeHdmiControlStatusChangeListenerLocked(listeners, isEnabled, mIsCecAvailable);
+            }
         }
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
index 0cf212c..f53ae52 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
@@ -40,6 +40,7 @@
 import android.hardware.hdmi.HdmiControlManager;
 import android.hardware.hdmi.HdmiPortInfo;
 import android.hardware.hdmi.IHdmiCecVolumeControlFeatureListener;
+import android.hardware.hdmi.IHdmiControlStatusChangeListener;
 import android.os.Binder;
 import android.os.IPowerManager;
 import android.os.IThermalService;
@@ -683,6 +684,100 @@
                 HdmiControlManager.HDMI_CEC_VERSION_2_0);
     }
 
+    @Test
+    public void initCec_statusListener_CecDisabled() {
+        HdmiControlStatusCallback hdmiControlStatusCallback = new HdmiControlStatusCallback();
+
+        mHdmiControlServiceSpy.addHdmiControlStatusChangeListener(hdmiControlStatusCallback);
+
+        mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
+                HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED,
+                HdmiControlManager.HDMI_CEC_CONTROL_DISABLED);
+        mTestLooper.dispatchAll();
+
+        assertThat(hdmiControlStatusCallback.mCecEnabled).isFalse();
+        assertThat(hdmiControlStatusCallback.mCecAvailable).isFalse();
+    }
+
+    @Test
+    public void initCec_statusListener_CecEnabled_NoCecResponse() {
+        HdmiControlStatusCallback hdmiControlStatusCallback = new HdmiControlStatusCallback();
+
+        mHdmiControlServiceSpy.addHdmiControlStatusChangeListener(hdmiControlStatusCallback);
+
+        mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
+                HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED,
+                HdmiControlManager.HDMI_CEC_CONTROL_DISABLED);
+        mTestLooper.dispatchAll();
+        mHdmiControlServiceSpy.getHdmiCecConfig().setIntValue(
+                HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED,
+                HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
+        mTestLooper.dispatchAll();
+        // Hit timeout twice due to retries
+        mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS);
+        mTestLooper.dispatchAll();
+        mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS);
+        mTestLooper.dispatchAll();
+
+        assertThat(hdmiControlStatusCallback.mCecEnabled).isTrue();
+        assertThat(hdmiControlStatusCallback.mCecAvailable).isFalse();
+    }
+
+    @Test
+    public void initCec_statusListener_CecEnabled_CecAvailable_TvOn() {
+        HdmiControlStatusCallback hdmiControlStatusCallback = new HdmiControlStatusCallback();
+        mHdmiControlServiceSpy.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_DISABLED);
+        mTestLooper.dispatchAll();
+
+        mHdmiControlServiceSpy.addHdmiControlStatusChangeListener(hdmiControlStatusCallback);
+        mHdmiControlServiceSpy.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
+        mHdmiControlServiceSpy.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
+        mTestLooper.dispatchAll();
+
+        HdmiCecMessage reportPowerStatus = HdmiCecMessageBuilder.buildReportPowerStatus(
+                Constants.ADDR_TV,
+                mHdmiControlServiceSpy.playback().mAddress, HdmiControlManager.POWER_STATUS_ON);
+        mNativeWrapper.onCecMessage(reportPowerStatus);
+        mTestLooper.dispatchAll();
+
+        assertThat(hdmiControlStatusCallback.mCecEnabled).isTrue();
+        assertThat(hdmiControlStatusCallback.mCecAvailable).isTrue();
+    }
+
+    @Test
+    public void initCec_statusListener_CecEnabled_CecAvailable_TvStandby() {
+        HdmiControlStatusCallback hdmiControlStatusCallback = new HdmiControlStatusCallback();
+        mHdmiControlServiceSpy.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_DISABLED);
+        mTestLooper.dispatchAll();
+
+        mHdmiControlServiceSpy.addHdmiControlStatusChangeListener(hdmiControlStatusCallback);
+        mHdmiControlServiceSpy.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
+        mHdmiControlServiceSpy.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
+        mTestLooper.dispatchAll();
+
+        HdmiCecMessage reportPowerStatus = HdmiCecMessageBuilder.buildReportPowerStatus(
+                Constants.ADDR_TV,
+                mHdmiControlServiceSpy.playback().mAddress,
+                HdmiControlManager.POWER_STATUS_STANDBY);
+        mNativeWrapper.onCecMessage(reportPowerStatus);
+        mTestLooper.dispatchAll();
+
+        assertThat(hdmiControlStatusCallback.mCecEnabled).isTrue();
+        assertThat(hdmiControlStatusCallback.mCecAvailable).isTrue();
+    }
+
+    private static class HdmiControlStatusCallback extends IHdmiControlStatusChangeListener.Stub {
+        boolean mCecEnabled = false;
+        boolean mCecAvailable = false;
+
+        @Override
+        public void onStatusChange(int isCecEnabled, boolean isCecAvailable)
+                throws RemoteException {
+            mCecEnabled = isCecEnabled == HdmiControlManager.HDMI_CEC_CONTROL_ENABLED;
+            mCecAvailable = isCecAvailable;
+        }
+    }
+
     private static class VolumeControlFeatureCallback extends
             IHdmiCecVolumeControlFeatureListener.Stub {
         boolean mCallbackReceived = false;