am b11f250e: Merge "Delegate HdmiCecService method impl to HdmiCecDevice subclass" into klp-modular-dev

* commit 'b11f250e09195d1ab250c93bfed0b31ed3a40f3d':
  Delegate HdmiCecService method impl to HdmiCecDevice subclass
diff --git a/api/current.txt b/api/current.txt
index 869a892..80181fc 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -11033,6 +11033,7 @@
   public final class HdmiCecClient {
     method public boolean isTvOn();
     method public void sendActiveSource();
+    method public void sendGiveDevicePowerStatus(int);
     method public void sendImageViewOn();
     method public void sendInactiveSource();
     method public void sendTextViewOn();
diff --git a/core/java/android/hardware/hdmi/HdmiCecClient.java b/core/java/android/hardware/hdmi/HdmiCecClient.java
index 1f382e6..cd86cd8 100644
--- a/core/java/android/hardware/hdmi/HdmiCecClient.java
+++ b/core/java/android/hardware/hdmi/HdmiCecClient.java
@@ -88,7 +88,7 @@
     }
 
     /**
-     * Send <TextViewOn> message.
+     * Send <Text View On> message.
      */
     public void sendTextViewOn() {
         try {
@@ -99,7 +99,7 @@
     }
 
     /**
-     * Send <ImageViewOn> message.
+     * Send <Image View On> message.
      */
     public void sendImageViewOn() {
         try {
@@ -110,6 +110,20 @@
     }
 
     /**
+     * Send <Give Device Power Status> message.
+     *
+     * @param address logical address of the device to send the message to, such as
+     *        {@link HdmiCec#ADDR_TV}.
+     */
+    public void sendGiveDevicePowerStatus(int address) {
+        try {
+            mService.sendGiveDevicePowerStatus(mBinder, address);
+        } catch (RemoteException e) {
+            Log.e(TAG, "sendGiveDevicePowerStatus threw exception ", e);
+        }
+    }
+
+    /**
      * Returns true if the TV or attached display is powered on.
      * <p>
      * The result of this method is only meaningful on playback devices (where the device
diff --git a/core/java/android/hardware/hdmi/IHdmiCecService.aidl b/core/java/android/hardware/hdmi/IHdmiCecService.aidl
index b5df131..ecdd345 100644
--- a/core/java/android/hardware/hdmi/IHdmiCecService.aidl
+++ b/core/java/android/hardware/hdmi/IHdmiCecService.aidl
@@ -33,6 +33,7 @@
     void sendInactiveSource(IBinder b);
     void sendImageViewOn(IBinder b);
     void sendTextViewOn(IBinder b);
+    void sendGiveDevicePowerStatus(IBinder b, int address);
     boolean isTvOn(IBinder b);
     void sendMessage(IBinder b, in HdmiCecMessage message);
 }
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecDevice.java
index 64b51c9..baae1d99 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecDevice.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecDevice.java
@@ -182,11 +182,49 @@
     }
 
     /**
+     * Send &lt;Active Source&gt; command. The default implementation does nothing. Should be
+     * overriden by subclass.
+     */
+    public void sendActiveSource(int physicalAddress) {
+        logWarning("<Active Source> not valid for the device type: " + mType
+                + " address:" + physicalAddress);
+    }
+
+    /**
+     * Send &lt;Inactive Source&gt; command. The default implementation does nothing. Should be
+     * overriden by subclass.
+     */
+    public void sendInactiveSource(int physicalAddress) {
+        logWarning("<Inactive Source> not valid for the device type: " + mType
+                + " address:" + physicalAddress);
+    }
+
+    /**
+     * Send &lt;Image View On&gt; command. The default implementation does nothing. Should be
+     * overriden by subclass.
+     */
+    public void sendImageViewOn() {
+        logWarning("<Image View On> not valid for the device type: " + mType);
+    }
+
+    /**
+     * Send &lt;Text View On&gt; command. The default implementation does nothing. Should be
+     * overriden by subclass.
+     */
+    public void sendTextViewOn() {
+        logWarning("<Text View On> not valid for the device type: " + mType);
+    }
+
+    /**
      * Check if the connected sink device is in powered-on state. The default implementation
      * simply returns false. Should be overriden by subclass to report the correct state.
      */
     public boolean isSinkDeviceOn() {
-        Log.w(TAG, "Not valid for the device type: " + mType);
+        logWarning("isSinkDeviceOn() not valid for the device type: " + mType);
         return false;
     }
+
+    private void logWarning(String msg) {
+        Log.w(TAG, msg);
+    }
 }
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecDevicePlayback.java b/services/core/java/com/android/server/hdmi/HdmiCecDevicePlayback.java
index 0310264..f8cf11d 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecDevicePlayback.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecDevicePlayback.java
@@ -66,14 +66,11 @@
         // 1) Response for the queried power status request arrives. Update the status.
         // 2) Broadcast or direct <Standby> command from TV, which is sent as TV itself is going
         //    into standby mode too.
-        // 3) Broadcast <Report Physical Address> command from TV, which is sent while it boots up.
         if (opcode == HdmiCec.MESSAGE_REPORT_POWER_STATUS) {
             mSinkDevicePowerStatus = params[0];
         } else if (srcAddress == HdmiCec.ADDR_TV) {
             if (opcode == HdmiCec.MESSAGE_STANDBY) {
                 mSinkDevicePowerStatus = HdmiCec.POWER_STATUS_STANDBY;
-            } else if (opcode == HdmiCec.MESSAGE_REPORT_PHYSICAL_ADDRESS) {
-                mSinkDevicePowerStatus = HdmiCec.POWER_STATUS_ON;
             }
         }
         super.handleMessage(srcAddress, dstAddress, opcode, params);
@@ -95,4 +92,38 @@
     public boolean isSinkDeviceOn() {
         return mSinkDevicePowerStatus == HdmiCec.POWER_STATUS_ON;
     }
+
+    @Override
+    public void sendActiveSource(int physicalAddress) {
+        setIsActiveSource(true);
+        byte[] param = new byte[] {
+                (byte) ((physicalAddress >> 8) & 0xff),
+                (byte) (physicalAddress & 0xff)
+        };
+        getService().sendMessage(getType(), HdmiCec.ADDR_BROADCAST, HdmiCec.MESSAGE_ACTIVE_SOURCE,
+                param);
+    }
+
+    @Override
+    public void sendInactiveSource(int physicalAddress) {
+        setIsActiveSource(false);
+        byte[] param = new byte[] {
+                (byte) ((physicalAddress >> 8) & 0xff),
+                (byte) (physicalAddress & 0xff)
+        };
+        getService().sendMessage(getType(), HdmiCec.ADDR_TV, HdmiCec.MESSAGE_INACTIVE_SOURCE,
+                param);
+    }
+
+    @Override
+    public void sendImageViewOn() {
+        getService().sendMessage(getType(), HdmiCec.ADDR_TV, HdmiCec.MESSAGE_IMAGE_VIEW_ON,
+                HdmiCecService.EMPTY_PARAM);
+    }
+
+    @Override
+    public void sendTextViewOn() {
+        getService().sendMessage(getType(), HdmiCec.ADDR_TV, HdmiCec.MESSAGE_TEXT_VIEW_ON,
+                HdmiCecService.EMPTY_PARAM);
+    }
 }
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecService.java b/services/core/java/com/android/server/hdmi/HdmiCecService.java
index aa496c5..0a4c719 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecService.java
@@ -277,14 +277,7 @@
             enforceAccessPermission();
             synchronized (mLock) {
                 HdmiCecDevice device = getLogicalDeviceLocked(b);
-                device.setIsActiveSource(true);
-                int physicalAddress = nativeGetPhysicalAddress(mNativePtr);
-                byte[] param = new byte[] {
-                    (byte) ((physicalAddress >> 8) & 0xff),
-                    (byte) (physicalAddress & 0xff)
-                };
-                nativeSendMessage(mNativePtr, device.getType(), HdmiCec.ADDR_BROADCAST,
-                        HdmiCec.MESSAGE_ACTIVE_SOURCE, param);
+                device.sendActiveSource(nativeGetPhysicalAddress(mNativePtr));
             }
         }
 
@@ -293,9 +286,7 @@
             enforceAccessPermission();
             synchronized (mLock) {
                 HdmiCecDevice device = getLogicalDeviceLocked(b);
-                device.setIsActiveSource(false);
-                nativeSendMessage(mNativePtr, device.getType(), HdmiCec.ADDR_BROADCAST,
-                        HdmiCec.MESSAGE_INACTIVE_SOURCE, EMPTY_PARAM);
+                device.sendInactiveSource(nativeGetPhysicalAddress(mNativePtr));
             }
         }
 
@@ -304,8 +295,7 @@
             enforceAccessPermission();
             synchronized (mLock) {
                 HdmiCecDevice device = getLogicalDeviceLocked(b);
-                nativeSendMessage(mNativePtr, device.getType(), HdmiCec.ADDR_TV,
-                        HdmiCec.MESSAGE_IMAGE_VIEW_ON, EMPTY_PARAM);
+                device.sendImageViewOn();
             }
         }
 
@@ -314,8 +304,16 @@
             enforceAccessPermission();
             synchronized (mLock) {
                 HdmiCecDevice device = getLogicalDeviceLocked(b);
-                nativeSendMessage(mNativePtr, device.getType(), HdmiCec.ADDR_TV,
-                        HdmiCec.MESSAGE_TEXT_VIEW_ON, EMPTY_PARAM);
+                device.sendTextViewOn();
+            }
+        }
+
+        public void sendGiveDevicePowerStatus(IBinder b, int address) {
+            enforceAccessPermission();
+            synchronized (mLock) {
+                HdmiCecDevice device = getLogicalDeviceLocked(b);
+                nativeSendMessage(mNativePtr, device.getType(), address,
+                        HdmiCec.MESSAGE_GIVE_DEVICE_POWER_STATUS, EMPTY_PARAM);
             }
         }
 
diff --git a/services/core/jni/com_android_server_hdmi_HdmiCecService.cpp b/services/core/jni/com_android_server_hdmi_HdmiCecService.cpp
index a00aaa8..54c9755 100644
--- a/services/core/jni/com_android_server_hdmi_HdmiCecService.cpp
+++ b/services/core/jni/com_android_server_hdmi_HdmiCecService.cpp
@@ -204,6 +204,11 @@
     } else {
         ALOGV("Logical Address Allocation success: %d", addr);
         mLogicalDevices.insert(std::pair<cec_device_type_t, cec_logical_address_t>(type, addr));
+
+        // Broadcast <Report Physical Address> when a new logical address was allocated to let
+        // other devices discover the new logical device and its logical - physical address
+        // association.
+        sendReportPhysicalAddress();
     }
     return addr;
 }