Merge "Make it not to go to sleep when changing TV's input to the others." into lmp-dev
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
index be4c834..b0c1a8a 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
@@ -210,6 +210,8 @@
                 return handleReportPhysicalAddress(message);
             case Constants.MESSAGE_ROUTING_CHANGE:
                 return handleRoutingChange(message);
+            case Constants.MESSAGE_ROUTING_INFORMATION:
+                return handleRoutingInformation(message);
             case Constants.MESSAGE_INITIATE_ARC:
                 return handleInitiateArc(message);
             case Constants.MESSAGE_TERMINATE_ARC:
@@ -331,6 +333,10 @@
         return false;
     }
 
+    protected boolean handleRoutingInformation(HdmiCecMessage message) {
+        return false;
+    }
+
     protected boolean handleReportPhysicalAddress(HdmiCecMessage message) {
         return false;
     }
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
index ae7fd82..5a2fa9c 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
@@ -16,8 +16,8 @@
 
 package com.android.server.hdmi;
 
-import android.hardware.hdmi.HdmiDeviceInfo;
 import android.hardware.hdmi.HdmiControlManager;
+import android.hardware.hdmi.HdmiDeviceInfo;
 import android.hardware.hdmi.IHdmiControlCallback;
 import android.os.RemoteException;
 import android.os.SystemProperties;
@@ -137,14 +137,14 @@
     protected boolean handleActiveSource(HdmiCecMessage message) {
         assertRunOnServiceThread();
         int physicalAddress = HdmiUtils.twoBytesToInt(message.getParams());
+        mayResetActiveSource(physicalAddress);
+        return true;  // Broadcast message.
+    }
+
+    private void mayResetActiveSource(int physicalAddress) {
         if (physicalAddress != mService.getPhysicalAddress()) {
             mIsActiveSource = false;
-            if (mService.isPowerOnOrTransient()) {
-                mService.nap();
-            }
-            return true;
         }
-        return false;
     }
 
     @Override
@@ -152,13 +152,58 @@
     protected boolean handleSetStreamPath(HdmiCecMessage message) {
         assertRunOnServiceThread();
         int physicalAddress = HdmiUtils.twoBytesToInt(message.getParams());
+        maySetActiveSource(physicalAddress);
+        maySendActiveSource();
+        wakeUpIfActiveSource();
+        return true;  // Broadcast message.
+    }
+
+    // Samsung model, we tested, sends <RoutingChange> and <RequestActiveSource> consecutively,
+    // Then if there is no <ActiveSource> response, it will change the input to
+    // the internal source.  To handle this, we'll set ActiveSource aggressively.
+    @Override
+    @ServiceThreadOnly
+    protected boolean handleRoutingChange(HdmiCecMessage message) {
+        assertRunOnServiceThread();
+        int newPath = HdmiUtils.twoBytesToInt(message.getParams(), 2);
+        maySetActiveSource(newPath);
+        return true;  // Broadcast message.
+    }
+
+    @Override
+    @ServiceThreadOnly
+    protected boolean handleRoutingInformation(HdmiCecMessage message) {
+        assertRunOnServiceThread();
+        int physicalAddress = HdmiUtils.twoBytesToInt(message.getParams());
+        maySetActiveSource(physicalAddress);
+        return true;  // Broadcast message.
+    }
+
+    private void maySetActiveSource(int physicalAddress) {
         if (physicalAddress == mService.getPhysicalAddress()) {
-            if (mService.isPowerStandbyOrTransient()) {
-                mService.wakeUp();
-            }
-            return true;
+            mIsActiveSource = true;
         }
-        return false;
+    }
+
+    private void wakeUpIfActiveSource() {
+        if (mIsActiveSource && mService.isPowerStandbyOrTransient()) {
+            mService.wakeUp();
+        }
+    }
+
+    private void maySendActiveSource() {
+        if (mIsActiveSource) {
+            mService.sendCecCommand(HdmiCecMessageBuilder.buildActiveSource(
+                    mAddress, mService.getPhysicalAddress()));
+        }
+    }
+
+    @Override
+    @ServiceThreadOnly
+    protected boolean handleRequestActiveSource(HdmiCecMessage message) {
+        assertRunOnServiceThread();
+        maySendActiveSource();
+        return true;  // Broadcast message.
     }
 
     @Override
@@ -174,4 +219,4 @@
         mIsActiveSource = false;
         checkIfPendingActionsCleared();
     }
-}
+}
\ No newline at end of file