Keep preferred address for HdmiControlService

Uses SystemProperties to store/retrieve preferred logical address

Bug: 15843075
Bug: 15844858
Change-Id: Ie1304805cbec4e11ef4b44a5cceb108121c60581
diff --git a/services/core/java/com/android/server/hdmi/Constants.java b/services/core/java/com/android/server/hdmi/Constants.java
index 1cdf44c..3028100 100644
--- a/services/core/java/com/android/server/hdmi/Constants.java
+++ b/services/core/java/com/android/server/hdmi/Constants.java
@@ -203,5 +203,8 @@
     //       in config.xml to allow customization.
     static final int IRT_MS = 300;
 
+    static final String PROPERTY_PREFERRED_ADDRESS_PLAYBACK = "hdmi_cec.preferred_address.playback";
+    static final String PROPERTY_PREFERRED_ADDRESS_TV = "hdmi_cec.preferred_address.tv";
+
     private Constants() { /* cannot be instantiated */ }
 }
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecController.java b/services/core/java/com/android/server/hdmi/HdmiCecController.java
index 14d9b75..72519f2 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecController.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecController.java
@@ -265,8 +265,6 @@
     @ServiceThreadOnly
     void clearLogicalAddress() {
         assertRunOnServiceThread();
-        // TODO: consider to backup logical address so that new logical address
-        // allocation can use it as preferred address.
         for (int i = 0; i < mLocalDevices.size(); ++i) {
             mLocalDevices.valueAt(i).clearAddress();
         }
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
index 8f3c551..f1e7ff2 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
@@ -20,6 +20,7 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
+import android.os.SystemProperties;
 import android.util.Slog;
 
 import com.android.internal.annotations.GuardedBy;
@@ -108,8 +109,7 @@
     @ServiceThreadOnly
     void init() {
         assertRunOnServiceThread();
-        mPreferredAddress = Constants.ADDR_UNREGISTERED;
-        // TODO: load preferred address from permanent storage.
+        mPreferredAddress = getPreferredAddress();
     }
 
     /**
@@ -118,6 +118,16 @@
     protected abstract void onAddressAllocated(int logicalAddress, boolean fromBootup);
 
     /**
+     * Get the preferred logical address from system properties.
+     */
+    protected abstract int getPreferredAddress();
+
+    /**
+     * Set the preferred logical address to system properties.
+     */
+    protected abstract void setPreferredAddress(int addr);
+
+    /**
      * Dispatch incoming message.
      *
      * @param message incoming message
@@ -398,6 +408,7 @@
         assertRunOnServiceThread();
         mAddress = mPreferredAddress = logicalAddress;
         onAddressAllocated(logicalAddress, fromBootup);
+        setPreferredAddress(logicalAddress);
     }
 
     @ServiceThreadOnly
@@ -427,18 +438,6 @@
     }
 
     @ServiceThreadOnly
-    void setPreferredAddress(int addr) {
-        assertRunOnServiceThread();
-        mPreferredAddress = addr;
-    }
-
-    @ServiceThreadOnly
-    int getPreferredAddress() {
-        assertRunOnServiceThread();
-        return mPreferredAddress;
-    }
-
-    @ServiceThreadOnly
     void addAndStartAction(final FeatureAction action) {
         assertRunOnServiceThread();
         if (mService.isPowerStandbyOrTransient()) {
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
index 06907ce..a66d78c 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
@@ -20,6 +20,7 @@
 import android.hardware.hdmi.HdmiControlManager;
 import android.hardware.hdmi.IHdmiControlCallback;
 import android.os.RemoteException;
+import android.os.SystemProperties;
 import android.util.Slog;
 
 import com.android.server.hdmi.HdmiAnnotations.ServiceThreadOnly;
@@ -44,6 +45,22 @@
                 mAddress, mService.getPhysicalAddress(), mDeviceType));
     }
 
+    @Override
+    @ServiceThreadOnly
+    protected int getPreferredAddress() {
+        assertRunOnServiceThread();
+        return SystemProperties.getInt(Constants.PROPERTY_PREFERRED_ADDRESS_PLAYBACK,
+                Constants.ADDR_UNREGISTERED);
+    }
+
+    @Override
+    @ServiceThreadOnly
+    protected void setPreferredAddress(int addr) {
+        assertRunOnServiceThread();
+        SystemProperties.set(Constants.PROPERTY_PREFERRED_ADDRESS_PLAYBACK,
+                String.valueOf(addr));
+    }
+
     @ServiceThreadOnly
     void oneTouchPlay(IHdmiControlCallback callback) {
         assertRunOnServiceThread();
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index da873ab..9fc2b92 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -26,6 +26,7 @@
 import android.media.AudioPort;
 import android.media.AudioSystem;
 import android.os.RemoteException;
+import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.provider.Settings.Global;
 import android.util.Slog;
@@ -108,6 +109,22 @@
         // TODO: unregister audio port update listener if local device is released.
     }
 
+    @Override
+    @ServiceThreadOnly
+    protected int getPreferredAddress() {
+        assertRunOnServiceThread();
+        return SystemProperties.getInt(Constants.PROPERTY_PREFERRED_ADDRESS_TV,
+                Constants.ADDR_UNREGISTERED);
+    }
+
+    @Override
+    @ServiceThreadOnly
+    protected void setPreferredAddress(int addr) {
+        assertRunOnServiceThread();
+        SystemProperties.set(Constants.PROPERTY_PREFERRED_ADDRESS_TV,
+                String.valueOf(addr));
+    }
+
     private void registerAudioPortUpdateListener() {
         mService.getAudioManager().registerAudioPortUpdateListener(
                 new OnAudioPortUpdateListener() {